e1000/base: m88e1512 phy in 82575
authorJijiang Liu <jijiang.liu@intel.com>
Wed, 18 Jun 2014 10:31:31 +0000 (12:31 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 18 Jun 2014 21:30:23 +0000 (23:30 +0200)
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
[Thomas: split code drop]

lib/librte_pmd_e1000/e1000/e1000_82575.c
lib/librte_pmd_e1000/e1000/e1000_82575.h
lib/librte_pmd_e1000/e1000/e1000_defines.h

index 28b29ba..2c447d8 100644 (file)
@@ -272,6 +272,11 @@ STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
                                hw->mac.ops.check_for_link =
                                                e1000_check_for_link_media_swap;
                }
+               if (phy->id == M88E1512_E_PHY_ID) {
+                       ret_val = e1000_initialize_M88E1512_phy(hw);
+                       if (ret_val)
+                               goto out;
+               }
                break;
        case IGP03E1000_E_PHY_ID:
        case IGP04E1000_E_PHY_ID:
@@ -752,6 +757,7 @@ out:
 STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
 {
        s32 ret_val = E1000_SUCCESS;
+       struct e1000_phy_info *phy = &hw->phy;
 
        DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
 
@@ -774,7 +780,11 @@ STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
                goto out;
 
        ret_val = hw->phy.ops.commit(hw);
+       if (ret_val)
+               goto out;
 
+       if (phy->id == M88E1512_E_PHY_ID)
+               ret_val = e1000_initialize_M88E1512_phy(hw);
 out:
        return ret_val;
 }
@@ -2788,6 +2798,95 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
        return __e1000_access_emi_reg(hw, addr, data, true);
 }
 
+/**
+ *  e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Initialize Marverl 1512 to work correctly with Avoton.
+ **/
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val = E1000_SUCCESS;
+
+       DEBUGFUNC("e1000_initialize_M88E1512_phy");
+
+       /* Check if this is correct PHY. */
+       if (phy->id != M88E1512_E_PHY_ID)
+               goto out;
+
+       /* Switch to PHY page 0xFF. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+       if (ret_val)
+               goto out;
+
+       /* Switch to PHY page 0xFB. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
+       if (ret_val)
+               goto out;
+
+       /* Switch to PHY page 0x12. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+       if (ret_val)
+               goto out;
+
+       /* Change mode to SGMII-to-Copper */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+       if (ret_val)
+               goto out;
+
+       /* Return the PHY to page 0. */
+       ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.commit(hw);
+       if (ret_val) {
+               DEBUGOUT("Error committing the PHY changes\n");
+               return ret_val;
+       }
+
+       msec_delay(1000);
+out:
+       return ret_val;
+}
+
 /**
  *  e1000_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
index 290fa2a..cbe145d 100644 (file)
@@ -497,6 +497,7 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
 s32 e1000_set_eee_i350(struct e1000_hw *);
 s32 e1000_set_eee_i354(struct e1000_hw *);
 s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
 
 /* I2C SDA and SCL timing parameters for standard mode */
 #define E1000_I2C_T_HD_STA     4
index 544105c..3023a60 100644 (file)
@@ -853,6 +853,10 @@ POSSIBILITY OF SUCH DAMAGE.
 #define E1000_PCS_STATUS_ADDR_I354     1
 #define E1000_PCS_STATUS_RX_LPI_RCVD   0x0400
 #define E1000_PCS_STATUS_TX_LPI_RCVD   0x0800
+#define E1000_M88E1512_CFG_REG_1       0x0010
+#define E1000_M88E1512_CFG_REG_2       0x0011
+#define E1000_M88E1512_CFG_REG_3       0x0007
+#define E1000_M88E1512_MODE            0x0014
 #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 */