*
* Returns an error code on error.
*/
-STATIC s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
- u16 reg, u16 *val, bool lock)
+s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 *val, bool lock)
{
u32 swfw_mask = hw->phy.phy_semaphore_mask;
int max_retry = 10;
u8 reg_high;
u8 csum;
+ if (hw->mac.type >= ixgbe_mac_X550)
+ max_retry = 3;
reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */
csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
csum = ~csum;
return IXGBE_ERR_I2C;
}
-/**
- * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
- * @hw: pointer to the hardware structure
- * @addr: I2C bus address to read from
- * @reg: I2C device register to read from
- * @val: pointer to location to receive read value
- *
- * Returns an error code on error.
- **/
-STATIC s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
- u16 reg, u16 *val)
-{
- return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true);
-}
-
-/**
- * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
- * @hw: pointer to the hardware structure
- * @addr: I2C bus address to read from
- * @reg: I2C device register to read from
- * @val: pointer to location to receive read value
- *
- * Returns an error code on error.
- **/
-STATIC s32
-ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
- u16 reg, u16 *val)
-{
- return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false);
-}
-
/**
* ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
* @hw: pointer to the hardware structure
*
* Returns an error code on error.
*/
-STATIC s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
- u16 reg, u16 val, bool lock)
+s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 val, bool lock)
{
u32 swfw_mask = hw->phy.phy_semaphore_mask;
int max_retry = 1;
return IXGBE_ERR_I2C;
}
-/**
- * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
- * @hw: pointer to the hardware structure
- * @addr: I2C bus address to write to
- * @reg: I2C device register to write to
- * @val: value to write
- *
- * Returns an error code on error.
- **/
-STATIC s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
- u8 addr, u16 reg, u16 val)
-{
- return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true);
-}
-
-/**
- * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
- * @hw: pointer to the hardware structure
- * @addr: I2C bus address to write to
- * @reg: I2C device register to write to
- * @val: value to write
- *
- * Returns an error code on error.
- **/
-STATIC s32
-ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
- u8 addr, u16 reg, u16 val)
-{
- return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false);
-}
-
/**
* ixgbe_init_phy_ops_generic - Inits PHY function ptrs
* @hw: pointer to the hardware structure
phy->ops.i2c_bus_clear = ixgbe_i2c_bus_clear;
phy->ops.identify_sfp = ixgbe_identify_module_generic;
phy->sfp_type = ixgbe_sfp_type_unknown;
- phy->ops.read_i2c_combined = ixgbe_read_i2c_combined_generic;
- phy->ops.write_i2c_combined = ixgbe_write_i2c_combined_generic;
- phy->ops.read_i2c_combined_unlocked =
- ixgbe_read_i2c_combined_generic_unlocked;
- phy->ops.write_i2c_combined_unlocked =
- ixgbe_write_i2c_combined_generic_unlocked;
phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked;
phy->ops.write_i2c_byte_unlocked =
ixgbe_write_i2c_byte_generic_unlocked;
/**
* ixgbe_get_phy_type_from_id - Get the phy type
- * @hw: pointer to hardware structure
+ * @phy_id: PHY ID information
*
**/
enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
case TN1010_PHY_ID:
phy_type = ixgbe_phy_tn;
break;
- case X550_PHY_ID:
+ case X550_PHY_ID1:
+ case X550_PHY_ID2:
+ case X550_PHY_ID3:
case X540_PHY_ID:
phy_type = ixgbe_phy_aq;
break;
phy_type = ixgbe_phy_unknown;
break;
}
-
- DEBUGOUT1("phy type found is %d\n", phy_type);
return phy_type;
}
if (hw->mac.type == ixgbe_mac_X550) {
if (speed & IXGBE_LINK_SPEED_5GB_FULL) {
- /* Set or unset auto-negotiation 1G advertisement */
+ /* Set or unset auto-negotiation 5G advertisement */
hw->phy.ops.read_reg(hw,
IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
}
if (speed & IXGBE_LINK_SPEED_2_5GB_FULL) {
- /* Set or unset auto-negotiation 1G advertisement */
+ /* Set or unset auto-negotiation 2.5G advertisement */
hw->phy.ops.read_reg(hw,
IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
/* Setup link based on the new speed settings */
- hw->phy.ops.setup_link(hw);
+ ixgbe_setup_phy_link(hw);
return IXGBE_SUCCESS;
}
/**
- * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @autoneg: boolean auto-negotiation value
+ * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy
+ * @hw: pointer to hardware structure
*
- * Determines the supported link capabilities by reading the PHY auto
- * negotiation 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,
- bool *autoneg)
+static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw)
{
s32 status;
u16 speed_ability;
- DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic");
-
- *speed = 0;
- *autoneg = true;
-
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
IXGBE_MDIO_PMA_PMD_DEV_TYPE,
&speed_ability);
+ if (status)
+ return status;
- if (status == IXGBE_SUCCESS) {
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
- *speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
- *speed |= IXGBE_LINK_SPEED_1GB_FULL;
- if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
- *speed |= IXGBE_LINK_SPEED_100_FULL;
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M)
+ hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X550:
+ hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;
+ hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;
+ break;
+ case ixgbe_mac_X550EM_x:
+ hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL;
+ break;
+ default:
+ break;
}
- /* Internal PHY does not support 100 Mbps */
- if (hw->mac.type == ixgbe_mac_X550EM_x)
- *speed &= ~IXGBE_LINK_SPEED_100_FULL;
+ return status;
+}
- if (hw->mac.type == ixgbe_mac_X550) {
- *speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
- *speed |= IXGBE_LINK_SPEED_5GB_FULL;
- }
+/**
+ * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: boolean auto-negotiation value
+ **/
+s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
+{
+ s32 status = IXGBE_SUCCESS;
+ DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic");
+
+ *autoneg = true;
+ if (!hw->phy.speeds_supported)
+ status = ixgbe_get_copper_speeds_supported(hw);
+
+ *speed = hw->phy.speeds_supported;
return status;
}
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);
hw->phy.id = identifier;
- /* LAN ID is needed for sfp_type determination */
- hw->mac.ops.set_lan_id(hw);
-
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
&comp_codes_10g);
DEBUGFUNC("ixgbe_read_i2c_byte_generic");
+ if (hw->mac.type >= ixgbe_mac_X550)
+ max_retry = 3;
if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
max_retry = IXGBE_SFP_DETECT_RETRIES;
u32 status;
u16 reg;
+ if (!on && ixgbe_mng_present(hw))
+ return 0;
+
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
®);