From e52997f96008fda655d7ec3aa4297d1272e8a385 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 16 Jun 2010 13:27:49 +0000 Subject: [PATCH] e1000e: enable support for EEE on 82579 This patch enables IEEE802.3az (a.k.a. Energy Efficient Ethernet) on the new 82579 LOMs. An optional module parameter is provided to disable the feature if desired. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/e1000.h | 1 + drivers/net/e1000e/hw.h | 1 + drivers/net/e1000e/ich8lan.c | 41 +++++++++++++++++++++++++++++++++++- drivers/net/e1000e/param.c | 28 ++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) 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 @@ -568,6 +572,35 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) return 0; } +/** + * 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; + } + } + } } -- 2.20.1