> +s32 txgbe_setup_mac_link_aml(struct txgbe_hw *hw, > + u32 speed, > + bool autoneg_wait_to_complete) > +{ > + bool autoneg = false; > + s32 status = 0; > + s32 ret_status = 0; > + u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN; > + bool link_up = false; > + int i; > + u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN; > + u32 value = 0; > + > + UNREFERENCED_PARAMETER(autoneg_wait_to_complete); > + > + if (hw->phy.sfp_type == txgbe_sfp_type_not_present) { > + DEBUGOUT("SFP not detected, skip setup mac link"); > + return 0; > + } > + > + /* Check to see if speed passed in is supported. */ > + status = hw->mac.get_link_capabilities(hw, > + &link_capabilities, &autoneg); > + if (status) > + return status; > + > + speed &= link_capabilities; > + if (speed == TXGBE_LINK_SPEED_UNKNOWN) > + return TXGBE_ERR_LINK_SETUP; > + > + value = rd32(hw, TXGBE_GPIOEXT); > + if (value & (TXGBE_SFP1_MOD_ABS_LS | TXGBE_SFP1_RX_LOS_LS)) > + return status; > + > + for (i = 0; i < 4; i++) { > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + if (link_up) > + break; > + msleep(250); > + } > + > + if (link_speed == speed && link_up && > + !(speed == TXGBE_LINK_SPEED_25GB_FULL)) > + return status;
speed != TXGBE_LINK_SPEED_25GB_FULL > + > + rte_spinlock_lock(&hw->phy_lock); > + ret_status = 0; > + rte_spinlock_unlock(&hw->phy_lock); > + > + if (ret_status == TXGBE_ERR_PHY_INIT_NOT_DONE) > + return status; > + > + for (i = 0; i < 4; i++) { > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + if (link_up) > + return status; > + msleep(250); > + } Double tab. > + > + return status; > +} > + > +/** > + * txgbe_setup_mac_link_multispeed_fiber_aml - Set MAC link speed > + * @hw: pointer to hardware structure > + * @speed: new link speed > + * @autoneg_wait_to_complete: true when waiting for completion is needed > + * > + * Set the link speed in the MAC and/or PHY register and restarts link. > + **/ > +static s32 txgbe_setup_mac_link_multispeed_fiber_aml(struct txgbe_hw *hw, > + u32 speed, > + bool autoneg_wait_to_complete) > +{ > + u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN; > + u32 highest_link_speed = TXGBE_LINK_SPEED_UNKNOWN; > + s32 status = 0; > + u32 speedcnt = 0; > + bool autoneg, link_up = false; > + > + /* Mask off requested but non-supported speeds */ > + status = hw->mac.get_link_capabilities(hw, &link_speed, &autoneg); > + if (status != 0) > + return status; > + > + speed &= link_speed; > + > + /* Try each speed one by one, highest priority first. We do this in > + * software because 10Gb fiber doesn't support speed autonegotiation. > + */ Neither 25Gb fiber. > + if (speed & TXGBE_LINK_SPEED_25GB_FULL) { > + speedcnt++; > + highest_link_speed = TXGBE_LINK_SPEED_25GB_FULL; > + > + /* If we already have link at this speed, just jump out */ > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + > + if ((link_speed == TXGBE_LINK_SPEED_25GB_FULL) && link_up) > + goto out; > + > + /* Allow module to change analog characteristics (1G->10G) */ 10G -> 25G > + msec_delay(40); > + > + status = hw->mac.setup_mac_link(hw, > + TXGBE_LINK_SPEED_25GB_FULL, > + autoneg_wait_to_complete); > + if (status != 0) > + return status; > + > + /*aml wait link in setup,no need to repeatly wait*/ > + /* If we have link, just jump out */ > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + > + if (link_up) > + goto out; > + > + } > + > + if (speed & TXGBE_LINK_SPEED_10GB_FULL) { > + speedcnt++; > + if (highest_link_speed == TXGBE_LINK_SPEED_UNKNOWN) > + highest_link_speed = TXGBE_LINK_SPEED_10GB_FULL; > + > + /* If we already have link at this speed, just jump out */ > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + > + if ((link_speed == TXGBE_LINK_SPEED_10GB_FULL) && link_up) > + goto out; > + > + /* Allow module to change analog characteristics (25G->10G) */ > + msec_delay(40); > + > + status = hw->mac.setup_mac_link(hw, TXGBE_LINK_SPEED_10GB_FULL, > + autoneg_wait_to_complete); > + if (status != 0) > + return status; > + > + /*aml wait link in setup,no need to repeatly wait*/ > + /* If we have link, just jump out */ > + txgbe_e56_check_phy_link(hw, &link_speed, &link_up); > + > + if (link_up) > + goto out; > + } > + > + /* We didn't get link. Configure back to the highest speed we tried, > + * (if there was more than one). We call ourselves back with just the > + * single highest speed that the user requested. > + */ > + if (speedcnt > 1) > + status = txgbe_setup_mac_link_multispeed_fiber_aml(hw, > + highest_link_speed, > + autoneg_wait_to_complete); > + > +out: > + /* Set autoneg_advertised value based on input link speed */ > + hw->phy.autoneg_advertised = 0; > + > + if (speed & TXGBE_LINK_SPEED_25GB_FULL) > + hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_25GB_FULL; > + > + if (speed & TXGBE_LINK_SPEED_10GB_FULL) > + hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_10GB_FULL; > + > + return status; > +} > + > diff --git a/drivers/net/txgbe/base/txgbe_hw.c > b/drivers/net/txgbe/base/txgbe_hw.c > index 85dbbc5eff..b14ab90466 100644 > --- a/drivers/net/txgbe/base/txgbe_hw.c > +++ b/drivers/net/txgbe/base/txgbe_hw.c > @@ -11,6 +11,8 @@ > #include "txgbe_eeprom.h" > #include "txgbe_mng.h" > #include "txgbe_hw.h" > +#include "txgbe_aml.h" > +#include "txgbe_aml40.h" > > #define TXGBE_RAPTOR_MAX_TX_QUEUES 128 > #define TXGBE_RAPTOR_MAX_RX_QUEUES 128 > @@ -1906,7 +1908,7 @@ static bool txgbe_need_crosstalk_fix(struct txgbe_hw > *hw) > * > * Reads the links register to determine if link is up and the current speed > **/ > -s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed, > +s32 txgbe_check_mac_link_sp(struct txgbe_hw *hw, u32 *speed, > bool *link_up, bool link_up_wait_to_complete) > { > u32 links_reg, links_orig; > @@ -2459,7 +2461,7 @@ s32 txgbe_setup_mac_link_multispeed_fiber(struct > txgbe_hw *hw, > **/ > s32 txgbe_init_shared_code(struct txgbe_hw *hw) > { > - s32 status; > + s32 status = 0; > > /* > * Set the mac type > @@ -2469,11 +2471,16 @@ s32 txgbe_init_shared_code(struct txgbe_hw *hw) > txgbe_init_ops_dummy(hw); > switch (hw->mac.type) { > case txgbe_mac_raptor: > + txgbe_init_ops_sp(hw); > + break; > case txgbe_mac_aml: > + txgbe_init_ops_aml(hw); > + break; > case txgbe_mac_aml40: > - status = txgbe_init_ops_pf(hw); > + txgbe_init_ops_aml40(hw); > break; > case txgbe_mac_raptor_vf: > + case txgbe_mac_aml_vf: > status = txgbe_init_ops_vf(hw); > break; > default: > @@ -2539,7 +2546,7 @@ s32 txgbe_set_mac_type(struct txgbe_hw *hw) > return err; > } > > -void txgbe_init_mac_link_ops(struct txgbe_hw *hw) > +void txgbe_init_mac_link_ops_sp(struct txgbe_hw *hw) > { > struct txgbe_mac_info *mac = &hw->mac; > > @@ -2599,7 +2606,7 @@ s32 txgbe_init_phy_raptor(struct txgbe_hw *hw) > goto init_phy_ops_out; > > /* Setup function pointers based on detected SFP module and speeds */ > - txgbe_init_mac_link_ops(hw); > + hw->mac.init_mac_link_ops(hw); > > /* If copper media, overwrite with copper function pointers */ > if (phy->media_type == txgbe_media_type_copper) { > @@ -2634,7 +2641,7 @@ s32 txgbe_setup_sfp_modules(struct txgbe_hw *hw) > if (hw->phy.sfp_type == txgbe_sfp_type_unknown) > return 0; > > - txgbe_init_mac_link_ops(hw); > + hw->mac.init_mac_link_ops(hw); > > /* PHY config will finish before releasing the semaphore */ > err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY); > @@ -2781,7 +2788,7 @@ s32 txgbe_flash_read_dword(struct txgbe_hw *hw, u32 > addr, u32 *data) > * Initialize the function pointers and assign the MAC type. > * Does not touch the hardware. > **/ > -s32 txgbe_init_ops_pf(struct txgbe_hw *hw) > +s32 txgbe_init_ops_generic(struct txgbe_hw *hw) > { > struct txgbe_bus_info *bus = &hw->bus; > struct txgbe_mac_info *mac = &hw->mac; > @@ -2793,7 +2800,6 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw) > bus->set_lan_id = txgbe_set_lan_id_multi_port; > > /* PHY */ > - phy->get_media_type = txgbe_get_media_type_raptor; > phy->identify = txgbe_identify_phy; > phy->init = txgbe_init_phy_raptor; > phy->read_reg = txgbe_read_phy_reg; > @@ -2861,8 +2867,6 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw) > mac->fc_autoneg = txgbe_fc_autoneg; > > /* Link */ > - mac->get_link_capabilities = txgbe_get_link_capabilities_raptor; > - mac->check_link = txgbe_check_mac_link; > mac->setup_pba = txgbe_set_pba; > > /* Manageability interface */ > @@ -2901,6 +2905,22 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw) > return 0; > } > > +void txgbe_init_ops_sp(struct txgbe_hw *hw) > +{ > + struct txgbe_mac_info *mac = &hw->mac; > + struct txgbe_phy_info *phy = &hw->phy; > + > + txgbe_init_ops_generic(hw); > + > + /* PHY */ > + phy->get_media_type = txgbe_get_media_type_sp; > + > + /* LINK */ > + mac->init_mac_link_ops = txgbe_init_mac_link_ops_sp; > + mac->get_link_capabilities = txgbe_get_link_capabilities_sp; > + mac->check_link = txgbe_check_mac_link_sp; > +} > + > /** > * txgbe_get_link_capabilities_raptor - Determines link capabilities > * @hw: pointer to hardware structure > @@ -2909,7 +2929,7 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw) > * > * Determines the link capabilities by reading the AUTOC register. > **/ > -s32 txgbe_get_link_capabilities_raptor(struct txgbe_hw *hw, > +s32 txgbe_get_link_capabilities_sp(struct txgbe_hw *hw, > u32 *speed, > bool *autoneg) > { > @@ -3015,7 +3035,7 @@ s32 txgbe_get_link_capabilities_raptor(struct txgbe_hw > *hw, > * > * Returns the media type (fiber, copper, backplane) > **/ > -u32 txgbe_get_media_type_raptor(struct txgbe_hw *hw) > +u32 txgbe_get_media_type_sp(struct txgbe_hw *hw) I think it should be a separate patch to cleanup codes: *_raptor -> *_sp > { > u32 media_type; > > @@ -3849,3 +3869,37 @@ s32 txgbe_reset_pipeline_raptor(struct txgbe_hw *hw) > return err; > } > > +s32 txgbe_e56_check_phy_link(struct txgbe_hw *hw, u32 *speed, > + bool *link_up) > +{ > + u32 rdata = 0; > + u32 links_reg = 0; > + > + /* must read it twice because the state may > + * not be correct the first time you read it > + */ > + rdata = rd32_epcs(hw, 0x30001); > + rdata = rd32_epcs(hw, 0x30001); > + > + if (rdata & TXGBE_AML_PHY_LINK_UP) > + *link_up = true; > + else > + *link_up = false; > + > + links_reg = rd32(hw, TXGBE_PORTSTAT); > + if (*link_up) { > + if ((links_reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) == > + TXGBE_CFG_PORT_ST_AML_LINK_40G) > + *speed = TXGBE_LINK_SPEED_40GB_FULL; > + else if ((links_reg & TXGBE_CFG_PORT_ST_AML_LINK_25G) == > + TXGBE_CFG_PORT_ST_AML_LINK_25G) > + *speed = TXGBE_LINK_SPEED_25GB_FULL; > + else if ((links_reg & TXGBE_CFG_PORT_ST_AML_LINK_10G) == > + TXGBE_CFG_PORT_ST_AML_LINK_10G) > + *speed = TXGBE_LINK_SPEED_10GB_FULL; > + } else { > + *speed = TXGBE_LINK_SPEED_UNKNOWN; > + } > + > + return 0; > +} > diff --git a/drivers/net/txgbe/base/txgbe_hw.h > b/drivers/net/txgbe/base/txgbe_hw.h > index 1ed2892f61..476a9688bd 100644 > --- a/drivers/net/txgbe/base/txgbe_hw.h > +++ b/drivers/net/txgbe/base/txgbe_hw.h > @@ -56,7 +56,7 @@ s32 txgbe_set_vlvf(struct txgbe_hw *hw, u32 vlan, u32 vind, > s32 txgbe_clear_vfta(struct txgbe_hw *hw); > s32 txgbe_find_vlvf_slot(struct txgbe_hw *hw, u32 vlan, bool vlvf_bypass); > > -s32 txgbe_check_mac_link(struct txgbe_hw *hw, > +s32 txgbe_check_mac_link_sp(struct txgbe_hw *hw, > u32 *speed, > bool *link_up, bool link_up_wait_to_complete); > > @@ -86,10 +86,11 @@ s32 txgbe_negotiate_fc(struct txgbe_hw *hw, u32 adv_reg, > u32 lp_reg, > u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); > s32 txgbe_init_shared_code(struct txgbe_hw *hw); > s32 txgbe_set_mac_type(struct txgbe_hw *hw); > -s32 txgbe_init_ops_pf(struct txgbe_hw *hw); > -s32 txgbe_get_link_capabilities_raptor(struct txgbe_hw *hw, > +s32 txgbe_init_ops_generic(struct txgbe_hw *hw); > +void txgbe_init_ops_sp(struct txgbe_hw *hw); > +s32 txgbe_get_link_capabilities_sp(struct txgbe_hw *hw, > u32 *speed, bool *autoneg); > -u32 txgbe_get_media_type_raptor(struct txgbe_hw *hw); > +u32 txgbe_get_media_type_sp(struct txgbe_hw *hw); > void txgbe_disable_tx_laser_multispeed_fiber(struct txgbe_hw *hw); > void txgbe_enable_tx_laser_multispeed_fiber(struct txgbe_hw *hw); > void txgbe_flap_tx_laser_multispeed_fiber(struct txgbe_hw *hw); > @@ -103,7 +104,7 @@ s32 txgbe_start_mac_link_raptor(struct txgbe_hw *hw, > s32 txgbe_setup_mac_link(struct txgbe_hw *hw, u32 speed, > bool autoneg_wait_to_complete); > s32 txgbe_setup_sfp_modules(struct txgbe_hw *hw); > -void txgbe_init_mac_link_ops(struct txgbe_hw *hw); > +void txgbe_init_mac_link_ops_sp(struct txgbe_hw *hw); > s32 txgbe_reset_hw(struct txgbe_hw *hw); > s32 txgbe_start_hw_raptor(struct txgbe_hw *hw); > s32 txgbe_init_phy_raptor(struct txgbe_hw *hw); > @@ -114,4 +115,6 @@ s32 txgbe_reinit_fdir_tables(struct txgbe_hw *hw); > bool txgbe_verify_lesm_fw_enabled_raptor(struct txgbe_hw *hw); > s32 txgbe_fmgr_cmd_op(struct txgbe_hw *hw, u32 cmd, u32 cmd_addr); > s32 txgbe_flash_read_dword(struct txgbe_hw *hw, u32 addr, u32 *data); > +s32 txgbe_e56_check_phy_link(struct txgbe_hw *hw, u32 *speed, > + bool *link_up); > #endif /* _TXGBE_HW_H_ */