aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorshemminger@osdl.org <shemminger@osdl.org>2005-11-30 14:45:18 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-01 02:20:20 -0500
commit018d1c667ef4dce5299dd79d38447840789c97d6 (patch)
treed208b079dcf74dc2c2e9fa4fc6212fefa2172d4d /drivers/net/sky2.c
parent0a1225769763779288d759e904c4f5a660844ce4 (diff)
[PATCH] sky2: race with MTU change
Avoid possible race conditions when doing MTU and change and shutdown. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f56de9894208..1d5c3039f53a 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1298,8 +1298,16 @@ static int sky2_down(struct net_device *dev)
1298 if (netif_msg_ifdown(sky2)) 1298 if (netif_msg_ifdown(sky2))
1299 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 1299 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
1300 1300
1301 /* Stop more packets from being queued */
1301 netif_stop_queue(dev); 1302 netif_stop_queue(dev);
1302 1303
1304 /* Disable port IRQ */
1305 local_irq_disable();
1306 hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
1307 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1308 local_irq_enable();
1309
1310
1303 sky2_phy_reset(hw, port); 1311 sky2_phy_reset(hw, port);
1304 1312
1305 /* Stop transmitter */ 1313 /* Stop transmitter */
@@ -1346,6 +1354,8 @@ static int sky2_down(struct net_device *dev)
1346 /* turn off LED's */ 1354 /* turn off LED's */
1347 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); 1355 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
1348 1356
1357 synchronize_irq(hw->pdev->irq);
1358
1349 sky2_tx_clean(sky2); 1359 sky2_tx_clean(sky2);
1350 sky2_rx_clean(sky2); 1360 sky2_rx_clean(sky2);
1351 1361
@@ -1586,9 +1596,12 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1586 return 0; 1596 return 0;
1587 } 1597 }
1588 1598
1589 local_irq_disable();
1590 sky2_write32(hw, B0_IMSK, 0); 1599 sky2_write32(hw, B0_IMSK, 0);
1591 1600
1601 dev->trans_start = jiffies; /* prevent tx timeout */
1602 netif_stop_queue(dev);
1603 netif_poll_disable(hw->dev[0]);
1604
1592 ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); 1605 ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
1593 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); 1606 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
1594 sky2_rx_stop(sky2); 1607 sky2_rx_stop(sky2);
@@ -1608,9 +1621,10 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1608 err = sky2_rx_start(sky2); 1621 err = sky2_rx_start(sky2);
1609 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl); 1622 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
1610 1623
1624 netif_poll_disable(hw->dev[0]);
1625 netif_wake_queue(dev);
1611 sky2_write32(hw, B0_IMSK, hw->intr_mask); 1626 sky2_write32(hw, B0_IMSK, hw->intr_mask);
1612 sky2_read32(hw, B0_IMSK); 1627
1613 local_irq_enable();
1614 return err; 1628 return err;
1615} 1629}
1616 1630