aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
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
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')
-rw-r--r--drivers/net/e1000e/e1000.h2
-rw-r--r--drivers/net/e1000e/ethtool.c40
-rw-r--r--drivers/net/e1000e/netdev.c46
3 files changed, 53 insertions, 35 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 4b3802ae1082..5255be753746 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -497,6 +497,8 @@ extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
497extern void e1000e_update_stats(struct e1000_adapter *adapter); 497extern void e1000e_update_stats(struct e1000_adapter *adapter);
498extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); 498extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
499extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); 499extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
500extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
501extern void e1000e_release_hw_control(struct e1000_adapter *adapter);
500extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); 502extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
501 503
502extern unsigned int copybreak; 504extern unsigned int copybreak;
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
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 98729a6fb096..fa5b60452547 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1980,15 +1980,15 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
1980} 1980}
1981 1981
1982/** 1982/**
1983 * e1000_get_hw_control - get control of the h/w from f/w 1983 * e1000e_get_hw_control - get control of the h/w from f/w
1984 * @adapter: address of board private structure 1984 * @adapter: address of board private structure
1985 * 1985 *
1986 * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit. 1986 * e1000e_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
1987 * For ASF and Pass Through versions of f/w this means that 1987 * For ASF and Pass Through versions of f/w this means that
1988 * the driver is loaded. For AMT version (only with 82573) 1988 * the driver is loaded. For AMT version (only with 82573)
1989 * of the f/w this means that the network i/f is open. 1989 * of the f/w this means that the network i/f is open.
1990 **/ 1990 **/
1991static void e1000_get_hw_control(struct e1000_adapter *adapter) 1991void e1000e_get_hw_control(struct e1000_adapter *adapter)
1992{ 1992{
1993 struct e1000_hw *hw = &adapter->hw; 1993 struct e1000_hw *hw = &adapter->hw;
1994 u32 ctrl_ext; 1994 u32 ctrl_ext;
@@ -2005,16 +2005,16 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter)
2005} 2005}
2006 2006
2007/** 2007/**
2008 * e1000_release_hw_control - release control of the h/w to f/w 2008 * e1000e_release_hw_control - release control of the h/w to f/w
2009 * @adapter: address of board private structure 2009 * @adapter: address of board private structure
2010 * 2010 *
2011 * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit. 2011 * e1000e_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
2012 * For ASF and Pass Through versions of f/w this means that the 2012 * For ASF and Pass Through versions of f/w this means that the
2013 * driver is no longer loaded. For AMT version (only with 82573) i 2013 * driver is no longer loaded. For AMT version (only with 82573) i
2014 * of the f/w this means that the network i/f is closed. 2014 * of the f/w this means that the network i/f is closed.
2015 * 2015 *
2016 **/ 2016 **/
2017static void e1000_release_hw_control(struct e1000_adapter *adapter) 2017void e1000e_release_hw_control(struct e1000_adapter *adapter)
2018{ 2018{
2019 struct e1000_hw *hw = &adapter->hw; 2019 struct e1000_hw *hw = &adapter->hw;
2020 u32 ctrl_ext; 2020 u32 ctrl_ext;
@@ -2445,7 +2445,7 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
2445 E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && 2445 E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
2446 (vid == adapter->mng_vlan_id)) { 2446 (vid == adapter->mng_vlan_id)) {
2447 /* release control to f/w */ 2447 /* release control to f/w */
2448 e1000_release_hw_control(adapter); 2448 e1000e_release_hw_control(adapter);
2449 return; 2449 return;
2450 } 2450 }
2451 2451
@@ -3187,7 +3187,6 @@ void e1000e_reset(struct e1000_adapter *adapter)
3187 ew32(PBA, pba); 3187 ew32(PBA, pba);
3188 } 3188 }
3189 3189
3190
3191 /* 3190 /*
3192 * flow control settings 3191 * flow control settings
3193 * 3192 *
@@ -3275,7 +3274,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
3275 * that the network interface is in control 3274 * that the network interface is in control
3276 */ 3275 */
3277 if (adapter->flags & FLAG_HAS_AMT) 3276 if (adapter->flags & FLAG_HAS_AMT)
3278 e1000_get_hw_control(adapter); 3277 e1000e_get_hw_control(adapter);
3279 3278
3280 ew32(WUC, 0); 3279 ew32(WUC, 0);
3281 3280
@@ -3288,6 +3287,13 @@ void e1000e_reset(struct e1000_adapter *adapter)
3288 ew32(VET, ETH_P_8021Q); 3287 ew32(VET, ETH_P_8021Q);
3289 3288
3290 e1000e_reset_adaptive(hw); 3289 e1000e_reset_adaptive(hw);
3290
3291 if (!netif_running(adapter->netdev) &&
3292 !test_bit(__E1000_TESTING, &adapter->state)) {
3293 e1000_power_down_phy(adapter);
3294 return;
3295 }
3296
3291 e1000_get_phy_info(hw); 3297 e1000_get_phy_info(hw);
3292 3298
3293 if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && 3299 if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
@@ -3573,7 +3579,7 @@ static int e1000_open(struct net_device *netdev)
3573 * interface is now open and reset the part to a known state. 3579 * interface is now open and reset the part to a known state.
3574 */ 3580 */
3575 if (adapter->flags & FLAG_HAS_AMT) { 3581 if (adapter->flags & FLAG_HAS_AMT) {
3576 e1000_get_hw_control(adapter); 3582 e1000e_get_hw_control(adapter);
3577 e1000e_reset(adapter); 3583 e1000e_reset(adapter);
3578 } 3584 }
3579 3585
@@ -3637,7 +3643,7 @@ static int e1000_open(struct net_device *netdev)
3637 return 0; 3643 return 0;
3638 3644
3639err_req_irq: 3645err_req_irq:
3640 e1000_release_hw_control(adapter); 3646 e1000e_release_hw_control(adapter);
3641 e1000_power_down_phy(adapter); 3647 e1000_power_down_phy(adapter);
3642 e1000e_free_rx_resources(adapter); 3648 e1000e_free_rx_resources(adapter);
3643err_setup_rx: 3649err_setup_rx:
@@ -3692,8 +3698,9 @@ static int e1000_close(struct net_device *netdev)
3692 * If AMT is enabled, let the firmware know that the network 3698 * If AMT is enabled, let the firmware know that the network
3693 * interface is now closed 3699 * interface is now closed
3694 */ 3700 */
3695 if (adapter->flags & FLAG_HAS_AMT) 3701 if ((adapter->flags & FLAG_HAS_AMT) &&
3696 e1000_release_hw_control(adapter); 3702 !test_bit(__E1000_TESTING, &adapter->state))
3703 e1000e_release_hw_control(adapter);
3697 3704
3698 if ((adapter->flags & FLAG_HAS_ERT) || 3705 if ((adapter->flags & FLAG_HAS_ERT) ||
3699 (adapter->hw.mac.type == e1000_pch2lan)) 3706 (adapter->hw.mac.type == e1000_pch2lan))
@@ -5212,7 +5219,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
5212 * Release control of h/w to f/w. If f/w is AMT enabled, this 5219 * Release control of h/w to f/w. If f/w is AMT enabled, this
5213 * would have already happened in close and is redundant. 5220 * would have already happened in close and is redundant.
5214 */ 5221 */
5215 e1000_release_hw_control(adapter); 5222 e1000e_release_hw_control(adapter);
5216 5223
5217 pci_disable_device(pdev); 5224 pci_disable_device(pdev);
5218 5225
@@ -5369,7 +5376,7 @@ static int __e1000_resume(struct pci_dev *pdev)
5369 * under the control of the driver. 5376 * under the control of the driver.
5370 */ 5377 */
5371 if (!(adapter->flags & FLAG_HAS_AMT)) 5378 if (!(adapter->flags & FLAG_HAS_AMT))
5372 e1000_get_hw_control(adapter); 5379 e1000e_get_hw_control(adapter);
5373 5380
5374 return 0; 5381 return 0;
5375} 5382}
@@ -5616,7 +5623,7 @@ static void e1000_io_resume(struct pci_dev *pdev)
5616 * under the control of the driver. 5623 * under the control of the driver.
5617 */ 5624 */
5618 if (!(adapter->flags & FLAG_HAS_AMT)) 5625 if (!(adapter->flags & FLAG_HAS_AMT))
5619 e1000_get_hw_control(adapter); 5626 e1000e_get_hw_control(adapter);
5620 5627
5621} 5628}
5622 5629
@@ -5966,7 +5973,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
5966 * under the control of the driver. 5973 * under the control of the driver.
5967 */ 5974 */
5968 if (!(adapter->flags & FLAG_HAS_AMT)) 5975 if (!(adapter->flags & FLAG_HAS_AMT))
5969 e1000_get_hw_control(adapter); 5976 e1000e_get_hw_control(adapter);
5970 5977
5971 strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1); 5978 strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1);
5972 err = register_netdev(netdev); 5979 err = register_netdev(netdev);
@@ -5985,12 +5992,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
5985 5992
5986err_register: 5993err_register:
5987 if (!(adapter->flags & FLAG_HAS_AMT)) 5994 if (!(adapter->flags & FLAG_HAS_AMT))
5988 e1000_release_hw_control(adapter); 5995 e1000e_release_hw_control(adapter);
5989err_eeprom: 5996err_eeprom:
5990 if (!e1000_check_reset_block(&adapter->hw)) 5997 if (!e1000_check_reset_block(&adapter->hw))
5991 e1000_phy_hw_reset(&adapter->hw); 5998 e1000_phy_hw_reset(&adapter->hw);
5992err_hw_init: 5999err_hw_init:
5993
5994 kfree(adapter->tx_ring); 6000 kfree(adapter->tx_ring);
5995 kfree(adapter->rx_ring); 6001 kfree(adapter->rx_ring);
5996err_sw_init: 6002err_sw_init:
@@ -6056,7 +6062,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
6056 * Release control of h/w to f/w. If f/w is AMT enabled, this 6062 * Release control of h/w to f/w. If f/w is AMT enabled, this
6057 * would have already happened in close and is redundant. 6063 * would have already happened in close and is redundant.
6058 */ 6064 */
6059 e1000_release_hw_control(adapter); 6065 e1000e_release_hw_control(adapter);
6060 6066
6061 e1000e_reset_interrupt_capability(adapter); 6067 e1000e_reset_interrupt_capability(adapter);
6062 kfree(adapter->tx_ring); 6068 kfree(adapter->tx_ring);