diff options
Diffstat (limited to 'drivers/net/igb/e1000_82575.c')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index c505b50d1fa3..9d7fa2fb85ea 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -727,6 +727,34 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw) } /** + * igb_power_up_serdes_link_82575 - Power up the serdes link after shutdown + * @hw: pointer to the HW structure + **/ +void igb_power_up_serdes_link_82575(struct e1000_hw *hw) +{ + u32 reg; + + + if ((hw->phy.media_type != e1000_media_type_internal_serdes) && + !igb_sgmii_active_82575(hw)) + return; + + /* Enable PCS to turn on link */ + reg = rd32(E1000_PCS_CFG0); + reg |= E1000_PCS_CFG_PCS_EN; + wr32(E1000_PCS_CFG0, reg); + + /* Power up the laser */ + reg = rd32(E1000_CTRL_EXT); + reg &= ~E1000_CTRL_EXT_SDP3_DATA; + wr32(E1000_CTRL_EXT, reg); + + /* flush the write to verify completion */ + wrfl(); + msleep(1); +} + +/** * igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex * @hw: pointer to the HW structure * @speed: stores the current speed @@ -791,27 +819,12 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) { u32 reg; - u16 eeprom_data = 0; - if (hw->phy.media_type != e1000_media_type_internal_serdes || + if (hw->phy.media_type != e1000_media_type_internal_serdes && igb_sgmii_active_82575(hw)) return; - if (hw->bus.func == E1000_FUNC_0) - hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); - else if (hw->mac.type == e1000_82580) - hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + - NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, - &eeprom_data); - else if (hw->bus.func == E1000_FUNC_1) - hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); - - /* - * If APM is not enabled in the EEPROM and management interface is - * not enabled, then power down. - */ - if (!(eeprom_data & E1000_NVM_APME_82575) && - !igb_enable_mng_pass_thru(hw)) { + if (!igb_enable_mng_pass_thru(hw)) { /* Disable PCS to turn off link */ reg = rd32(E1000_PCS_CFG0); reg &= ~E1000_PCS_CFG_PCS_EN; @@ -826,8 +839,6 @@ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw) wrfl(); msleep(1); } - - return; } /** @@ -1183,6 +1194,22 @@ out: } /** + * igb_power_down_phy_copper_82575 - Remove link during PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +void igb_power_down_phy_copper_82575(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(igb_enable_mng_pass_thru(hw) || igb_check_reset_block(hw))) + igb_power_down_phy_copper(hw); + + return; +} + +/** * igb_clear_hw_cntrs_82575 - Clear device specific hardware counters * @hw: pointer to the HW structure * |