aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ethtool.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2011-01-06 09:29:52 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-10 02:44:09 -0500
commit31dbe5b4ac6fca72dec946e4d0fa7f0913f1d9b1 (patch)
tree8774e4836c881a7a2c18ddb02f253b66c82aec6c /drivers/net/e1000e/ethtool.c
parentfe46f58fa61f025564a3c1e80b789885cb4b0f30 (diff)
e1000e: power off PHY after reset when interface is down
Some Phys supported by the driver do not remain powered off across a reset of the device when the interface is down, e.g. on 82571, but not on 82574. This patch powers down (only when WoL is disabled) the PHY after a reset if the interface is down and the ethtool diagnostics are not currently running. The ethtool diagnostic function required a minor re-factor as a result, and the e1000_[get|put]_hw_control() functions are renamed since they are no longer static to netdev.c as they are needed by the ethtool diagnostics. A couple minor whitespace issues were cleaned up, too. Reported-by: Arthur Jones <ajones@riverbed.com> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@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/ethtool.c')
-rw-r--r--drivers/net/e1000e/ethtool.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index c942ccab8bca..f8ed03dab9b1 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1708,6 +1708,19 @@ static void e1000_diag_test(struct net_device *netdev,
1708 bool if_running = netif_running(netdev); 1708 bool if_running = netif_running(netdev);
1709 1709
1710 set_bit(__E1000_TESTING, &adapter->state); 1710 set_bit(__E1000_TESTING, &adapter->state);
1711
1712 if (!if_running) {
1713 /* Get control of and reset hardware */
1714 if (adapter->flags & FLAG_HAS_AMT)
1715 e1000e_get_hw_control(adapter);
1716
1717 e1000e_power_up_phy(adapter);
1718
1719 adapter->hw.phy.autoneg_wait_to_complete = 1;
1720 e1000e_reset(adapter);
1721 adapter->hw.phy.autoneg_wait_to_complete = 0;
1722 }
1723
1711 if (eth_test->flags == ETH_TEST_FL_OFFLINE) { 1724 if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
1712 /* Offline tests */ 1725 /* Offline tests */
1713 1726
@@ -1721,8 +1734,6 @@ static void e1000_diag_test(struct net_device *netdev,
1721 if (if_running) 1734 if (if_running)
1722 /* indicate we're in test mode */ 1735 /* indicate we're in test mode */
1723 dev_close(netdev); 1736 dev_close(netdev);
1724 else
1725 e1000e_reset(adapter);
1726 1737
1727 if (e1000_reg_test(adapter, &data[0])) 1738 if (e1000_reg_test(adapter, &data[0]))
1728 eth_test->flags |= ETH_TEST_FL_FAILED; 1739 eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1736,8 +1747,6 @@ static void e1000_diag_test(struct net_device *netdev,
1736 eth_test->flags |= ETH_TEST_FL_FAILED; 1747 eth_test->flags |= ETH_TEST_FL_FAILED;
1737 1748
1738 e1000e_reset(adapter); 1749 e1000e_reset(adapter);
1739 /* make sure the phy is powered up */
1740 e1000e_power_up_phy(adapter);
1741 if (e1000_loopback_test(adapter, &data[3])) 1750 if (e1000_loopback_test(adapter, &data[3]))
1742 eth_test->flags |= ETH_TEST_FL_FAILED; 1751 eth_test->flags |= ETH_TEST_FL_FAILED;
1743 1752
@@ -1759,28 +1768,29 @@ static void e1000_diag_test(struct net_device *netdev,
1759 if (if_running) 1768 if (if_running)
1760 dev_open(netdev); 1769 dev_open(netdev);
1761 } else { 1770 } else {
1762 if (!if_running && (adapter->flags & FLAG_HAS_AMT)) { 1771 /* Online tests */
1763 clear_bit(__E1000_TESTING, &adapter->state);
1764 dev_open(netdev);
1765 set_bit(__E1000_TESTING, &adapter->state);
1766 }
1767 1772
1768 e_info("online testing starting\n"); 1773 e_info("online testing starting\n");
1769 /* Online tests */
1770 if (e1000_link_test(adapter, &data[4]))
1771 eth_test->flags |= ETH_TEST_FL_FAILED;
1772 1774
1773 /* Online tests aren't run; pass by default */ 1775 /* register, eeprom, intr and loopback tests not run online */
1774 data[0] = 0; 1776 data[0] = 0;
1775 data[1] = 0; 1777 data[1] = 0;
1776 data[2] = 0; 1778 data[2] = 0;
1777 data[3] = 0; 1779 data[3] = 0;
1778 1780
1779 if (!if_running && (adapter->flags & FLAG_HAS_AMT)) 1781 if (e1000_link_test(adapter, &data[4]))
1780 dev_close(netdev); 1782 eth_test->flags |= ETH_TEST_FL_FAILED;
1781 1783
1782 clear_bit(__E1000_TESTING, &adapter->state); 1784 clear_bit(__E1000_TESTING, &adapter->state);
1783 } 1785 }
1786
1787 if (!if_running) {
1788 e1000e_reset(adapter);
1789
1790 if (adapter->flags & FLAG_HAS_AMT)
1791 e1000e_release_hw_control(adapter);
1792 }
1793
1784 msleep_interruptible(4 * 1000); 1794 msleep_interruptible(4 * 1000);
1785} 1795}
1786 1796