diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2011-01-06 09:29:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-10 02:44:09 -0500 |
commit | 31dbe5b4ac6fca72dec946e4d0fa7f0913f1d9b1 (patch) | |
tree | 8774e4836c881a7a2c18ddb02f253b66c82aec6c /drivers/net/e1000e/ethtool.c | |
parent | fe46f58fa61f025564a3c1e80b789885cb4b0f30 (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.c | 40 |
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 | ||