diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000e/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 41 | ||||
-rw-r--r-- | drivers/net/e1000e/param.c | 28 |
4 files changed, 70 insertions, 1 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 0e59f15be110..c233496b1f47 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -423,6 +423,7 @@ struct e1000_info { #define FLAG2_IS_DISCARDING (1 << 2) #define FLAG2_DISABLE_ASPM_L1 (1 << 3) #define FLAG2_HAS_PHY_STATS (1 << 4) +#define FLAG2_HAS_EEE (1 << 5) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 96116ce5e5cc..eecb2eca507b 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -937,6 +937,7 @@ struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; bool nvm_k1_enabled; + bool eee_disable; }; struct e1000_hw { diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 8274499b7df6..5e55de002487 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -131,6 +131,10 @@ /* PHY Power Management Control */ #define HV_PM_CTRL PHY_REG(770, 17) +/* PHY Low Power Idle Control */ +#define I82579_LPI_CTRL PHY_REG(772, 20) +#define I82579_LPI_CTRL_ENABLE_MASK 0x6000 + /* Strapping Option Register - RO */ #define E1000_STRAP 0x0000C #define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 @@ -569,6 +573,35 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) } /** + * e1000_set_eee_pchlan - Enable/disable EEE support + * @hw: pointer to the HW structure + * + * Enable/disable EEE based on setting in dev_spec structure. The bits in + * the LPI Control register will remain set only if/when link is up. + **/ +static s32 e1000_set_eee_pchlan(struct e1000_hw *hw) +{ + s32 ret_val = 0; + u16 phy_reg; + + if (hw->phy.type != e1000_phy_82579) + goto out; + + ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); + if (ret_val) + goto out; + + if (hw->dev_spec.ich8lan.eee_disable) + phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK; + else + phy_reg |= I82579_LPI_CTRL_ENABLE_MASK; + + ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); +out: + return ret_val; +} + +/** * e1000_check_for_copper_link_ich8lan - Check for link (Copper) * @hw: pointer to the HW structure * @@ -625,6 +658,11 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) */ e1000e_check_downshift(hw); + /* Enable/Disable EEE after link up */ + ret_val = e1000_set_eee_pchlan(hw); + if (ret_val) + goto out; + /* * If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. @@ -3820,7 +3858,8 @@ struct e1000_info e1000_pch2_info = { | FLAG_HAS_FLASH | FLAG_HAS_JUMBO_FRAMES | FLAG_APME_IN_WUC, - .flags2 = FLAG2_HAS_PHY_STATS, + .flags2 = FLAG2_HAS_PHY_STATS + | FLAG2_HAS_EEE, .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index a150e48a117f..a74846097afd 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -161,6 +161,15 @@ E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lea E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \ "the CRC"); +/* + * Enable/disable EEE (a.k.a. IEEE802.3az) + * + * Valid Range: 0, 1 + * + * Default Value: 1 + */ +E1000_PARAM(EEE, "Enable/disable on parts that support the feature"); + struct e1000_option { enum { enable_option, range_option, list_option } type; const char *name; @@ -477,4 +486,23 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) } } } + { /* EEE for parts supporting the feature */ + static const struct e1000_option opt = { + .type = enable_option, + .name = "EEE Support", + .err = "defaulting to Enabled", + .def = OPTION_ENABLED + }; + + if (adapter->flags2 & FLAG2_HAS_EEE) { + /* Currently only supported on 82579 */ + if (num_EEE > bd) { + unsigned int eee = EEE[bd]; + e1000_validate_option(&eee, &opt, adapter); + hw->dev_spec.ich8lan.eee_disable = !eee; + } else { + hw->dev_spec.ich8lan.eee_disable = !opt.def; + } + } + } } |