diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2009-12-01 10:47:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-02 03:35:52 -0500 |
commit | 17f208deb9bf88315aa72c08c866a235c399fb9a (patch) | |
tree | 9cc8bc9ce40587590fcea9d80e134adaf54567b2 /drivers/net/e1000e/netdev.c | |
parent | eb656d4552a6c9de5fdcee4a376b171f57b8a4a2 (diff) |
e1000e: provide family-specific PHY power up/down operations
The different families (80003es2lan, 8257x, ICHx/PCH) supported by the
driver each have their own conditions when the PHY can be powered down.
This patch rewrites the PHY power up/down code to fit with the family-
specific style used in the driver. All pre-existing calls to power up or
down the PHY remain untouched. A new call to power down the PHY when
removing the driver when the interface is down replaces the current call
to reset the PHY in order to reduce power consumption.
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/netdev.c')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 50 |
1 files changed, 11 insertions, 39 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2381cb76f17c..ab4db5266f14 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2641,18 +2641,8 @@ static void e1000_configure(struct e1000_adapter *adapter) | |||
2641 | **/ | 2641 | **/ |
2642 | void e1000e_power_up_phy(struct e1000_adapter *adapter) | 2642 | void e1000e_power_up_phy(struct e1000_adapter *adapter) |
2643 | { | 2643 | { |
2644 | u16 mii_reg = 0; | 2644 | if (adapter->hw.phy.ops.power_up) |
2645 | 2645 | adapter->hw.phy.ops.power_up(&adapter->hw); | |
2646 | /* Just clear the power down bit to wake the phy back up */ | ||
2647 | if (adapter->hw.phy.media_type == e1000_media_type_copper) { | ||
2648 | /* | ||
2649 | * According to the manual, the phy will retain its | ||
2650 | * settings across a power-down/up cycle | ||
2651 | */ | ||
2652 | e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg); | ||
2653 | mii_reg &= ~MII_CR_POWER_DOWN; | ||
2654 | e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg); | ||
2655 | } | ||
2656 | 2646 | ||
2657 | adapter->hw.mac.ops.setup_link(&adapter->hw); | 2647 | adapter->hw.mac.ops.setup_link(&adapter->hw); |
2658 | } | 2648 | } |
@@ -2660,35 +2650,17 @@ void e1000e_power_up_phy(struct e1000_adapter *adapter) | |||
2660 | /** | 2650 | /** |
2661 | * e1000_power_down_phy - Power down the PHY | 2651 | * e1000_power_down_phy - Power down the PHY |
2662 | * | 2652 | * |
2663 | * Power down the PHY so no link is implied when interface is down | 2653 | * Power down the PHY so no link is implied when interface is down. |
2664 | * The PHY cannot be powered down is management or WoL is active | 2654 | * The PHY cannot be powered down if management or WoL is active. |
2665 | */ | 2655 | */ |
2666 | static void e1000_power_down_phy(struct e1000_adapter *adapter) | 2656 | static void e1000_power_down_phy(struct e1000_adapter *adapter) |
2667 | { | 2657 | { |
2668 | struct e1000_hw *hw = &adapter->hw; | ||
2669 | u16 mii_reg; | ||
2670 | |||
2671 | /* WoL is enabled */ | 2658 | /* WoL is enabled */ |
2672 | if (adapter->wol) | 2659 | if (adapter->wol) |
2673 | return; | 2660 | return; |
2674 | 2661 | ||
2675 | /* non-copper PHY? */ | 2662 | if (adapter->hw.phy.ops.power_down) |
2676 | if (adapter->hw.phy.media_type != e1000_media_type_copper) | 2663 | adapter->hw.phy.ops.power_down(&adapter->hw); |
2677 | return; | ||
2678 | |||
2679 | /* reset is blocked because of a SoL/IDER session */ | ||
2680 | if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw)) | ||
2681 | return; | ||
2682 | |||
2683 | /* manageability (AMT) is enabled */ | ||
2684 | if (er32(MANC) & E1000_MANC_SMBUS_EN) | ||
2685 | return; | ||
2686 | |||
2687 | /* power down the PHY */ | ||
2688 | e1e_rphy(hw, PHY_CONTROL, &mii_reg); | ||
2689 | mii_reg |= MII_CR_POWER_DOWN; | ||
2690 | e1e_wphy(hw, PHY_CONTROL, mii_reg); | ||
2691 | mdelay(1); | ||
2692 | } | 2664 | } |
2693 | 2665 | ||
2694 | /** | 2666 | /** |
@@ -5294,17 +5266,17 @@ static void __devexit e1000_remove(struct pci_dev *pdev) | |||
5294 | cancel_work_sync(&adapter->print_hang_task); | 5266 | cancel_work_sync(&adapter->print_hang_task); |
5295 | flush_scheduled_work(); | 5267 | flush_scheduled_work(); |
5296 | 5268 | ||
5269 | if (!(netdev->flags & IFF_UP)) | ||
5270 | e1000_power_down_phy(adapter); | ||
5271 | |||
5272 | unregister_netdev(netdev); | ||
5273 | |||
5297 | /* | 5274 | /* |
5298 | * Release control of h/w to f/w. If f/w is AMT enabled, this | 5275 | * Release control of h/w to f/w. If f/w is AMT enabled, this |
5299 | * would have already happened in close and is redundant. | 5276 | * would have already happened in close and is redundant. |
5300 | */ | 5277 | */ |
5301 | e1000_release_hw_control(adapter); | 5278 | e1000_release_hw_control(adapter); |
5302 | 5279 | ||
5303 | unregister_netdev(netdev); | ||
5304 | |||
5305 | if (!e1000_check_reset_block(&adapter->hw)) | ||
5306 | e1000_phy_hw_reset(&adapter->hw); | ||
5307 | |||
5308 | e1000e_reset_interrupt_capability(adapter); | 5280 | e1000e_reset_interrupt_capability(adapter); |
5309 | kfree(adapter->tx_ring); | 5281 | kfree(adapter->tx_ring); |
5310 | kfree(adapter->rx_ring); | 5282 | kfree(adapter->rx_ring); |