aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAuke Kok <auke\-jan.h.kok@intel.com>2006-09-27 15:54:02 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-09-27 15:54:02 -0400
commit1314bbf3a3d911218fc153e14873e2e384d08084 (patch)
tree4b2517261087f6d1374fe84272dcf20cd184f701 /drivers
parent4f5f2317fbb3655edae21de3ada0f1692523eeef (diff)
e1000: driver state fixes (race fix)
We were plagued by our interrupt handler posting a watchdog event which could occur when our adapter was going down in case a late packet arrived just before e1000_down() finished. This caused the watchdog timer to start after the NIC was down and keep rescheduling it every N seconds. Once the driver unloaded it would panic. Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e1000/e1000.h3
-rw-r--r--drivers/net/e1000/e1000_ethtool.c6
-rw-r--r--drivers/net/e1000/e1000_main.c28
3 files changed, 23 insertions, 14 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index a9501e7b8ef9..7ecce438d258 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -345,8 +345,9 @@ struct e1000_adapter {
345}; 345};
346 346
347enum e1000_state_t { 347enum e1000_state_t {
348 __E1000_DRIVER_TESTING, 348 __E1000_TESTING,
349 __E1000_RESETTING, 349 __E1000_RESETTING,
350 __E1000_DOWN
350}; 351};
351 352
352#endif /* _E1000_H_ */ 353#endif /* _E1000_H_ */
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 5edf8a099ceb..2cc949a34451 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1624,7 +1624,7 @@ e1000_diag_test(struct net_device *netdev,
1624 struct e1000_adapter *adapter = netdev_priv(netdev); 1624 struct e1000_adapter *adapter = netdev_priv(netdev);
1625 boolean_t if_running = netif_running(netdev); 1625 boolean_t if_running = netif_running(netdev);
1626 1626
1627 set_bit(__E1000_DRIVER_TESTING, &adapter->flags); 1627 set_bit(__E1000_TESTING, &adapter->flags);
1628 if (eth_test->flags == ETH_TEST_FL_OFFLINE) { 1628 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
1629 /* Offline tests */ 1629 /* Offline tests */
1630 1630
@@ -1669,7 +1669,7 @@ e1000_diag_test(struct net_device *netdev,
1669 adapter->hw.autoneg = autoneg; 1669 adapter->hw.autoneg = autoneg;
1670 1670
1671 e1000_reset(adapter); 1671 e1000_reset(adapter);
1672 clear_bit(__E1000_DRIVER_TESTING, &adapter->flags); 1672 clear_bit(__E1000_TESTING, &adapter->flags);
1673 if (if_running) 1673 if (if_running)
1674 dev_open(netdev); 1674 dev_open(netdev);
1675 } else { 1675 } else {
@@ -1684,7 +1684,7 @@ e1000_diag_test(struct net_device *netdev,
1684 data[2] = 0; 1684 data[2] = 0;
1685 data[3] = 0; 1685 data[3] = 0;
1686 1686
1687 clear_bit(__E1000_DRIVER_TESTING, &adapter->flags); 1687 clear_bit(__E1000_TESTING, &adapter->flags);
1688 } 1688 }
1689 msleep_interruptible(4 * 1000); 1689 msleep_interruptible(4 * 1000);
1690} 1690}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index e2615782966e..5098dd7df7cd 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -476,13 +476,14 @@ e1000_up(struct e1000_adapter *adapter)
476 476
477 adapter->tx_queue_len = netdev->tx_queue_len; 477 adapter->tx_queue_len = netdev->tx_queue_len;
478 478
479 mod_timer(&adapter->watchdog_timer, jiffies);
480
481#ifdef CONFIG_E1000_NAPI 479#ifdef CONFIG_E1000_NAPI
482 netif_poll_enable(netdev); 480 netif_poll_enable(netdev);
483#endif 481#endif
484 e1000_irq_enable(adapter); 482 e1000_irq_enable(adapter);
485 483
484 clear_bit(__E1000_DOWN, &adapter->flags);
485
486 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
486 return 0; 487 return 0;
487} 488}
488 489
@@ -561,6 +562,10 @@ e1000_down(struct e1000_adapter *adapter)
561{ 562{
562 struct net_device *netdev = adapter->netdev; 563 struct net_device *netdev = adapter->netdev;
563 564
565 /* signal that we're down so the interrupt handler does not
566 * reschedule our watchdog timer */
567 set_bit(__E1000_DOWN, &adapter->flags);
568
564 e1000_irq_disable(adapter); 569 e1000_irq_disable(adapter);
565 570
566 del_timer_sync(&adapter->tx_fifo_stall_timer); 571 del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -903,11 +908,6 @@ e1000_probe(struct pci_dev *pdev,
903 INIT_WORK(&adapter->reset_task, 908 INIT_WORK(&adapter->reset_task,
904 (void (*)(void *))e1000_reset_task, netdev); 909 (void (*)(void *))e1000_reset_task, netdev);
905 910
906 /* we're going to reset, so assume we have no link for now */
907
908 netif_carrier_off(netdev);
909 netif_stop_queue(netdev);
910
911 e1000_check_options(adapter); 911 e1000_check_options(adapter);
912 912
913 /* Initial Wake on LAN setting 913 /* Initial Wake on LAN setting
@@ -1014,6 +1014,10 @@ e1000_probe(struct pci_dev *pdev,
1014 if ((err = register_netdev(netdev))) 1014 if ((err = register_netdev(netdev)))
1015 goto err_register; 1015 goto err_register;
1016 1016
1017 /* tell the stack to leave us alone until e1000_open() is called */
1018 netif_carrier_off(netdev);
1019 netif_stop_queue(netdev);
1020
1017 DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n"); 1021 DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
1018 1022
1019 cards_found++; 1023 cards_found++;
@@ -1200,6 +1204,8 @@ e1000_sw_init(struct e1000_adapter *adapter)
1200 atomic_set(&adapter->irq_sem, 1); 1204 atomic_set(&adapter->irq_sem, 1);
1201 spin_lock_init(&adapter->stats_lock); 1205 spin_lock_init(&adapter->stats_lock);
1202 1206
1207 set_bit(__E1000_DOWN, &adapter->flags);
1208
1203 return 0; 1209 return 0;
1204} 1210}
1205 1211
@@ -1265,7 +1271,7 @@ e1000_open(struct net_device *netdev)
1265 int err; 1271 int err;
1266 1272
1267 /* disallow open during test */ 1273 /* disallow open during test */
1268 if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags)) 1274 if (test_bit(__E1000_TESTING, &adapter->flags))
1269 return -EBUSY; 1275 return -EBUSY;
1270 1276
1271 /* allocate transmit descriptors */ 1277 /* allocate transmit descriptors */
@@ -3072,7 +3078,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
3072 if (unlikely(adapter->hw.mac_type == e1000_82547)) { 3078 if (unlikely(adapter->hw.mac_type == e1000_82547)) {
3073 if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) { 3079 if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
3074 netif_stop_queue(netdev); 3080 netif_stop_queue(netdev);
3075 mod_timer(&adapter->tx_fifo_stall_timer, jiffies); 3081 mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
3076 spin_unlock_irqrestore(&tx_ring->tx_lock, flags); 3082 spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
3077 return NETDEV_TX_BUSY; 3083 return NETDEV_TX_BUSY;
3078 } 3084 }
@@ -3468,7 +3474,9 @@ e1000_intr(int irq, void *data, struct pt_regs *regs)
3468 rctl = E1000_READ_REG(hw, RCTL); 3474 rctl = E1000_READ_REG(hw, RCTL);
3469 E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); 3475 E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
3470 } 3476 }
3471 mod_timer(&adapter->watchdog_timer, jiffies); 3477 /* guard against interrupt when we're going down */
3478 if (!test_bit(__E1000_DOWN, &adapter->flags))
3479 mod_timer(&adapter->watchdog_timer, jiffies + 1);
3472 } 3480 }
3473 3481
3474#ifdef CONFIG_E1000_NAPI 3482#ifdef CONFIG_E1000_NAPI