From 8ef32003772a14c61c70b540e41c259c482c2fb6 Mon Sep 17 00:00:00 2001 From: Jijiang Liu Date: Wed, 18 Jun 2014 15:46:07 +0200 Subject: [PATCH] ixgbe/base: rework link negotiation Signed-off-by: Jijiang Liu Acked-by: Helin Zhang Tested-by: Waterman Cao [Thomas: split code drop] --- lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c | 10 +-- lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c | 86 +++++++++++++---------- lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h | 6 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c | 8 +-- lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h | 3 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c | 32 ++++++--- lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h | 1 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c | 55 +++++++++++++-- lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h | 5 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h | 14 +++- lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c | 56 +++++++++++---- lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h | 2 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c | 6 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h | 2 +- lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c | 7 +- lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 2 +- 16 files changed, 194 insertions(+), 101 deletions(-) diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c index b285c4c6dd..311dd51b1e 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c @@ -56,11 +56,9 @@ STATIC s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, bool link_up_wait_to_complete); STATIC s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); STATIC s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); STATIC s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); STATIC s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); @@ -722,15 +720,15 @@ out: * ixgbe_setup_mac_link_82598 - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ STATIC s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { + bool autoneg = false; s32 status = IXGBE_SUCCESS; ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); @@ -776,14 +774,12 @@ STATIC s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, * ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true if waiting is needed to complete * * Sets the link speed in the AUTOC register in the MAC and restarts link. **/ STATIC s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete) { s32 status; @@ -791,7 +787,7 @@ STATIC s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, DEBUGFUNC("ixgbe_setup_copper_link_82598"); /* Setup the PHY according to input speed */ - status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, + status = hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); /* Set up MAC */ ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c index f987f348db..2b95db539a 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c @@ -47,7 +47,6 @@ POSSIBILITY OF SUCH DAMAGE. STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); STATIC s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, @@ -331,13 +330,13 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) * ixgbe_get_link_capabilities_82599 - Determines link capabilities * @hw: pointer to hardware structure * @speed: pointer to link speed - * @negotiation: true when autoneg or autotry is enabled + * @autoneg: true when autoneg or autotry is enabled * * Determines the link capabilities by reading the AUTOC register. **/ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, - bool *negotiation) + bool *autoneg) { s32 status = IXGBE_SUCCESS; u32 autoc = 0; @@ -348,10 +347,14 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, /* Check if 1G SFP module. */ if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || +#ifdef SUPPORT_1000BASE_LX + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || +#endif hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { *speed = IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = true; + *autoneg = true; goto out; } @@ -368,22 +371,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, switch (autoc & IXGBE_AUTOC_LMS_MASK) { case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: *speed = IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = false; + *autoneg = false; break; case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: *speed = IXGBE_LINK_SPEED_10GB_FULL; - *negotiation = false; + *autoneg = false; break; case IXGBE_AUTOC_LMS_1G_AN: *speed = IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = true; + *autoneg = true; break; case IXGBE_AUTOC_LMS_10G_SERIAL: *speed = IXGBE_LINK_SPEED_10GB_FULL; - *negotiation = false; + *autoneg = false; break; case IXGBE_AUTOC_LMS_KX4_KX_KR: @@ -395,7 +398,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = true; + *autoneg = true; break; case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII: @@ -406,12 +409,12 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = true; + *autoneg = true; break; case IXGBE_AUTOC_LMS_SGMII_1G_100M: *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL; - *negotiation = false; + *autoneg = false; break; default: @@ -423,7 +426,8 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, if (hw->phy.multispeed_fiber) { *speed |= IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL; - *negotiation = true; + + *autoneg = true; } out: @@ -643,17 +647,17 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) } } + /** * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { s32 status = IXGBE_SUCCESS; @@ -662,13 +666,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, u32 speedcnt = 0; u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); u32 i = 0; - bool link_up = false; - bool negotiation; + bool autoneg, link_up = false; DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber"); /* Mask off requested but non-supported speeds */ - status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation); + status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg); if (status != IXGBE_SUCCESS) return status; @@ -691,16 +694,22 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, goto out; /* Set the module link speed */ - esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - IXGBE_WRITE_FLUSH(hw); + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + break; + default: + DEBUGOUT("Unexpected media type.\n"); + break; + } /* Allow module to change analog characteristics (1G->10G) */ msec_delay(40); status = ixgbe_setup_mac_link_82599(hw, IXGBE_LINK_SPEED_10GB_FULL, - autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) return status; @@ -742,17 +751,23 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, goto out; /* Set the module link speed */ - esdp_reg &= ~IXGBE_ESDP_SDP5; - esdp_reg |= IXGBE_ESDP_SDP5_DIR; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - IXGBE_WRITE_FLUSH(hw); + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + esdp_reg &= ~IXGBE_ESDP_SDP5; + esdp_reg |= IXGBE_ESDP_SDP5_DIR; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + break; + default: + DEBUGOUT("Unexpected media type.\n"); + break; + } /* Allow module to change analog characteristics (10G->1G) */ msec_delay(40); status = ixgbe_setup_mac_link_82599(hw, IXGBE_LINK_SPEED_1GB_FULL, - autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) return status; @@ -779,7 +794,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, */ if (speedcnt > 1) status = ixgbe_setup_mac_link_multispeed_fiber(hw, - highest_link_speed, autoneg, autoneg_wait_to_complete); + highest_link_speed, autoneg_wait_to_complete); out: /* Set autoneg_advertised value based on input link speed */ @@ -798,13 +813,12 @@ out: * ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed * * Implements the Intel SmartSpeed algorithm. **/ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { s32 status = IXGBE_SUCCESS; @@ -837,7 +851,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, /* First, try to get link with full advertisement */ hw->phy.smart_speed_active = false; for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) { - status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) goto out; @@ -872,7 +886,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, /* Turn SmartSpeed on to disable KR support */ hw->phy.smart_speed_active = true; - status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) goto out; @@ -897,7 +911,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, /* We didn't get link. Turn SmartSpeed back off. */ hw->phy.smart_speed_active = false; - status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, + status = ixgbe_setup_mac_link_82599(hw, speed, autoneg_wait_to_complete); out: @@ -911,15 +925,15 @@ out: * ixgbe_setup_mac_link_82599 - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { + bool autoneg = false; s32 status = IXGBE_SUCCESS; u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); @@ -1048,14 +1062,12 @@ out: * ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true if waiting is needed to complete * * Restarts link on PHY and MAC based on settings passed in. **/ STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete) { s32 status; @@ -1063,7 +1075,7 @@ STATIC s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, DEBUGFUNC("ixgbe_setup_copper_link_82599"); /* Setup the PHY according to input speed */ - status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, + status = hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); /* Set up MAC */ ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h index fc5fe0b262..d30eb6d184 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h @@ -42,15 +42,15 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete); s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete); s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete); s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); + bool autoneg_wait_to_complete); s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw); void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw); s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c index d872f5230e..92775cafe6 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c @@ -528,16 +528,14 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, * ixgbe_setup_phy_link_speed - Set auto advertise * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * * Sets the auto advertised capabilities **/ s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete) { return ixgbe_call_func(hw, hw->phy.ops.setup_link_speed, (hw, speed, - autoneg, autoneg_wait_to_complete), + autoneg_wait_to_complete), IXGBE_NOT_IMPLEMENTED); } @@ -597,17 +595,15 @@ void ixgbe_flap_tx_laser(struct ixgbe_hw *hw) * ixgbe_setup_link - Set link speed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * * Configures link settings. Restarts the link. * Performs autonegotiation if needed. **/ s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete) { return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed, - autoneg, autoneg_wait_to_complete), + autoneg_wait_to_complete), IXGBE_NOT_IMPLEMENTED); } diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h index 10429132d5..4e20213956 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h @@ -74,13 +74,12 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, bool *link_up); s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); void ixgbe_disable_tx_laser(struct ixgbe_hw *hw); void ixgbe_enable_tx_laser(struct ixgbe_hw *hw); void ixgbe_flap_tx_laser(struct ixgbe_hw *hw); s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); + bool autoneg_wait_to_complete); s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete); s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c index 64df997c7c..57859b15f4 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c @@ -925,23 +925,18 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) } /** - * ixgbe_get_bus_info_generic - Generic set PCI bus info + * ixgbe_set_pci_config_data_generic - Generic store PCI bus info * @hw: pointer to hardware structure + * @link_status: the link status returned by the PCI config space * - * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure + * Stores the PCI bus info (speed, width, type) within the ixgbe_hw structure **/ -s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) +void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status) { struct ixgbe_mac_info *mac = &hw->mac; - u16 link_status; - - DEBUGFUNC("ixgbe_get_bus_info_generic"); hw->bus.type = ixgbe_bus_type_pci_express; - /* Get the negotiated link width and speed from PCI config space */ - link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); - switch (link_status & IXGBE_PCI_LINK_WIDTH) { case IXGBE_PCI_LINK_WIDTH_1: hw->bus.width = ixgbe_bus_width_pcie_x1; @@ -976,6 +971,25 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) } mac->ops.set_lan_id(hw); +} + +/** + * ixgbe_get_bus_info_generic - Generic set PCI bus info + * @hw: pointer to hardware structure + * + * Gets the PCI bus info (speed, width, type) then calls helper function to + * store this data within the ixgbe_hw structure. + **/ +s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw) +{ + u16 link_status; + + DEBUGFUNC("ixgbe_get_bus_info_generic"); + + /* Get the negotiated link width and speed from PCI config space */ + link_status = IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_LINK_STATUS); + + ixgbe_set_pci_config_data_generic(hw, link_status); return IXGBE_SUCCESS; } diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h index 09e687566f..a30bd684ea 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h @@ -69,6 +69,7 @@ s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf, u32 eeprom_buf_size, u16 *pba_block_size); s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr); s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw); +void ixgbe_set_pci_config_data_generic(struct ixgbe_hw *hw, u16 link_status); void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw); s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c index 4d032d2fde..98a7b45389 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c @@ -570,11 +570,9 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled **/ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete) { UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); @@ -1077,6 +1075,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) else hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; +#ifdef SUPPORT_10GBASE_ER + } else if (comp_codes_10g & + IXGBE_SFF_10GBASEER_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_er_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_er_core1; +#endif /* SUPPORT_10GBASE_ER */ } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = @@ -1091,6 +1099,15 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) else hw->phy.sfp_type = ixgbe_sfp_type_1g_sx_core1; +#ifdef SUPPORT_1000BASE_LX + } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_1g_lx_core1; +#endif /* SUPPORT_1000BASE_LX */ } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; } @@ -1178,7 +1195,11 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) if (comp_codes_10g == 0 && !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || +#ifdef SUPPORT_1000BASE_LX + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || +#endif + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; status = IXGBE_ERR_SFP_NOT_SUPPORTED; @@ -1193,10 +1214,18 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) ixgbe_get_device_caps(hw, &enforce_sfp); if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && - !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0) || - (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1))) { + !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 || +#ifdef SUPPORT_1000BASE_LX + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 || +#endif +#ifdef SUPPORT_10GBASE_ER + hw->phy.sfp_type == ixgbe_sfp_type_er_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_er_core1 || +#endif + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = IXGBE_SUCCESS; @@ -1272,10 +1301,22 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, * SR modules */ if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || +#ifdef SUPPORT_10GBASE_ER + sfp_type == ixgbe_sfp_type_er_core0 || +#endif /* SUPPORT_10GBASE_ER */ +#ifdef SUPPORT_1000BASE_LX + sfp_type == ixgbe_sfp_type_1g_lx_core0 || +#endif /* SUPPORT_1000BASE_LX */ sfp_type == ixgbe_sfp_type_1g_cu_core0 || sfp_type == ixgbe_sfp_type_1g_sx_core0) sfp_type = ixgbe_sfp_type_srlr_core0; else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || +#ifdef SUPPORT_10GBASE_ER + sfp_type == ixgbe_sfp_type_er_core1 || +#endif /* SUPPORT_10GBASE_ER */ +#ifdef SUPPORT_1000BASE_LX + sfp_type == ixgbe_sfp_type_1g_lx_core1 || +#endif /* SUPPORT_1000BASE_LX */ sfp_type == ixgbe_sfp_type_1g_cu_core1 || sfp_type == ixgbe_sfp_type_1g_sx_core1) sfp_type = ixgbe_sfp_type_srlr_core1; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h index a07c66ea94..191e697971 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h @@ -57,6 +57,10 @@ POSSIBILITY OF SUCH DAMAGE. #define IXGBE_SFF_1GBASET_CAPABLE 0x8 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 +#ifdef SUPPORT_10GBASE_ER +#define IXGBE_SFF_10GBASEER_CAPABLE 0x80 +#endif /* SUPPORT_10GBASE_ER */ +#define IXGBE_SFF_ADDRESSING_MODE 0x4 #define IXGBE_I2C_EEPROM_READ_MASK 0x100 #define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 #define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 @@ -109,7 +113,6 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw); s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h index ad7af8f0ba..b449242938 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h @@ -2816,6 +2816,14 @@ enum ixgbe_sfp_type { ixgbe_sfp_type_1g_cu_core1 = 10, ixgbe_sfp_type_1g_sx_core0 = 11, ixgbe_sfp_type_1g_sx_core1 = 12, +#ifdef SUPPORT_1000BASE_LX + ixgbe_sfp_type_1g_lx_core0 = 13, + ixgbe_sfp_type_1g_lx_core1 = 14, +#endif /* SUPPORT_1000BASE_LX */ +#ifdef SUPPORT_10GBASE_ER + ixgbe_sfp_type_er_core0 = 15, + ixgbe_sfp_type_er_core1 = 16, +#endif /* SUPPORT_10GBASE_ER */ ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; @@ -3041,7 +3049,7 @@ struct ixgbe_mac_operations { void (*disable_tx_laser)(struct ixgbe_hw *); void (*enable_tx_laser)(struct ixgbe_hw *); void (*flap_tx_laser)(struct ixgbe_hw *); - s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); + s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); @@ -3095,8 +3103,7 @@ struct ixgbe_phy_operations { s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *); s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16); s32 (*setup_link)(struct ixgbe_hw *); - s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool, - bool); + s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *); s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *); s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *); @@ -3139,6 +3146,7 @@ struct ixgbe_mac_info { u32 max_rx_queues; u32 orig_autoc; u8 san_mac_rar_index; + bool get_link_status; u32 orig_autoc2; u16 max_msix_vectors; bool arc_subsystem_valid; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c index caeb4393a1..98fde8bab2 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.c @@ -477,8 +477,7 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) * * Set the link speed in the AUTOC register and restarts link. **/ -s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, +s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete) { UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete); @@ -497,23 +496,26 @@ s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool autoneg_wait_to_complete) { + struct ixgbe_mbx_info *mbx = &hw->mbx; + struct ixgbe_mac_info *mac = &hw->mac; + s32 ret_val = IXGBE_SUCCESS; u32 links_reg; + u32 in_msg = 0; UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); - if (!(hw->mbx.ops.check_for_rst(hw, 0))) { - *link_up = false; - *speed = 0; - return -1; - } + /* If we were hit with a reset drop the link */ + if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) + mac->get_link_status = true; - links_reg = IXGBE_VFREAD_REG(hw, IXGBE_VFLINKS); + if (!mac->get_link_status) + goto out; - if (links_reg & IXGBE_LINKS_UP) - *link_up = true; - else - *link_up = false; + /* if link status is down no point in checking to see if pf is up */ + links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); + if (!(links_reg & IXGBE_LINKS_UP)) + goto out; - switch (links_reg & IXGBE_LINKS_SPEED_10G_82599) { + switch (links_reg & IXGBE_LINKS_SPEED_82599) { case IXGBE_LINKS_SPEED_10G_82599: *speed = IXGBE_LINK_SPEED_10GB_FULL; break; @@ -525,7 +527,33 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, break; } - return IXGBE_SUCCESS; + /* if the read failed it could just be a mailbox collision, best wait + * until we are called again and don't report an error + */ + if (mbx->ops.read(hw, &in_msg, 1, 0)) + goto out; + + if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { + /* msg is not CTS and is NACK we must have lost CTS status */ + if (in_msg & IXGBE_VT_MSGTYPE_NACK) + ret_val = -1; + goto out; + } + + /* the pf is talking, if we timed out in the past we reinit */ + if (!mbx->timeout) { + ret_val = -1; + goto out; + } + + /* if we passed all the tests above then the link is up and we no + * longer need to check for link + */ + mac->get_link_status = false; + +out: + *link_up = !mac->get_link_status; + return ret_val; } /** diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h index 2261218e6f..a2f3df0c72 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_vf.h @@ -120,7 +120,7 @@ u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw); u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw); s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr); s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool autoneg_wait_to_complete); + bool autoneg_wait_to_complete); s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool autoneg_wait_to_complete); s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c index ea1cef6cc0..b8826d668e 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c @@ -186,16 +186,14 @@ enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) * ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed **/ s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { DEBUGFUNC("ixgbe_setup_mac_link_X540"); - return hw->phy.ops.setup_link_speed(hw, speed, autoneg, - autoneg_wait_to_complete); + return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); } /** diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h index fac9a6d61a..8a10dd4b59 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h @@ -41,7 +41,7 @@ s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg); enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed, - bool autoneg, bool link_up_wait_to_complete); + bool link_up_wait_to_complete); s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw); s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw); u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw); diff --git a/lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c b/lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c index 71177dcc7e..27a5f70b40 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c +++ b/lib/librte_pmd_ixgbe/ixgbe_82599_bypass.c @@ -112,14 +112,13 @@ out: * ixgbe_setup_mac_link_multispeed_fixed_fiber - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed - * @autoneg: true if autonegotiation enabled * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ static s32 ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, + ixgbe_link_speed speed, bool autoneg_wait_to_complete) { s32 status = IXGBE_SUCCESS; @@ -168,7 +167,6 @@ ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw, status = ixgbe_setup_mac_link_82599(hw, IXGBE_LINK_SPEED_10GB_FULL, - autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) return status; @@ -217,7 +215,6 @@ ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw, status = ixgbe_setup_mac_link_82599(hw, IXGBE_LINK_SPEED_1GB_FULL, - autoneg, autoneg_wait_to_complete); if (status != IXGBE_SUCCESS) return status; @@ -244,7 +241,7 @@ ixgbe_setup_mac_link_multispeed_fixed_fiber(struct ixgbe_hw *hw, */ if (speedcnt > 1) status = ixgbe_setup_mac_link_multispeed_fixed_fiber(hw, - highest_link_speed, autoneg, autoneg_wait_to_complete); + highest_link_speed, autoneg_wait_to_complete); out: /* Set autoneg_advertised value based on input link speed */ diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 85c4a77491..618488a6a4 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -1497,7 +1497,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev) goto error; } - err = ixgbe_setup_link(hw, speed, negotiate, link_up); + err = ixgbe_setup_link(hw, speed, link_up); if (err) goto error; -- 2.20.1