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