add i225 devices PHY type. Initialization phy's
ops.read and ops.write pointers.
Add relevant MMD registers and masks for i225 devices.
Implemented GPY methods for read and write PHY registers.

Signed-off-by: Sasha Neftin <sasha.nef...@intel.com>
Signed-off-by: Guinan Sun <guinanx....@intel.com>
---
 drivers/net/e1000/base/e1000_defines.h |  5 ++
 drivers/net/e1000/base/e1000_hw.h      |  1 +
 drivers/net/e1000/base/e1000_phy.c     | 82 +++++++++++++++++++++++++-
 drivers/net/e1000/base/e1000_phy.h     |  6 ++
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/net/e1000/base/e1000_defines.h 
b/drivers/net/e1000/base/e1000_defines.h
index ee2ecceee..3ef1e4d32 100644
--- a/drivers/net/e1000/base/e1000_defines.h
+++ b/drivers/net/e1000/base/e1000_defines.h
@@ -986,6 +986,11 @@
 #define PHY_1000T_STATUS       0x0A /* 1000Base-T Status Reg */
 #define PHY_EXT_STATUS         0x0F /* Extended Status Reg */
 
+/* PHY GPY 211 registers */
+#define STANDARD_AN_REG_MASK   0x0007 /* MMD */
+#define ANEG_MULTIGBT_AN_CTRL  0x0020 /* MULTI GBT AN Control Register */
+#define MMD_DEVADDR_SHIFT      16     /* Shift MMD to higher bits */
+#define CR_2500T_FD_CAPS       0x0080 /* Advertise 2500T FD capability */
 #define PHY_CONTROL_LB         0x4000 /* PHY Loopback bit */
 
 /* NVM Control */
diff --git a/drivers/net/e1000/base/e1000_hw.h 
b/drivers/net/e1000/base/e1000_hw.h
index b6822991f..76b4dd5c1 100644
--- a/drivers/net/e1000/base/e1000_hw.h
+++ b/drivers/net/e1000/base/e1000_hw.h
@@ -273,6 +273,7 @@ enum e1000_phy_type {
        e1000_phy_82580,
        e1000_phy_vf,
        e1000_phy_i210,
+       e1000_phy_i225,
 };
 
 enum e1000_bus_type {
diff --git a/drivers/net/e1000/base/e1000_phy.c 
b/drivers/net/e1000/base/e1000_phy.c
index 956c06747..23805ba7d 100644
--- a/drivers/net/e1000/base/e1000_phy.c
+++ b/drivers/net/e1000/base/e1000_phy.c
@@ -1841,6 +1841,9 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
                        case M88E1543_E_PHY_ID:
                        case M88E1512_E_PHY_ID:
                        case I210_I_PHY_ID:
+                       /* fall-through */
+                       case I225_I_PHY_ID:
+                       /* fall-through */
                                reset_dsp = false;
                                break;
                        default:
@@ -1882,6 +1885,8 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
                return E1000_SUCCESS;
        if (hw->phy.id == I210_I_PHY_ID)
                return E1000_SUCCESS;
+       if (hw->phy.id == I225_I_PHY_ID)
+               return E1000_SUCCESS;
        if ((hw->phy.id == M88E1543_E_PHY_ID) ||
            (hw->phy.id == M88E1512_E_PHY_ID))
                return E1000_SUCCESS;
@@ -2409,7 +2414,7 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
 s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val;
+       s32 ret_val  = 0;
        u16 phy_data, phy_data2, is_cm;
        u16 index, default_page;
 
@@ -2437,6 +2442,11 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
                phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
                phy->cable_length = phy_data / (is_cm ? 100 : 1);
                break;
+       case I225_I_PHY_ID:
+               if (ret_val)
+                       return ret_val;
+               /* TODO - complete with Foxville data */
+               break;
        case M88E1543_E_PHY_ID:
        case M88E1512_E_PHY_ID:
        case M88E1340M_E_PHY_ID:
@@ -3016,6 +3026,9 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
        case I210_I_PHY_ID:
                phy_type = e1000_phy_i210;
                break;
+       case I225_I_PHY_ID:
+               phy_type = e1000_phy_i225;
+               break;
        default:
                phy_type = e1000_phy_unknown;
                break;
@@ -4073,6 +4086,73 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 
offset, u16 *data)
        return ret_val;
 }
 
+/**
+ *  e1000_write_phy_reg_gpy - Write GPY PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore, if necessary, then writes the data to PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       s32 ret_val;
+       u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
+
+       DEBUGFUNC("e1000_write_phy_reg_gpy");
+
+       offset = offset & GPY_REG_MASK;
+
+       if (!dev_addr) {
+               ret_val = hw->phy.ops.acquire(hw);
+               if (ret_val)
+                       return ret_val;
+               ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
+               if (ret_val)
+                       return ret_val;
+               hw->phy.ops.release(hw);
+       } else {
+               ret_val = e1000_write_xmdio_reg(hw, (u16)offset, dev_addr,
+                                               data);
+       }
+       return ret_val;
+}
+
+/**
+ *  e1000_read_phy_reg_gpy - Read GPY PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: lower half is register offset to read to
+ *     upper half is MMD to use.
+ *  @data: data to read at register offset
+ *
+ *  Acquires semaphore, if necessary, then reads the data in the PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000_read_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       s32 ret_val;
+       u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
+
+       DEBUGFUNC("e1000_read_phy_reg_gpy");
+
+       offset = offset & GPY_REG_MASK;
+
+       if (!dev_addr) {
+               ret_val = hw->phy.ops.acquire(hw);
+               if (ret_val)
+                       return ret_val;
+               ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
+               if (ret_val)
+                       return ret_val;
+               hw->phy.ops.release(hw);
+       } else {
+               ret_val = e1000_read_xmdio_reg(hw, (u16)offset, dev_addr,
+                                              data);
+       }
+       return ret_val;
+}
+
 /**
  *  e1000_read_phy_reg_mphy - Read mPHY control register
  *  @hw: pointer to the HW structure
diff --git a/drivers/net/e1000/base/e1000_phy.h 
b/drivers/net/e1000/base/e1000_phy.h
index 2c71e64c8..05a1d27ff 100644
--- a/drivers/net/e1000/base/e1000_phy.h
+++ b/drivers/net/e1000/base/e1000_phy.h
@@ -86,6 +86,8 @@ s32  e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
 s32  e1000_get_cable_length_82577(struct e1000_hw *hw);
 s32  e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
 s32  e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
+s32  e1000_write_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 data);
+s32  e1000_read_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 *data);
 s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
 s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
                             bool line_override);
@@ -115,6 +117,10 @@ bool e1000_is_mphy_ready(struct e1000_hw *hw);
 #define GS40G_MAC_SPEED_1G             0X0006
 #define GS40G_COPPER_SPEC              0x0010
 
+/* GPY211 - I225 defines */
+#define GPY_MMD_MASK                   0xFFFF0000
+#define GPY_MMD_SHIFT                  16
+#define GPY_REG_MASK                   0x0000FFFF
 /* BM/HV Specific Registers */
 #define BM_PORT_CTRL_PAGE              769
 #define BM_WUC_PAGE                    800
-- 
2.17.1

Reply via email to