ixgbe/base: support 5G link speed
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe / ixgbe_phy.c
index f799876..38c9909 100644 (file)
@@ -744,6 +744,44 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
                                      autoneg_reg);
        }
 
+       if (hw->mac.type == ixgbe_mac_X550) {
+               if (speed & IXGBE_LINK_SPEED_5GB_FULL) {
+                       /* Set or unset auto-negotiation 1G advertisement */
+                       hw->phy.ops.read_reg(hw,
+                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                               &autoneg_reg);
+
+                       autoneg_reg &= ~IXGBE_MII_5GBASE_T_ADVERTISE;
+                       if (hw->phy.autoneg_advertised &
+                            IXGBE_LINK_SPEED_5GB_FULL)
+                               autoneg_reg |= IXGBE_MII_5GBASE_T_ADVERTISE;
+
+                       hw->phy.ops.write_reg(hw,
+                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                               autoneg_reg);
+               }
+
+               if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) {
+                       /* Set or unset auto-negotiation 1G advertisement */
+                       hw->phy.ops.read_reg(hw,
+                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                               &autoneg_reg);
+
+                       autoneg_reg &= ~IXGBE_MII_2_5GBASE_T_ADVERTISE;
+                       if (hw->phy.autoneg_advertised &
+                           IXGBE_LINK_SPEED_2_5GB_FULL)
+                               autoneg_reg |= IXGBE_MII_2_5GBASE_T_ADVERTISE;
+
+                       hw->phy.ops.write_reg(hw,
+                               IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+                               IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                               autoneg_reg);
+               }
+       }
+
        if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
                /* Set or unset auto-negotiation 1G advertisement */
                hw->phy.ops.read_reg(hw,
@@ -815,6 +853,12 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
                hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
 
+       if (speed & IXGBE_LINK_SPEED_5GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_5GB_FULL;
+
+       if (speed & IXGBE_LINK_SPEED_2_5GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_2_5GB_FULL;
+
        if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
 
@@ -833,7 +877,8 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
  *  @speed: pointer to link speed
  *  @autoneg: boolean auto-negotiation value
  *
- *  Determines the link capabilities by reading the AUTOC register.
+ *  Determines the supported link capabilities by reading the PHY auto
+ *  negotiation register.
  **/
 s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
                                               ixgbe_link_speed *speed,
@@ -860,6 +905,15 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
                        *speed |= IXGBE_LINK_SPEED_100_FULL;
        }
 
+       /* Internal PHY does not support 100 Mbps */
+       if (hw->mac.type == ixgbe_mac_X550EM_x)
+               *speed &= ~IXGBE_LINK_SPEED_100_FULL;
+
+       if (hw->mac.type == ixgbe_mac_X550) {
+               *speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
+               *speed |= IXGBE_LINK_SPEED_5GB_FULL;
+       }
+
        return status;
 }
 
@@ -1201,6 +1255,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                goto out;
        }
 
+       /* LAN ID is needed for I2C access */
+       hw->mac.ops.set_lan_id(hw);
+
        status = hw->phy.ops.read_i2c_eeprom(hw,
                                             IXGBE_SFF_IDENTIFIER,
                                             &identifier);
@@ -1208,9 +1265,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
        if (status != IXGBE_SUCCESS)
                goto err_read_i2c_eeprom;
 
-       /* LAN ID is needed for sfp_type determination */
-       hw->mac.ops.set_lan_id(hw);
-
        if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
                hw->phy.type = ixgbe_phy_sfp_unsupported;
                status = IXGBE_ERR_SFP_NOT_SUPPORTED;