aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e1000e/82571.c26
-rw-r--r--drivers/net/e1000e/e1000.h2
-rw-r--r--drivers/net/e1000e/es2lan.c21
-rw-r--r--drivers/net/e1000e/hw.h2
-rw-r--r--drivers/net/e1000e/ich8lan.c23
-rw-r--r--drivers/net/e1000e/netdev.c50
-rw-r--r--drivers/net/e1000e/phy.c37
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);
69static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); 69static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
70static s32 e1000_led_on_82574(struct e1000_hw *hw); 70static s32 e1000_led_on_82574(struct e1000_hw *hw);
71static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); 71static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
72static 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 **/
1614static 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,
568extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, 568extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
569 u32 usec_interval, bool *success); 569 u32 usec_interval, bool *success);
570extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); 570extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
571extern void e1000_power_up_phy_copper(struct e1000_hw *hw);
572extern void e1000_power_down_phy_copper(struct e1000_hw *hw);
571extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); 573extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
572extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); 574extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
573extern s32 e1000e_check_downshift(struct e1000_hw *hw); 575extern 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);
115static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, 115static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
116 u16 data); 116 u16 data);
117static 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 **/
1316static 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);
217static s32 e1000_led_on_pchlan(struct e1000_hw *hw); 217static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
218static s32 e1000_led_off_pchlan(struct e1000_hw *hw); 218static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
219static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); 219static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
220static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
220static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); 221static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
221static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); 222static 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 **/
3407static 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 **/
2642void e1000e_power_up_phy(struct e1000_adapter *adapter) 2642void 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 */
2666static void e1000_power_down_phy(struct e1000_adapter *adapter) 2656static 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 **/
2544void 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 **/
2562void 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 *