aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2006-06-27 12:06:28 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-06-27 12:06:28 -0400
commit2db10a081c5c1082d58809a1bcf1a6073f4db160 (patch)
treef54772ef60f2c5bf5f8d602a83d6dc508158a0e0 /drivers
parentacfbc9fde2ec7f304398f6ad7644002e07bf84bc (diff)
e1000: rework driver hardware reset locking
After studying the driver mac reset code it was found that there were multiple race conditions possible to reset the unit twice or bring it e1000_up() double. This fixes all occurences where the driver needs to reset the mac. We also remove irq requesting/releasing into _open and _close so that while the device is _up we will never touch the irq's. This fixes the double free irq bug that people saw. To make sure that the watchdog task doesn't cause another race we let it run as a non-scheduled task. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e1000/e1000.h8
-rw-r--r--drivers/net/e1000/e1000_ethtool.c46
-rw-r--r--drivers/net/e1000/e1000_main.c126
3 files changed, 105 insertions, 75 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 2bc34fbfa69c..2b96ad0482ef 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -69,7 +69,6 @@
69#ifdef NETIF_F_TSO 69#ifdef NETIF_F_TSO
70#include <net/checksum.h> 70#include <net/checksum.h>
71#endif 71#endif
72#include <linux/workqueue.h>
73#include <linux/mii.h> 72#include <linux/mii.h>
74#include <linux/ethtool.h> 73#include <linux/ethtool.h>
75#include <linux/if_vlan.h> 74#include <linux/if_vlan.h>
@@ -255,7 +254,6 @@ struct e1000_adapter {
255 spinlock_t tx_queue_lock; 254 spinlock_t tx_queue_lock;
256#endif 255#endif
257 atomic_t irq_sem; 256 atomic_t irq_sem;
258 struct work_struct watchdog_task;
259 struct work_struct reset_task; 257 struct work_struct reset_task;
260 uint8_t fc_autoneg; 258 uint8_t fc_autoneg;
261 259
@@ -340,8 +338,13 @@ struct e1000_adapter {
340#ifdef NETIF_F_TSO 338#ifdef NETIF_F_TSO
341 boolean_t tso_force; 339 boolean_t tso_force;
342#endif 340#endif
341 unsigned long flags;
343}; 342};
344 343
344enum e1000_state_t {
345 __E1000_DRIVER_TESTING,
346 __E1000_RESETTING,
347};
345 348
346/* e1000_main.c */ 349/* e1000_main.c */
347extern char e1000_driver_name[]; 350extern char e1000_driver_name[];
@@ -349,6 +352,7 @@ extern char e1000_driver_version[];
349int e1000_up(struct e1000_adapter *adapter); 352int e1000_up(struct e1000_adapter *adapter);
350void e1000_down(struct e1000_adapter *adapter); 353void e1000_down(struct e1000_adapter *adapter);
351void e1000_reset(struct e1000_adapter *adapter); 354void e1000_reset(struct e1000_adapter *adapter);
355void e1000_reinit_locked(struct e1000_adapter *adapter);
352int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); 356int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
353void e1000_free_all_tx_resources(struct e1000_adapter *adapter); 357void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
354int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); 358int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 845d293b2f6a..cf5c5f46341f 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -203,11 +203,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
203 203
204 /* reset the link */ 204 /* reset the link */
205 205
206 if (netif_running(adapter->netdev)) { 206 if (netif_running(adapter->netdev))
207 e1000_down(adapter); 207 e1000_reinit_locked(adapter);
208 e1000_reset(adapter); 208 else
209 e1000_up(adapter);
210 } else
211 e1000_reset(adapter); 209 e1000_reset(adapter);
212 210
213 return 0; 211 return 0;
@@ -254,10 +252,9 @@ e1000_set_pauseparam(struct net_device *netdev,
254 hw->original_fc = hw->fc; 252 hw->original_fc = hw->fc;
255 253
256 if (adapter->fc_autoneg == AUTONEG_ENABLE) { 254 if (adapter->fc_autoneg == AUTONEG_ENABLE) {
257 if (netif_running(adapter->netdev)) { 255 if (netif_running(adapter->netdev))
258 e1000_down(adapter); 256 e1000_reinit_locked(adapter);
259 e1000_up(adapter); 257 else
260 } else
261 e1000_reset(adapter); 258 e1000_reset(adapter);
262 } else 259 } else
263 return ((hw->media_type == e1000_media_type_fiber) ? 260 return ((hw->media_type == e1000_media_type_fiber) ?
@@ -279,10 +276,9 @@ e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
279 struct e1000_adapter *adapter = netdev_priv(netdev); 276 struct e1000_adapter *adapter = netdev_priv(netdev);
280 adapter->rx_csum = data; 277 adapter->rx_csum = data;
281 278
282 if (netif_running(netdev)) { 279 if (netif_running(netdev))
283 e1000_down(adapter); 280 e1000_reinit_locked(adapter);
284 e1000_up(adapter); 281 else
285 } else
286 e1000_reset(adapter); 282 e1000_reset(adapter);
287 return 0; 283 return 0;
288} 284}
@@ -631,6 +627,9 @@ e1000_set_ringparam(struct net_device *netdev,
631 tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues; 627 tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
632 rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues; 628 rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
633 629
630 while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
631 msleep(1);
632
634 if (netif_running(adapter->netdev)) 633 if (netif_running(adapter->netdev))
635 e1000_down(adapter); 634 e1000_down(adapter);
636 635
@@ -691,9 +690,11 @@ e1000_set_ringparam(struct net_device *netdev,
691 adapter->rx_ring = rx_new; 690 adapter->rx_ring = rx_new;
692 adapter->tx_ring = tx_new; 691 adapter->tx_ring = tx_new;
693 if ((err = e1000_up(adapter))) 692 if ((err = e1000_up(adapter)))
694 return err; 693 goto err_setup;
695 } 694 }
696 695
696 clear_bit(__E1000_RESETTING, &adapter->flags);
697
697 return 0; 698 return 0;
698err_setup_tx: 699err_setup_tx:
699 e1000_free_all_rx_resources(adapter); 700 e1000_free_all_rx_resources(adapter);
@@ -701,6 +702,8 @@ err_setup_rx:
701 adapter->rx_ring = rx_old; 702 adapter->rx_ring = rx_old;
702 adapter->tx_ring = tx_old; 703 adapter->tx_ring = tx_old;
703 e1000_up(adapter); 704 e1000_up(adapter);
705err_setup:
706 clear_bit(__E1000_RESETTING, &adapter->flags);
704 return err; 707 return err;
705} 708}
706 709
@@ -1568,6 +1571,7 @@ e1000_diag_test(struct net_device *netdev,
1568 struct e1000_adapter *adapter = netdev_priv(netdev); 1571 struct e1000_adapter *adapter = netdev_priv(netdev);
1569 boolean_t if_running = netif_running(netdev); 1572 boolean_t if_running = netif_running(netdev);
1570 1573
1574 set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
1571 if (eth_test->flags == ETH_TEST_FL_OFFLINE) { 1575 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
1572 /* Offline tests */ 1576 /* Offline tests */
1573 1577
@@ -1582,7 +1586,8 @@ e1000_diag_test(struct net_device *netdev,
1582 eth_test->flags |= ETH_TEST_FL_FAILED; 1586 eth_test->flags |= ETH_TEST_FL_FAILED;
1583 1587
1584 if (if_running) 1588 if (if_running)
1585 e1000_down(adapter); 1589 /* indicate we're in test mode */
1590 dev_close(netdev);
1586 else 1591 else
1587 e1000_reset(adapter); 1592 e1000_reset(adapter);
1588 1593
@@ -1607,8 +1612,9 @@ e1000_diag_test(struct net_device *netdev,
1607 adapter->hw.autoneg = autoneg; 1612 adapter->hw.autoneg = autoneg;
1608 1613
1609 e1000_reset(adapter); 1614 e1000_reset(adapter);
1615 clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
1610 if (if_running) 1616 if (if_running)
1611 e1000_up(adapter); 1617 dev_open(netdev);
1612 } else { 1618 } else {
1613 /* Online tests */ 1619 /* Online tests */
1614 if (e1000_link_test(adapter, &data[4])) 1620 if (e1000_link_test(adapter, &data[4]))
@@ -1619,6 +1625,8 @@ e1000_diag_test(struct net_device *netdev,
1619 data[1] = 0; 1625 data[1] = 0;
1620 data[2] = 0; 1626 data[2] = 0;
1621 data[3] = 0; 1627 data[3] = 0;
1628
1629 clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
1622 } 1630 }
1623 msleep_interruptible(4 * 1000); 1631 msleep_interruptible(4 * 1000);
1624} 1632}
@@ -1807,10 +1815,8 @@ static int
1807e1000_nway_reset(struct net_device *netdev) 1815e1000_nway_reset(struct net_device *netdev)
1808{ 1816{
1809 struct e1000_adapter *adapter = netdev_priv(netdev); 1817 struct e1000_adapter *adapter = netdev_priv(netdev);
1810 if (netif_running(netdev)) { 1818 if (netif_running(netdev))
1811 e1000_down(adapter); 1819 e1000_reinit_locked(adapter);
1812 e1000_up(adapter);
1813 }
1814 return 0; 1820 return 0;
1815} 1821}
1816 1822
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index a373ccb308d8..52d698bb2595 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -133,7 +133,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
133static void e1000_set_multi(struct net_device *netdev); 133static void e1000_set_multi(struct net_device *netdev);
134static void e1000_update_phy_info(unsigned long data); 134static void e1000_update_phy_info(unsigned long data);
135static void e1000_watchdog(unsigned long data); 135static void e1000_watchdog(unsigned long data);
136static void e1000_watchdog_task(struct e1000_adapter *adapter);
137static void e1000_82547_tx_fifo_stall(unsigned long data); 136static void e1000_82547_tx_fifo_stall(unsigned long data);
138static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); 137static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
139static struct net_device_stats * e1000_get_stats(struct net_device *netdev); 138static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
@@ -261,6 +260,44 @@ e1000_exit_module(void)
261 260
262module_exit(e1000_exit_module); 261module_exit(e1000_exit_module);
263 262
263static int e1000_request_irq(struct e1000_adapter *adapter)
264{
265 struct net_device *netdev = adapter->netdev;
266 int flags, err = 0;
267
268 flags = SA_SHIRQ | SA_SAMPLE_RANDOM;
269#ifdef CONFIG_PCI_MSI
270 if (adapter->hw.mac_type > e1000_82547_rev_2) {
271 adapter->have_msi = TRUE;
272 if ((err = pci_enable_msi(adapter->pdev))) {
273 DPRINTK(PROBE, ERR,
274 "Unable to allocate MSI interrupt Error: %d\n", err);
275 adapter->have_msi = FALSE;
276 }
277 }
278 if (adapter->have_msi)
279 flags &= ~SA_SHIRQ;
280#endif
281 if ((err = request_irq(adapter->pdev->irq, &e1000_intr, flags,
282 netdev->name, netdev)))
283 DPRINTK(PROBE, ERR,
284 "Unable to allocate interrupt Error: %d\n", err);
285
286 return err;
287}
288
289static void e1000_free_irq(struct e1000_adapter *adapter)
290{
291 struct net_device *netdev = adapter->netdev;
292
293 free_irq(adapter->pdev->irq, netdev);
294
295#ifdef CONFIG_PCI_MSI
296 if (adapter->have_msi)
297 pci_disable_msi(adapter->pdev);
298#endif
299}
300
264/** 301/**
265 * e1000_irq_disable - Mask off interrupt generation on the NIC 302 * e1000_irq_disable - Mask off interrupt generation on the NIC
266 * @adapter: board private structure 303 * @adapter: board private structure
@@ -387,7 +424,7 @@ int
387e1000_up(struct e1000_adapter *adapter) 424e1000_up(struct e1000_adapter *adapter)
388{ 425{
389 struct net_device *netdev = adapter->netdev; 426 struct net_device *netdev = adapter->netdev;
390 int i, err; 427 int i;
391 428
392 /* hardware has been reset, we need to reload some things */ 429 /* hardware has been reset, we need to reload some things */
393 430
@@ -415,24 +452,6 @@ e1000_up(struct e1000_adapter *adapter)
415 E1000_DESC_UNUSED(ring)); 452 E1000_DESC_UNUSED(ring));
416 } 453 }
417 454
418#ifdef CONFIG_PCI_MSI
419 if (adapter->hw.mac_type > e1000_82547_rev_2) {
420 adapter->have_msi = TRUE;
421 if ((err = pci_enable_msi(adapter->pdev))) {
422 DPRINTK(PROBE, ERR,
423 "Unable to allocate MSI interrupt Error: %d\n", err);
424 adapter->have_msi = FALSE;
425 }
426 }
427#endif
428 if ((err = request_irq(adapter->pdev->irq, &e1000_intr,
429 SA_SHIRQ | SA_SAMPLE_RANDOM,
430 netdev->name, netdev))) {
431 DPRINTK(PROBE, ERR,
432 "Unable to allocate interrupt Error: %d\n", err);
433 return err;
434 }
435
436 adapter->tx_queue_len = netdev->tx_queue_len; 455 adapter->tx_queue_len = netdev->tx_queue_len;
437 456
438 mod_timer(&adapter->watchdog_timer, jiffies); 457 mod_timer(&adapter->watchdog_timer, jiffies);
@@ -450,16 +469,10 @@ e1000_down(struct e1000_adapter *adapter)
450{ 469{
451 struct net_device *netdev = adapter->netdev; 470 struct net_device *netdev = adapter->netdev;
452 boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) && 471 boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
453 e1000_check_mng_mode(&adapter->hw); 472 e1000_check_mng_mode(&adapter->hw);
454 473
455 e1000_irq_disable(adapter); 474 e1000_irq_disable(adapter);
456 475
457 free_irq(adapter->pdev->irq, netdev);
458#ifdef CONFIG_PCI_MSI
459 if (adapter->hw.mac_type > e1000_82547_rev_2 &&
460 adapter->have_msi == TRUE)
461 pci_disable_msi(adapter->pdev);
462#endif
463 del_timer_sync(&adapter->tx_fifo_stall_timer); 476 del_timer_sync(&adapter->tx_fifo_stall_timer);
464 del_timer_sync(&adapter->watchdog_timer); 477 del_timer_sync(&adapter->watchdog_timer);
465 del_timer_sync(&adapter->phy_info_timer); 478 del_timer_sync(&adapter->phy_info_timer);
@@ -496,6 +509,17 @@ e1000_down(struct e1000_adapter *adapter)
496} 509}
497 510
498void 511void
512e1000_reinit_locked(struct e1000_adapter *adapter)
513{
514 WARN_ON(in_interrupt());
515 while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
516 msleep(1);
517 e1000_down(adapter);
518 e1000_up(adapter);
519 clear_bit(__E1000_RESETTING, &adapter->flags);
520}
521
522void
499e1000_reset(struct e1000_adapter *adapter) 523e1000_reset(struct e1000_adapter *adapter)
500{ 524{
501 uint32_t pba, manc; 525 uint32_t pba, manc;
@@ -758,9 +782,6 @@ e1000_probe(struct pci_dev *pdev,
758 adapter->watchdog_timer.function = &e1000_watchdog; 782 adapter->watchdog_timer.function = &e1000_watchdog;
759 adapter->watchdog_timer.data = (unsigned long) adapter; 783 adapter->watchdog_timer.data = (unsigned long) adapter;
760 784
761 INIT_WORK(&adapter->watchdog_task,
762 (void (*)(void *))e1000_watchdog_task, adapter);
763
764 init_timer(&adapter->phy_info_timer); 785 init_timer(&adapter->phy_info_timer);
765 adapter->phy_info_timer.function = &e1000_update_phy_info; 786 adapter->phy_info_timer.function = &e1000_update_phy_info;
766 adapter->phy_info_timer.data = (unsigned long) adapter; 787 adapter->phy_info_timer.data = (unsigned long) adapter;
@@ -1078,6 +1099,10 @@ e1000_open(struct net_device *netdev)
1078 struct e1000_adapter *adapter = netdev_priv(netdev); 1099 struct e1000_adapter *adapter = netdev_priv(netdev);
1079 int err; 1100 int err;
1080 1101
1102 /* disallow open during test */
1103 if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
1104 return -EBUSY;
1105
1081 /* allocate transmit descriptors */ 1106 /* allocate transmit descriptors */
1082 1107
1083 if ((err = e1000_setup_all_tx_resources(adapter))) 1108 if ((err = e1000_setup_all_tx_resources(adapter)))
@@ -1088,6 +1113,10 @@ e1000_open(struct net_device *netdev)
1088 if ((err = e1000_setup_all_rx_resources(adapter))) 1113 if ((err = e1000_setup_all_rx_resources(adapter)))
1089 goto err_setup_rx; 1114 goto err_setup_rx;
1090 1115
1116 err = e1000_request_irq(adapter);
1117 if (err)
1118 goto err_up;
1119
1091 if ((err = e1000_up(adapter))) 1120 if ((err = e1000_up(adapter)))
1092 goto err_up; 1121 goto err_up;
1093 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; 1122 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
@@ -1131,7 +1160,9 @@ e1000_close(struct net_device *netdev)
1131{ 1160{
1132 struct e1000_adapter *adapter = netdev_priv(netdev); 1161 struct e1000_adapter *adapter = netdev_priv(netdev);
1133 1162
1163 WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
1134 e1000_down(adapter); 1164 e1000_down(adapter);
1165 e1000_free_irq(adapter);
1135 1166
1136 e1000_free_all_tx_resources(adapter); 1167 e1000_free_all_tx_resources(adapter);
1137 e1000_free_all_rx_resources(adapter); 1168 e1000_free_all_rx_resources(adapter);
@@ -2201,14 +2232,6 @@ static void
2201e1000_watchdog(unsigned long data) 2232e1000_watchdog(unsigned long data)
2202{ 2233{
2203 struct e1000_adapter *adapter = (struct e1000_adapter *) data; 2234 struct e1000_adapter *adapter = (struct e1000_adapter *) data;
2204
2205 /* Do the rest outside of interrupt context */
2206 schedule_work(&adapter->watchdog_task);
2207}
2208
2209static void
2210e1000_watchdog_task(struct e1000_adapter *adapter)
2211{
2212 struct net_device *netdev = adapter->netdev; 2235 struct net_device *netdev = adapter->netdev;
2213 struct e1000_tx_ring *txdr = adapter->tx_ring; 2236 struct e1000_tx_ring *txdr = adapter->tx_ring;
2214 uint32_t link, tctl; 2237 uint32_t link, tctl;
@@ -2919,8 +2942,7 @@ e1000_reset_task(struct net_device *netdev)
2919{ 2942{
2920 struct e1000_adapter *adapter = netdev_priv(netdev); 2943 struct e1000_adapter *adapter = netdev_priv(netdev);
2921 2944
2922 e1000_down(adapter); 2945 e1000_reinit_locked(adapter);
2923 e1000_up(adapter);
2924} 2946}
2925 2947
2926/** 2948/**
@@ -3026,10 +3048,8 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
3026 3048
3027 netdev->mtu = new_mtu; 3049 netdev->mtu = new_mtu;
3028 3050
3029 if (netif_running(netdev)) { 3051 if (netif_running(netdev))
3030 e1000_down(adapter); 3052 e1000_reinit_locked(adapter);
3031 e1000_up(adapter);
3032 }
3033 3053
3034 adapter->hw.max_frame_size = max_frame; 3054 adapter->hw.max_frame_size = max_frame;
3035 3055
@@ -4180,10 +4200,9 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
4180 return retval; 4200 return retval;
4181 } 4201 }
4182 } 4202 }
4183 if (netif_running(adapter->netdev)) { 4203 if (netif_running(adapter->netdev))
4184 e1000_down(adapter); 4204 e1000_reinit_locked(adapter);
4185 e1000_up(adapter); 4205 else
4186 } else
4187 e1000_reset(adapter); 4206 e1000_reset(adapter);
4188 break; 4207 break;
4189 case M88E1000_PHY_SPEC_CTRL: 4208 case M88E1000_PHY_SPEC_CTRL:
@@ -4200,10 +4219,9 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
4200 case PHY_CTRL: 4219 case PHY_CTRL:
4201 if (mii_reg & MII_CR_POWER_DOWN) 4220 if (mii_reg & MII_CR_POWER_DOWN)
4202 break; 4221 break;
4203 if (netif_running(adapter->netdev)) { 4222 if (netif_running(adapter->netdev))
4204 e1000_down(adapter); 4223 e1000_reinit_locked(adapter);
4205 e1000_up(adapter); 4224 else
4206 } else
4207 e1000_reset(adapter); 4225 e1000_reset(adapter);
4208 break; 4226 break;
4209 } 4227 }
@@ -4462,8 +4480,10 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
4462 4480
4463 netif_device_detach(netdev); 4481 netif_device_detach(netdev);
4464 4482
4465 if (netif_running(netdev)) 4483 if (netif_running(netdev)) {
4484 WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4466 e1000_down(adapter); 4485 e1000_down(adapter);
4486 }
4467 4487
4468#ifdef CONFIG_PM 4488#ifdef CONFIG_PM
4469 /* Implement our own version of pci_save_state(pdev) because pci- 4489 /* Implement our own version of pci_save_state(pdev) because pci-