diff options
-rw-r--r-- | drivers/net/e1000e/82571.c | 26 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 21 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 23 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 50 | ||||
-rw-r--r-- | drivers/net/e1000e/phy.c | 37 |
7 files changed, 122 insertions, 39 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 8ea3ed7e5364..26ea5d57a354 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -69,6 +69,7 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw); | |||
69 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | 69 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); |
70 | static s32 e1000_led_on_82574(struct e1000_hw *hw); | 70 | static s32 e1000_led_on_82574(struct e1000_hw *hw); |
71 | static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); | 71 | static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); |
72 | static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); | ||
72 | 73 | ||
73 | /** | 74 | /** |
74 | * e1000_init_phy_params_82571 - Init PHY func ptrs. | 75 | * e1000_init_phy_params_82571 - Init PHY func ptrs. |
@@ -88,6 +89,9 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) | |||
88 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | 89 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; |
89 | phy->reset_delay_us = 100; | 90 | phy->reset_delay_us = 100; |
90 | 91 | ||
92 | phy->ops.power_up = e1000_power_up_phy_copper; | ||
93 | phy->ops.power_down = e1000_power_down_phy_copper_82571; | ||
94 | |||
91 | switch (hw->mac.type) { | 95 | switch (hw->mac.type) { |
92 | case e1000_82571: | 96 | case e1000_82571: |
93 | case e1000_82572: | 97 | case e1000_82572: |
@@ -1601,6 +1605,28 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) | |||
1601 | } | 1605 | } |
1602 | 1606 | ||
1603 | /** | 1607 | /** |
1608 | * e1000_power_down_phy_copper_82571 - Remove link during PHY power down | ||
1609 | * @hw: pointer to the HW structure | ||
1610 | * | ||
1611 | * In the case of a PHY power down to save power, or to turn off link during a | ||
1612 | * driver unload, or wake on lan is not enabled, remove the link. | ||
1613 | **/ | ||
1614 | static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) | ||
1615 | { | ||
1616 | struct e1000_phy_info *phy = &hw->phy; | ||
1617 | struct e1000_mac_info *mac = &hw->mac; | ||
1618 | |||
1619 | if (!(phy->ops.check_reset_block)) | ||
1620 | return; | ||
1621 | |||
1622 | /* If the management interface is not enabled, then power down */ | ||
1623 | if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) | ||
1624 | e1000_power_down_phy_copper(hw); | ||
1625 | |||
1626 | return; | ||
1627 | } | ||
1628 | |||
1629 | /** | ||
1604 | * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters | 1630 | * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters |
1605 | * @hw: pointer to the HW structure | 1631 | * @hw: pointer to the HW structure |
1606 | * | 1632 | * |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 4c08752b824d..c4e861fb3862 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -568,6 +568,8 @@ extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, | |||
568 | extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, | 568 | extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, |
569 | u32 usec_interval, bool *success); | 569 | u32 usec_interval, bool *success); |
570 | extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); | 570 | extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); |
571 | extern void e1000_power_up_phy_copper(struct e1000_hw *hw); | ||
572 | extern void e1000_power_down_phy_copper(struct e1000_hw *hw); | ||
571 | extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); | 573 | extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); |
572 | extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); | 574 | extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); |
573 | extern s32 e1000e_check_downshift(struct e1000_hw *hw); | 575 | extern s32 e1000e_check_downshift(struct e1000_hw *hw); |
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 3f435c16608d..c7bc657b5da2 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c | |||
@@ -114,6 +114,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, | |||
114 | u16 *data); | 114 | u16 *data); |
115 | static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, | 115 | static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, |
116 | u16 data); | 116 | u16 data); |
117 | static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); | ||
117 | 118 | ||
118 | /** | 119 | /** |
119 | * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. | 120 | * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. |
@@ -127,6 +128,9 @@ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) | |||
127 | if (hw->phy.media_type != e1000_media_type_copper) { | 128 | if (hw->phy.media_type != e1000_media_type_copper) { |
128 | phy->type = e1000_phy_none; | 129 | phy->type = e1000_phy_none; |
129 | return 0; | 130 | return 0; |
131 | } else { | ||
132 | phy->ops.power_up = e1000_power_up_phy_copper; | ||
133 | phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; | ||
130 | } | 134 | } |
131 | 135 | ||
132 | phy->addr = 1; | 136 | phy->addr = 1; |
@@ -1303,6 +1307,23 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, | |||
1303 | } | 1307 | } |
1304 | 1308 | ||
1305 | /** | 1309 | /** |
1310 | * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down | ||
1311 | * @hw: pointer to the HW structure | ||
1312 | * | ||
1313 | * In the case of a PHY power down to save power, or to turn off link during a | ||
1314 | * driver unload, or wake on lan is not enabled, remove the link. | ||
1315 | **/ | ||
1316 | static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) | ||
1317 | { | ||
1318 | /* If the management interface is not enabled, then power down */ | ||
1319 | if (!(hw->mac.ops.check_mng_mode(hw) || | ||
1320 | hw->phy.ops.check_reset_block(hw))) | ||
1321 | e1000_power_down_phy_copper(hw); | ||
1322 | |||
1323 | return; | ||
1324 | } | ||
1325 | |||
1326 | /** | ||
1306 | * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters | 1327 | * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters |
1307 | * @hw: pointer to the HW structure | 1328 | * @hw: pointer to the HW structure |
1308 | * | 1329 | * |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 6c3d55fc7753..e0addf3eea8a 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -774,6 +774,8 @@ struct e1000_phy_operations { | |||
774 | s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); | 774 | s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); |
775 | s32 (*write_reg)(struct e1000_hw *, u32, u16); | 775 | s32 (*write_reg)(struct e1000_hw *, u32, u16); |
776 | s32 (*write_reg_locked)(struct e1000_hw *, u32, u16); | 776 | s32 (*write_reg_locked)(struct e1000_hw *, u32, u16); |
777 | void (*power_up)(struct e1000_hw *); | ||
778 | void (*power_down)(struct e1000_hw *); | ||
777 | }; | 779 | }; |
778 | 780 | ||
779 | /* Function pointers for the NVM. */ | 781 | /* Function pointers for the NVM. */ |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 7530fc5d81c3..9c3895598923 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -217,6 +217,7 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); | |||
217 | static s32 e1000_led_on_pchlan(struct e1000_hw *hw); | 217 | static s32 e1000_led_on_pchlan(struct e1000_hw *hw); |
218 | static s32 e1000_led_off_pchlan(struct e1000_hw *hw); | 218 | static s32 e1000_led_off_pchlan(struct e1000_hw *hw); |
219 | static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); | 219 | static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); |
220 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); | ||
220 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); | 221 | static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); |
221 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); | 222 | static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); |
222 | 223 | ||
@@ -266,6 +267,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
266 | phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; | 267 | phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan; |
267 | phy->ops.write_reg = e1000_write_phy_reg_hv; | 268 | phy->ops.write_reg = e1000_write_phy_reg_hv; |
268 | phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; | 269 | phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked; |
270 | phy->ops.power_up = e1000_power_up_phy_copper; | ||
271 | phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; | ||
269 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; | 272 | phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; |
270 | 273 | ||
271 | phy->id = e1000_phy_unknown; | 274 | phy->id = e1000_phy_unknown; |
@@ -299,6 +302,9 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) | |||
299 | phy->addr = 1; | 302 | phy->addr = 1; |
300 | phy->reset_delay_us = 100; | 303 | phy->reset_delay_us = 100; |
301 | 304 | ||
305 | phy->ops.power_up = e1000_power_up_phy_copper; | ||
306 | phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; | ||
307 | |||
302 | /* | 308 | /* |
303 | * We may need to do this twice - once for IGP and if that fails, | 309 | * We may need to do this twice - once for IGP and if that fails, |
304 | * we'll set BM func pointers and try again | 310 | * we'll set BM func pointers and try again |
@@ -3392,6 +3398,23 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) | |||
3392 | } | 3398 | } |
3393 | 3399 | ||
3394 | /** | 3400 | /** |
3401 | * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down | ||
3402 | * @hw: pointer to the HW structure | ||
3403 | * | ||
3404 | * In the case of a PHY power down to save power, or to turn off link during a | ||
3405 | * driver unload, or wake on lan is not enabled, remove the link. | ||
3406 | **/ | ||
3407 | static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) | ||
3408 | { | ||
3409 | /* If the management interface is not enabled, then power down */ | ||
3410 | if (!(hw->mac.ops.check_mng_mode(hw) || | ||
3411 | hw->phy.ops.check_reset_block(hw))) | ||
3412 | e1000_power_down_phy_copper(hw); | ||
3413 | |||
3414 | return; | ||
3415 | } | ||
3416 | |||
3417 | /** | ||
3395 | * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters | 3418 | * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters |
3396 | * @hw: pointer to the HW structure | 3419 | * @hw: pointer to the HW structure |
3397 | * | 3420 | * |
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); |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 9ce499734dca..140b23b320fd 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -2534,6 +2534,43 @@ out: | |||
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | /** | 2536 | /** |
2537 | * e1000_power_up_phy_copper - Restore copper link in case of PHY power down | ||
2538 | * @hw: pointer to the HW structure | ||
2539 | * | ||
2540 | * In the case of a PHY power down to save power, or to turn off link during a | ||
2541 | * driver unload, or wake on lan is not enabled, restore the link to previous | ||
2542 | * settings. | ||
2543 | **/ | ||
2544 | void e1000_power_up_phy_copper(struct e1000_hw *hw) | ||
2545 | { | ||
2546 | u16 mii_reg = 0; | ||
2547 | |||
2548 | /* The PHY will retain its settings across a power down/up cycle */ | ||
2549 | e1e_rphy(hw, PHY_CONTROL, &mii_reg); | ||
2550 | mii_reg &= ~MII_CR_POWER_DOWN; | ||
2551 | e1e_wphy(hw, PHY_CONTROL, mii_reg); | ||
2552 | } | ||
2553 | |||
2554 | /** | ||
2555 | * e1000_power_down_phy_copper - Restore copper link in case of PHY power down | ||
2556 | * @hw: pointer to the HW structure | ||
2557 | * | ||
2558 | * In the case of a PHY power down to save power, or to turn off link during a | ||
2559 | * driver unload, or wake on lan is not enabled, restore the link to previous | ||
2560 | * settings. | ||
2561 | **/ | ||
2562 | void e1000_power_down_phy_copper(struct e1000_hw *hw) | ||
2563 | { | ||
2564 | u16 mii_reg = 0; | ||
2565 | |||
2566 | /* The PHY will retain its settings across a power down/up cycle */ | ||
2567 | e1e_rphy(hw, PHY_CONTROL, &mii_reg); | ||
2568 | mii_reg |= MII_CR_POWER_DOWN; | ||
2569 | e1e_wphy(hw, PHY_CONTROL, mii_reg); | ||
2570 | msleep(1); | ||
2571 | } | ||
2572 | |||
2573 | /** | ||
2537 | * e1000e_commit_phy - Soft PHY reset | 2574 | * e1000e_commit_phy - Soft PHY reset |
2538 | * @hw: pointer to the HW structure | 2575 | * @hw: pointer to the HW structure |
2539 | * | 2576 | * |