Add EEE advertising support for i225 series NICs. This is mostly identical to IGC driver, with some minor differences due to the way IGC driver was originally generated.
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com> --- drivers/net/intel/e1000/base/e1000_defines.h | 9 +++ drivers/net/intel/e1000/base/e1000_i225.c | 68 ++++++++++++++++++++ drivers/net/intel/e1000/base/e1000_i225.h | 2 + drivers/net/intel/e1000/base/e1000_regs.h | 1 + 4 files changed, 80 insertions(+) diff --git a/drivers/net/intel/e1000/base/e1000_defines.h b/drivers/net/intel/e1000/base/e1000_defines.h index 10009d7a19..a32100195a 100644 --- a/drivers/net/intel/e1000/base/e1000_defines.h +++ b/drivers/net/intel/e1000/base/e1000_defines.h @@ -863,6 +863,15 @@ #define E1000_EEE_SU_LPI_CLK_STP 0x00800000 /* EEE LPI Clock Stop */ #define E1000_EEE_LP_ADV_DEV_I210 7 /* EEE LP Adv Device */ #define E1000_EEE_LP_ADV_ADDR_I210 61 /* EEE LP Adv Register */ +#define E1000_EEE_SU_LPI_CLK_STP 0x00800000 /* EEE LPI Clock Stop */ +#define E1000_EEE_LP_ADV_DEV_I225 7 /* EEE LP Adv Device */ +#define E1000_EEE_LP_ADV_ADDR_I225 61 /* EEE LP Adv Register */ +#define E1000_EEE_LP_ADV_2_5G 0 /* EEE LP Adv 2.5G */ +#define E1000_EEE_LP_ADV_1G 2 /* EEE LP Adv 1G */ +#define E1000_EEE_LP_ADV_100M 1 /* EEE LP Adv 100M */ +#define E1000_ANEG_EEE_AN_LPAB1_I225 26 /* EEE LP Ability 1 Offset */ +#define E1000_ANEG_EEE_AN_LPAB2_I225 0x2A /* EEE LP Ability 2 Offset */ + /* PCI Express Control */ #define E1000_GCR_RXD_NO_SNOOP 0x00000001 #define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 diff --git a/drivers/net/intel/e1000/base/e1000_i225.c b/drivers/net/intel/e1000/base/e1000_i225.c index 9a512f3baf..067ec8924d 100644 --- a/drivers/net/intel/e1000/base/e1000_i225.c +++ b/drivers/net/intel/e1000/base/e1000_i225.c @@ -128,6 +128,9 @@ STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw) mac->ops.id_led_init = e1000_id_led_init_i225; mac->ops.blink_led = e1000_blink_led_i225; + /* Disable EEE by default */ + dev_spec->eee_disable = true; + return E1000_SUCCESS; } @@ -1183,6 +1186,7 @@ s32 e1000_init_hw_i225(struct e1000_hw *hw) hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i225; ret_val = e1000_init_hw_base(hw); + e1000_set_eee_i225(hw, false, false, false); return ret_val; } @@ -1282,3 +1286,67 @@ s32 e1000_id_led_init_i225(struct e1000_hw *hw) return E1000_SUCCESS; } + +/** + * e1000_set_eee_i225 - Enable/disable EEE support + * @hw: pointer to the HW structure + * @adv2p5G: boolean flag enabling 2.5G EEE advertisement + * @adv1G: boolean flag enabling 1G EEE advertisement + * @adv100M: boolean flag enabling 100M EEE advertisement + * + * Enable/disable EEE based on setting in dev_spec structure. + * + **/ +s32 e1000_set_eee_i225(struct e1000_hw *hw, bool adv2p5G, bool adv1G, + bool adv100M) +{ + u32 ipcnfg, eeer; + + DEBUGFUNC("e1000_set_eee_i225"); + + if (hw->mac.type != e1000_i225 || + hw->phy.media_type != e1000_media_type_copper) + goto out; + ipcnfg = E1000_READ_REG(hw, E1000_IPCNFG); + eeer = E1000_READ_REG(hw, E1000_EEER); + + /* enable or disable per user setting */ + if (!(hw->dev_spec._i225.eee_disable)) { + u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU); + + if (adv100M) + ipcnfg |= E1000_IPCNFG_EEE_100M_AN; + else + ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN; + + if (adv1G) + ipcnfg |= E1000_IPCNFG_EEE_1G_AN; + else + ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN; + + if (adv2p5G) + ipcnfg |= E1000_IPCNFG_EEE_2_5G_AN; + else + ipcnfg &= ~E1000_IPCNFG_EEE_2_5G_AN; + + eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); + + /* This bit should not be set in normal operation. */ + if (eee_su & E1000_EEE_SU_LPI_CLK_STP) + DEBUGOUT("LPI Clock Stop Bit should not be set!\n"); + } else { + ipcnfg &= ~(E1000_IPCNFG_EEE_2_5G_AN | E1000_IPCNFG_EEE_1G_AN | + E1000_IPCNFG_EEE_100M_AN); + eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); + } + E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg); + E1000_WRITE_REG(hw, E1000_EEER, eeer); + E1000_READ_REG(hw, E1000_IPCNFG); + E1000_READ_REG(hw, E1000_EEER); +out: + + return E1000_SUCCESS; +} + diff --git a/drivers/net/intel/e1000/base/e1000_i225.h b/drivers/net/intel/e1000/base/e1000_i225.h index cd6e7d0f6f..d9e02383c3 100644 --- a/drivers/net/intel/e1000/base/e1000_i225.h +++ b/drivers/net/intel/e1000/base/e1000_i225.h @@ -27,6 +27,8 @@ s32 e1000_init_hw_i225(struct e1000_hw *hw); s32 e1000_setup_copper_link_i225(struct e1000_hw *hw); s32 e1000_set_d0_lplu_state_i225(struct e1000_hw *hw, bool active); s32 e1000_set_d3_lplu_state_i225(struct e1000_hw *hw, bool active); +s32 e1000_set_eee_i225(struct e1000_hw *hw, bool adv2p5G, bool adv1G, + bool adv100M); #define ID_LED_DEFAULT_I225 ((ID_LED_OFF1_ON2 << 8) | \ (ID_LED_DEF1_DEF2 << 4) | \ diff --git a/drivers/net/intel/e1000/base/e1000_regs.h b/drivers/net/intel/e1000/base/e1000_regs.h index 04bb94f819..3a4779f80b 100644 --- a/drivers/net/intel/e1000/base/e1000_regs.h +++ b/drivers/net/intel/e1000/base/e1000_regs.h @@ -688,6 +688,7 @@ #define E1000_LTRC 0x01A0 /* Latency Tolerance Reporting Control */ #define E1000_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/ #define E1000_EEE_SU 0x0E34 /* EEE Setup */ +#define E1000_EEE_SU_2P5 0x0E3C /* EEE 2.5G Setup */ #define E1000_TLPIC 0x4148 /* EEE Tx LPI Count - TLPIC */ #define E1000_RLPIC 0x414C /* EEE Rx LPI Count - RLPIC */ -- 2.43.5