@@ -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 */
@@ -273,6 +273,7 @@ enum e1000_phy_type {
e1000_phy_82580,
e1000_phy_vf,
e1000_phy_i210,
+ e1000_phy_i225,
};
enum e1000_bus_type {
@@ -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
@@ -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