aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-05-10 10:59:31 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-13 02:31:09 -0400
commit11b08be830078c1cc4af484d0f85c3a010319c97 (patch)
treebf0cd95d65cdeb4c9fbc61d6a7cce0032fcad691 /drivers/net/e1000e
parent4fe4491fc5578019174d0f02d1ae740fce78deac (diff)
e1000e: bad state after running ethtool diagnostics with AMT enabled
When running ethtool online diagnostics with no open interface, there is a short period of time where the driver relinquishes control of the adapter during which time AMT (manageability firmware) can put the adapter into an unknown state resulting in such things as link test failure, hardware hang, reporting an incorrect link speed, etc. Resetting the adapter during an open() resolves this by putting the adapter into a quiescent state. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/ethtool.c9
-rw-r--r--drivers/net/e1000e/netdev.c16
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6ff376cfe139..2c521218102b 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1737,6 +1737,12 @@ static void e1000_diag_test(struct net_device *netdev,
1737 if (if_running) 1737 if (if_running)
1738 dev_open(netdev); 1738 dev_open(netdev);
1739 } else { 1739 } else {
1740 if (!if_running && (adapter->flags & FLAG_HAS_AMT)) {
1741 clear_bit(__E1000_TESTING, &adapter->state);
1742 dev_open(netdev);
1743 set_bit(__E1000_TESTING, &adapter->state);
1744 }
1745
1740 e_info("online testing starting\n"); 1746 e_info("online testing starting\n");
1741 /* Online tests */ 1747 /* Online tests */
1742 if (e1000_link_test(adapter, &data[4])) 1748 if (e1000_link_test(adapter, &data[4]))
@@ -1748,6 +1754,9 @@ static void e1000_diag_test(struct net_device *netdev,
1748 data[2] = 0; 1754 data[2] = 0;
1749 data[3] = 0; 1755 data[3] = 0;
1750 1756
1757 if (!if_running && (adapter->flags & FLAG_HAS_AMT))
1758 dev_close(netdev);
1759
1751 clear_bit(__E1000_TESTING, &adapter->state); 1760 clear_bit(__E1000_TESTING, &adapter->state);
1752 } 1761 }
1753 msleep_interruptible(4 * 1000); 1762 msleep_interruptible(4 * 1000);
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c5f65a29865a..ab79bec082f0 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3444,6 +3444,15 @@ static int e1000_open(struct net_device *netdev)
3444 if (err) 3444 if (err)
3445 goto err_setup_rx; 3445 goto err_setup_rx;
3446 3446
3447 /*
3448 * If AMT is enabled, let the firmware know that the network
3449 * interface is now open and reset the part to a known state.
3450 */
3451 if (adapter->flags & FLAG_HAS_AMT) {
3452 e1000_get_hw_control(adapter);
3453 e1000e_reset(adapter);
3454 }
3455
3447 e1000e_power_up_phy(adapter); 3456 e1000e_power_up_phy(adapter);
3448 3457
3449 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; 3458 adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
@@ -3452,13 +3461,6 @@ static int e1000_open(struct net_device *netdev)
3452 e1000_update_mng_vlan(adapter); 3461 e1000_update_mng_vlan(adapter);
3453 3462
3454 /* 3463 /*
3455 * If AMT is enabled, let the firmware know that the network
3456 * interface is now open
3457 */
3458 if (adapter->flags & FLAG_HAS_AMT)
3459 e1000_get_hw_control(adapter);
3460
3461 /*
3462 * before we allocate an interrupt, we must be ready to handle it. 3464 * before we allocate an interrupt, we must be ready to handle it.
3463 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt 3465 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
3464 * as soon as we call pci_request_irq, so we have to setup our 3466 * as soon as we call pci_request_irq, so we have to setup our