Message ID | 1472747141-15886-2-git-send-email-jeremy.linton@arm.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
> @@ -1520,17 +1513,22 @@ static int smsc911x_open(struct net_device *dev) > unsigned int timeout; > unsigned int temp; > unsigned int intcfg; > + int retval; > > - /* if the phy is not yet registered, retry later*/ > + /* find and start the given phy */ > if (!dev->phydev) { > - SMSC_WARN(pdata, hw, "phy_dev is NULL"); > - return -EAGAIN; > + if (smsc911x_mii_probe(dev) < 0) { > + SMSC_WARN(pdata, probe, "Error starting phy"); > + retval = -EAGAIN; smsc911x_mii_probe() returns an error code. It is better to use that, than -EAGAIN, which is rather odd to start with. > + goto out; > + } > } > > /* Reset the LAN911x */ > if (smsc911x_soft_reset(pdata)) { > SMSC_WARN(pdata, hw, "soft reset failed"); > - return -EIO; > + retval = -EIO; > + goto mii_free_out; smsc911x_soft_reset() also returns an error code you should use. This patch also seems to do quite a few different things. Please can you break it up into multiple patches. Thanks Andrew
On 09/01/2016 11:58 AM, Andrew Lunn wrote: >> @@ -1520,17 +1513,22 @@ static int smsc911x_open(struct net_device *dev) >> unsigned int timeout; >> unsigned int temp; >> unsigned int intcfg; >> + int retval; >> >> - /* if the phy is not yet registered, retry later*/ >> + /* find and start the given phy */ >> if (!dev->phydev) { >> - SMSC_WARN(pdata, hw, "phy_dev is NULL"); >> - return -EAGAIN; >> + if (smsc911x_mii_probe(dev) < 0) { >> + SMSC_WARN(pdata, probe, "Error starting phy"); >> + retval = -EAGAIN; > > smsc911x_mii_probe() returns an error code. It is better to use that, > than -EAGAIN, which is rather odd to start with. Thats a good point, I was just maintaining the existing behavior, but its definitely better to just return the actual error. > >> + goto out; >> + } >> } >> >> /* Reset the LAN911x */ >> if (smsc911x_soft_reset(pdata)) { >> SMSC_WARN(pdata, hw, "soft reset failed"); >> - return -EIO; >> + retval = -EIO; >> + goto mii_free_out; > > smsc911x_soft_reset() also returns an error code you should use. > > This patch also seems to do quite a few different things. Please can > you break it up into multiple patches. That was the comment from the previous patch, but It confused me because it was only really moving the MDIO startup, the rest was a side effect of that and atomic to it (AKA it wasn't clear how to make it smaller). I read it as Steve misinterpreting the laundry list of fixes as things being individually fixed, rather than one thing fixing a bunch of stuff. This patch does add additional code I overlooked to cleanup the phy if it fails, I guess in theory that portion could be a prereq patch, I will break that portion out. I'm still not sure how to partially move the MDIO startup...
> This patch does add additional code I overlooked to cleanup the phy > if it fails, I guess in theory that portion could be a prereq patch, > I will break that portion out. I'm still not sure how to partially > move the MDIO startup... Hi Jeremy You can add a cleanup patch which replaces these hard coded return values with the value returned by the function calls. Then do the move. In general, it is easier to review lots of small obvious patches, than one big patch with lots of things going on. Andrew
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index ca31345..6d6dcfe 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -1099,15 +1099,8 @@ static int smsc911x_mii_init(struct platform_device *pdev, goto err_out_free_bus_2; } - if (smsc911x_mii_probe(dev) < 0) { - SMSC_WARN(pdata, probe, "Error registering mii bus"); - goto err_out_unregister_bus_3; - } - return 0; -err_out_unregister_bus_3: - mdiobus_unregister(pdata->mii_bus); err_out_free_bus_2: mdiobus_free(pdata->mii_bus); err_out_1: @@ -1520,17 +1513,22 @@ static int smsc911x_open(struct net_device *dev) unsigned int timeout; unsigned int temp; unsigned int intcfg; + int retval; - /* if the phy is not yet registered, retry later*/ + /* find and start the given phy */ if (!dev->phydev) { - SMSC_WARN(pdata, hw, "phy_dev is NULL"); - return -EAGAIN; + if (smsc911x_mii_probe(dev) < 0) { + SMSC_WARN(pdata, probe, "Error starting phy"); + retval = -EAGAIN; + goto out; + } } /* Reset the LAN911x */ if (smsc911x_soft_reset(pdata)) { SMSC_WARN(pdata, hw, "soft reset failed"); - return -EIO; + retval = -EIO; + goto mii_free_out; } smsc911x_reg_write(pdata, HW_CFG, 0x00050000); @@ -1600,7 +1598,8 @@ static int smsc911x_open(struct net_device *dev) if (!pdata->software_irq_signal) { netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n", dev->irq); - return -ENODEV; + retval = -ENODEV; + goto mii_free_out; } SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d", dev->irq); @@ -1646,6 +1645,12 @@ static int smsc911x_open(struct net_device *dev) netif_start_queue(dev); return 0; + +mii_free_out: + phy_disconnect(dev->phydev); + dev->phydev = NULL; +out: + return retval; } /* Entry point for stopping the interface */ @@ -1668,8 +1673,11 @@ static int smsc911x_stop(struct net_device *dev) smsc911x_tx_update_txcounters(dev); /* Bring the PHY down */ - if (dev->phydev) + if (dev->phydev) { phy_stop(dev->phydev); + phy_disconnect(dev->phydev); + dev->phydev = NULL; + } SMSC_TRACE(pdata, ifdown, "Interface stopped"); return 0; @@ -2291,11 +2299,10 @@ static int smsc911x_drv_remove(struct platform_device *pdev) pdata = netdev_priv(dev); BUG_ON(!pdata); BUG_ON(!pdata->ioaddr); - BUG_ON(!dev->phydev); + WARN_ON(dev->phydev); SMSC_TRACE(pdata, ifdown, "Stopping driver"); - phy_disconnect(dev->phydev); mdiobus_unregister(pdata->mii_bus); mdiobus_free(pdata->mii_bus); @@ -2494,6 +2501,12 @@ static int smsc911x_drv_probe(struct platform_device *pdev) netif_carrier_off(dev); + retval = smsc911x_mii_init(pdev, dev); + if (retval) { + SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); + goto out_free_irq; + } + retval = register_netdev(dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i registering device", retval); @@ -2503,12 +2516,6 @@ static int smsc911x_drv_probe(struct platform_device *pdev) "Network interface: \"%s\"", dev->name); } - retval = smsc911x_mii_init(pdev, dev); - if (retval) { - SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); - goto out_unregister_netdev_5; - } - spin_lock_irq(&pdata->mac_lock); /* Check if mac address has been specified when bringing interface up */ @@ -2544,8 +2551,6 @@ static int smsc911x_drv_probe(struct platform_device *pdev) return 0; -out_unregister_netdev_5: - unregister_netdev(dev); out_free_irq: free_irq(dev->irq, dev); out_disable_resources:
Move phy startup/shutdown into the smsc911x_open/stop routines. This allows the module to be unloaded because phy_connect_direct is no longer always holding the module use count. This one change also resolves a number of other problems. The link status of a downed interface no longer reflects a stale state. Errors caused by the net device being opened before the mdio/phy was configured. There is also a potential power savings as the phy's don't remain powered when the interface isn't running. Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> --- drivers/net/ethernet/smsc/smsc911x.c | 51 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-)