summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike McCormack <mikem@ring3k.org>2009-07-21 20:57:56 -0700
committerDavid S. Miller <davem@davemloft.net>2009-07-21 20:57:56 -0700
commita947a39d52f5b647a2fd5eca55d39e722a2fa90f (patch)
tree5378a344f99d3206c63376cfd73fe336eb2049b9
parent86669530d966ca21f4245b9990e7ae188d433d1e (diff)
downloadlinux-3.10-a947a39d52f5b647a2fd5eca55d39e722a2fa90f.tar.gz
linux-3.10-a947a39d52f5b647a2fd5eca55d39e722a2fa90f.tar.bz2
linux-3.10-a947a39d52f5b647a2fd5eca55d39e722a2fa90f.zip
sky2: Avoid races in sky2_down
Reset rx chain before trying to drain it. Shut interrupts off last, incase there's something to report. Signed-off-by: Mike McCormack <mikem@ring3k.org> Acked-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/sky2.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index ba768dfa59e..3550c5dcd93 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1818,12 +1818,6 @@ static int sky2_down(struct net_device *dev)
if (netif_msg_ifdown(sky2))
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
- /* Disable port IRQ */
- imask = sky2_read32(hw, B0_IMSK);
- imask &= ~portirq_msk[port];
- sky2_write32(hw, B0_IMSK, imask);
- sky2_read32(hw, B0_IMSK);
-
/* Force flow control off */
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
@@ -1863,8 +1857,6 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
- sky2_rx_stop(sky2);
-
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
@@ -1874,6 +1866,14 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, STAT_ISR_TIMER_CNT, 0);
sky2_read8(hw, STAT_ISR_TIMER_CTRL);
+ sky2_rx_stop(sky2);
+
+ /* Disable port IRQ */
+ imask = sky2_read32(hw, B0_IMSK);
+ imask &= ~portirq_msk[port];
+ sky2_write32(hw, B0_IMSK, imask);
+ sky2_read32(hw, B0_IMSK);
+
synchronize_irq(hw->pdev->irq);
napi_synchronize(&hw->napi);