|
@@ -1281,6 +1281,53 @@ static s32 ixgbe_setup_ixfi_x550em_x(struct ixgbe_hw *hw)
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
|
|
|
+ * internal PHY
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ **/
|
|
|
+static s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
|
|
|
+{
|
|
|
+ s32 status;
|
|
|
+ u32 link_ctrl;
|
|
|
+
|
|
|
+ /* Restart auto-negotiation. */
|
|
|
+ status = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
|
|
|
+
|
|
|
+ if (status) {
|
|
|
+ hw_dbg(hw, "Auto-negotiation did not complete\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
|
|
|
+ status = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
|
|
|
+
|
|
|
+ if (hw->mac.type == ixgbe_mac_x550em_a) {
|
|
|
+ u32 flx_mask_st20;
|
|
|
+
|
|
|
+ /* Indicate to FW that AN restart has been asserted */
|
|
|
+ status = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
|
|
|
+
|
|
|
+ if (status) {
|
|
|
+ hw_dbg(hw, "Auto-negotiation did not complete\n");
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
|
|
|
+ status = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
/** ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
|
|
|
* @hw: pointer to hardware structure
|
|
|
* @speed: the link speed to force
|
|
@@ -1330,16 +1377,7 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
|
|
|
}
|
|
|
|
|
|
/* Toggle port SW reset by AN reset. */
|
|
|
- status = ixgbe_read_iosf_sb_reg_x550(hw,
|
|
|
- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
|
|
|
- if (status)
|
|
|
- return status;
|
|
|
-
|
|
|
- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
|
|
|
- status = ixgbe_write_iosf_sb_reg_x550(hw,
|
|
|
- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
|
|
|
+ status = ixgbe_restart_an_internal_phy_x550em(hw);
|
|
|
|
|
|
return status;
|
|
|
}
|
|
@@ -1422,6 +1460,55 @@ ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @speed: the link speed to force
|
|
|
+ *
|
|
|
+ * Configures the integrated PHY for native SFI mode. Used to connect the
|
|
|
+ * internal PHY directly to an SFP cage, without autonegotiation.
|
|
|
+ **/
|
|
|
+static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
|
|
|
+{
|
|
|
+ struct ixgbe_mac_info *mac = &hw->mac;
|
|
|
+ s32 status;
|
|
|
+ u32 reg_val;
|
|
|
+
|
|
|
+ /* Disable all AN and force speed to 10G Serial. */
|
|
|
+ status = mac->ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
|
|
|
+ if (status)
|
|
|
+ return status;
|
|
|
+
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
|
|
|
+
|
|
|
+ /* Select forced link speed for internal PHY. */
|
|
|
+ switch (*speed) {
|
|
|
+ case IXGBE_LINK_SPEED_10GB_FULL:
|
|
|
+ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
|
|
|
+ break;
|
|
|
+ case IXGBE_LINK_SPEED_1GB_FULL:
|
|
|
+ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ /* Other link speeds are not supported by internal PHY. */
|
|
|
+ return IXGBE_ERR_LINK_SETUP;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = mac->ops.write_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
|
|
|
+
|
|
|
+ /* Toggle port SW reset by AN reset. */
|
|
|
+ status = ixgbe_restart_an_internal_phy_x550em(hw);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ixgbe_setup_mac_link_sfp_n - Setup internal PHY for native SFP
|
|
|
* @hw: pointer to hardware structure
|
|
@@ -1434,45 +1521,39 @@ ixgbe_setup_mac_link_sfp_n(struct ixgbe_hw *hw, ixgbe_link_speed speed,
|
|
|
{
|
|
|
bool setup_linear = false;
|
|
|
u32 reg_phy_int;
|
|
|
- s32 rc;
|
|
|
+ s32 ret_val;
|
|
|
|
|
|
/* Check if SFP module is supported and linear */
|
|
|
- rc = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
|
|
|
+ ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
|
|
|
|
|
|
/* If no SFP module present, then return success. Return success since
|
|
|
* SFP not present error is not excepted in the setup MAC link flow.
|
|
|
*/
|
|
|
- if (rc == IXGBE_ERR_SFP_NOT_PRESENT)
|
|
|
+ if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
|
|
|
return 0;
|
|
|
|
|
|
- if (!rc)
|
|
|
- return rc;
|
|
|
+ if (!ret_val)
|
|
|
+ return ret_val;
|
|
|
|
|
|
- /* Configure internal PHY for native SFI */
|
|
|
- rc = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
- IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY,
|
|
|
- ®_phy_int);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ /* Configure internal PHY for native SFI based on module type */
|
|
|
+ ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int);
|
|
|
+ if (!ret_val)
|
|
|
+ return ret_val;
|
|
|
|
|
|
- if (setup_linear) {
|
|
|
- reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LIMITING;
|
|
|
- reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LINEAR;
|
|
|
- } else {
|
|
|
- reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LIMITING;
|
|
|
- reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LINEAR;
|
|
|
- }
|
|
|
+ reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
|
|
|
+ if (!setup_linear)
|
|
|
+ reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
|
|
|
|
|
|
- rc = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
- IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY,
|
|
|
- reg_phy_int);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
|
|
|
+ if (!ret_val)
|
|
|
+ return ret_val;
|
|
|
|
|
|
- /* Setup XFI/SFI internal link */
|
|
|
- return ixgbe_setup_ixfi_x550em(hw, &speed);
|
|
|
+ /* Setup SFI internal link. */
|
|
|
+ return ixgbe_setup_sfi_x550a(hw, &speed);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1488,19 +1569,19 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed,
|
|
|
u32 reg_slice, slice_offset;
|
|
|
bool setup_linear = false;
|
|
|
u16 reg_phy_ext;
|
|
|
- s32 rc;
|
|
|
+ s32 ret_val;
|
|
|
|
|
|
/* Check if SFP module is supported and linear */
|
|
|
- rc = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
|
|
|
+ ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
|
|
|
|
|
|
/* If no SFP module present, then return success. Return success since
|
|
|
* SFP not present error is not excepted in the setup MAC link flow.
|
|
|
*/
|
|
|
- if (rc == IXGBE_ERR_SFP_NOT_PRESENT)
|
|
|
+ if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
|
|
|
return 0;
|
|
|
|
|
|
- if (!rc)
|
|
|
- return rc;
|
|
|
+ if (!ret_val)
|
|
|
+ return ret_val;
|
|
|
|
|
|
/* Configure internal PHY for KR/KX. */
|
|
|
ixgbe_setup_kr_speed_x550em(hw, speed);
|
|
@@ -1509,10 +1590,10 @@ ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw, ixgbe_link_speed speed,
|
|
|
return IXGBE_ERR_PHY_ADDR_INVALID;
|
|
|
|
|
|
/* Get external PHY device id */
|
|
|
- rc = hw->phy.ops.read_reg(hw, IXGBE_CS4227_GLOBAL_ID_MSB,
|
|
|
+ ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_GLOBAL_ID_MSB,
|
|
|
IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ if (ret_val)
|
|
|
+ return ret_val;
|
|
|
|
|
|
/* When configuring quad port CS4223, the MAC instance is part
|
|
|
* of the slice offset.
|
|
@@ -1625,7 +1706,7 @@ ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed,
|
|
|
__always_unused bool autoneg_wait_to_complete)
|
|
|
{
|
|
|
struct ixgbe_mac_info *mac = &hw->mac;
|
|
|
- u32 lval, sval;
|
|
|
+ u32 lval, sval, flx_val;
|
|
|
s32 rc;
|
|
|
|
|
|
rc = mac->ops.read_iosf_sb_reg(hw,
|
|
@@ -1659,11 +1740,31 @@ ixgbe_setup_sgmii(struct ixgbe_hw *hw, __always_unused ixgbe_link_speed speed,
|
|
|
if (rc)
|
|
|
return rc;
|
|
|
|
|
|
- lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
|
|
|
+ rc = mac->ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ rc = mac->ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
|
|
|
+ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
|
|
|
+ flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
|
|
|
+ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
|
|
|
+ flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
|
|
|
+
|
|
|
rc = mac->ops.write_iosf_sb_reg(hw,
|
|
|
- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
+ rc = ixgbe_restart_an_internal_phy_x550em(hw);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -2020,13 +2121,31 @@ static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
|
|
|
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
|
|
|
reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
|
|
|
|
|
|
- /* Restart auto-negotiation. */
|
|
|
- reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
|
|
|
status = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
|
|
|
|
|
|
- return status;
|
|
|
+ if (hw->mac.type == ixgbe_mac_x550em_a) {
|
|
|
+ /* Set lane mode to KR auto negotiation */
|
|
|
+ status = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
|
|
|
+
|
|
|
+ if (status)
|
|
|
+ return status;
|
|
|
+
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
|
|
|
+ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
|
|
|
+ reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
|
|
|
+ reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
|
|
|
+
|
|
|
+ status = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
+ IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
|
|
|
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ixgbe_restart_an_internal_phy_x550em(hw);
|
|
|
}
|
|
|
|
|
|
/** ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
|
|
@@ -2894,7 +3013,6 @@ static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
|
|
|
static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
s32 status = 0;
|
|
|
- u32 link_ctrl = 0;
|
|
|
u32 an_cntl = 0;
|
|
|
|
|
|
/* Validate the requested mode */
|
|
@@ -2965,18 +3083,7 @@ static s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
|
|
|
IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
|
|
|
|
|
|
/* Restart auto-negotiation. */
|
|
|
- status = hw->mac.ops.read_iosf_sb_reg(hw,
|
|
|
- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
|
|
|
- if (status) {
|
|
|
- hw_dbg(hw, "Auto-Negotiation did not complete\n");
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
|
|
|
- status = hw->mac.ops.write_iosf_sb_reg(hw,
|
|
|
- IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
|
|
|
- IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
|
|
|
+ status = ixgbe_restart_an_internal_phy_x550em(hw);
|
|
|
|
|
|
return status;
|
|
|
}
|
|
@@ -3243,7 +3350,7 @@ static struct ixgbe_mac_operations mac_ops_x550em_a = {
|
|
|
.acquire_swfw_sync = ixgbe_acquire_swfw_sync_x550em_a,
|
|
|
.release_swfw_sync = ixgbe_release_swfw_sync_x550em_a,
|
|
|
.setup_fc = ixgbe_setup_fc_x550em,
|
|
|
- .fc_autoneg = NULL, /* defined later */
|
|
|
+ .fc_autoneg = ixgbe_fc_autoneg,
|
|
|
.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a,
|
|
|
.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a,
|
|
|
};
|