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

Reply via email to