diff options
author | Claudiu Manoil <claudiu.manoil@freescale.com> | 2014-05-07 14:08:03 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-05-09 16:08:48 (GMT) |
commit | 20302a8bd25be4fa33d376234f9e0aea65a790fd (patch) | |
tree | eaa2b920cc13fe1e74d52484ef36920a1a09781c /drivers/net/ethernet/freescale | |
parent | c413b7a34a8eef5b581570c8da1df9b9972f3971 (diff) | |
download | linux-fsl-qoriq-20302a8bd25be4fa33d376234f9e0aea65a790fd.tar.xz |
gianfar: Use netif_device_{detach,attach}() around reset
We need to keep the TX queues stopped throughout a reset,
without triggering the TX watchdog and regardless of the
link state. Given the way the watchdog works, the proper
way to do this is to use netif_device_{detach,attach}()
just as we do around suspend/resume.
netif_device_detach() can be called to stop TX queues in a
control operation other than ndo_stop, and in our case
this is insured by testing the driver's RESETTING state
flag.
napi_disable() is called before the stopping the TX queues
to make sure that the poll function is not running,
and therefore there can be no netif_wake_queue() calls.
(Inspired by sfc.)
Change-Id: Ie00ddaf39e454938b4ab5418d038de5d1a277b03
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/11994
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Rajan Gupta <rajan.gupta@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 8ce76ec..0139e0a 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -2033,14 +2033,17 @@ void stop_gfar(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); - netif_tx_stop_all_queues(dev); - smp_mb__before_clear_bit(); set_bit(GFAR_DOWN, &priv->state); smp_mb__after_clear_bit(); disable_napi(priv); + if (test_bit(GFAR_RESETTING, &priv->state)) + netif_device_detach(dev); + else + netif_tx_stop_all_queues(dev); + /* disable ints and gracefully shut down Rx/Tx DMA */ gfar_halt(priv); @@ -2293,9 +2296,12 @@ int startup_gfar(struct net_device *ndev) phy_start(priv->phydev); - enable_napi(priv); + if (test_bit(GFAR_RESETTING, &priv->state)) + netif_device_attach(ndev); + else + netif_tx_wake_all_queues(ndev); - netif_tx_wake_all_queues(ndev); + enable_napi(priv); return 0; } |