src/dpdk/drivers/net/txgbe/base/txgbe_hw.c
s32 txgbe_setup_mac_link(struct txgbe_hw *hw,
			       u32 speed,
			       bool autoneg_wait_to_complete)
{
	bool autoneg = false;
	s32 status = 0;

	u64 autoc = hw->mac.autoc_read(hw);
	u64 pma_pmd_10gs = autoc & TXGBE_AUTOC_10GS_PMA_PMD_MASK;
	u64 pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;
	u64 link_mode = autoc & TXGBE_AUTOC_LMS_MASK;
	u64 current_autoc = autoc;
	u64 orig_autoc = 0;
	u32 links_reg;
	u32 i;
	u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN;

	DEBUGFUNC("txgbe_setup_mac_link");

	/* 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;

	/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
	if (hw->mac.orig_link_settings_stored)
		orig_autoc = hw->mac.orig_autoc;
	else
		orig_autoc = autoc;

	link_mode = autoc & TXGBE_AUTOC_LMS_MASK;
	pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;

	if (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||
	    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
	    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
		/* Set KX4/KX/KR support according to speed requested */
		autoc &= ~(TXGBE_AUTOC_KX_SUPP |
			   TXGBE_AUTOC_KX4_SUPP |
			   TXGBE_AUTOC_KR_SUPP);
		if (speed & TXGBE_LINK_SPEED_10GB_FULL) {
			if (orig_autoc & TXGBE_AUTOC_KX4_SUPP)
				autoc |= TXGBE_AUTOC_KX4_SUPP;
			if ((orig_autoc & TXGBE_AUTOC_KR_SUPP) &&
			    !hw->phy.smart_speed_active)
				autoc |= TXGBE_AUTOC_KR_SUPP;
		}
		if (speed & TXGBE_LINK_SPEED_1GB_FULL)
			autoc |= TXGBE_AUTOC_KX_SUPP;
	} else if ((pma_pmd_1g == TXGBE_AUTOC_1G_SFI) &&
		   (link_mode == TXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
		    link_mode == TXGBE_AUTOC_LMS_1G_AN)) {
		/* Switch from 1G SFI to 10G SFI if requested */
		if (speed == TXGBE_LINK_SPEED_10GB_FULL &&
		    pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI) {
			autoc &= ~TXGBE_AUTOC_LMS_MASK;
			autoc |= TXGBE_AUTOC_LMS_10G;
		}
	} else if ((pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI) &&
		   (link_mode == TXGBE_AUTOC_LMS_10G)) {
		/* Switch from 10G SFI to 1G SFI if requested */
		if (speed == TXGBE_LINK_SPEED_1GB_FULL &&
		    pma_pmd_1g == TXGBE_AUTOC_1G_SFI) {
			autoc &= ~TXGBE_AUTOC_LMS_MASK;
			if (autoneg || hw->phy.type == txgbe_phy_qsfp_intel)
				autoc |= TXGBE_AUTOC_LMS_1G_AN;
			else
				autoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN;
		}
	}

	if (autoc == current_autoc)
		return status;

	autoc &= ~TXGBE_AUTOC_SPEED_MASK;
	autoc |= TXGBE_AUTOC_SPEED(speed);
	autoc |= (autoneg ? TXGBE_AUTOC_AUTONEG : 0);

	/* Restart link */
	hw->mac.autoc_write(hw, autoc);

	/* Only poll for autoneg to complete if specified to do so */
	if (autoneg_wait_to_complete) {
		if (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||
		    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
		    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
			links_reg = 0; /*Just in case Autoneg time=0*/
			for (i = 0; i < TXGBE_AUTO_NEG_TIME; i++) {
				links_reg = rd32(hw, TXGBE_PORTSTAT);
				if (links_reg & TXGBE_PORTSTAT_UP)
					break;
				msec_delay(100);
			}
			if (!(links_reg & TXGBE_PORTSTAT_UP)) {
				status = TXGBE_ERR_AUTONEG_NOT_COMPLETE;
				DEBUGOUT("Autoneg did not complete.\n");
			}
		}
	}

	/* Add delay to filter out noises during initial link setup */
	msec_delay(50);

	return status;
}
/**
 *  txgbe_setup_mac_link - 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 AUTOC register and restarts link.
 **/
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 AUTOC register and restarts link.
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 AUTOC register and restarts link .
s32 txgbe_setup_mac_link(struct txgbe_hw *hw,
			       u32 speed,
			       bool autoneg_wait_to_complete)
{
	bool autoneg = false;
	s32 status = 0;
	u64 autoc = hw->mac.autoc_read(hw);
	u64 pma_pmd_10gs = autoc & TXGBE_AUTOC_10GS_PMA_PMD_MASK;
	u64 pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;
	u64 link_mode = autoc & TXGBE_AUTOC_LMS_MASK;
	u64 current_autoc = autoc;
	u64 orig_autoc = 0;
	u32 links_reg;
	u32 i;
	u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN;
	DEBUGFUNC("txgbe_setup_mac_link");
	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;
	if (hw->mac.orig_link_settings_stored)
		orig_autoc = hw->mac.orig_autoc;
	else
		orig_autoc = autoc;
	link_mode = autoc & TXGBE_AUTOC_LMS_MASK;
	pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK;
	if (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||
	    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
	    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
		autoc &= ~(TXGBE_AUTOC_KX_SUPP |
			   TXGBE_AUTOC_KX4_SUPP |
			   TXGBE_AUTOC_KR_SUPP);
		if (speed & TXGBE_LINK_SPEED_10GB_FULL) {
			if (orig_autoc & TXGBE_AUTOC_KX4_SUPP)
				autoc |= TXGBE_AUTOC_KX4_SUPP;
			if ((orig_autoc & TXGBE_AUTOC_KR_SUPP) &&
			    !hw->phy.smart_speed_active)
				autoc |= TXGBE_AUTOC_KR_SUPP;
		}
		if (speed & TXGBE_LINK_SPEED_1GB_FULL)
			autoc |= TXGBE_AUTOC_KX_SUPP;
	} else if ((pma_pmd_1g == TXGBE_AUTOC_1G_SFI) &&
		   (link_mode == TXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
		    link_mode == TXGBE_AUTOC_LMS_1G_AN)) {
		if (speed == TXGBE_LINK_SPEED_10GB_FULL &&
		    pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI) {
			autoc &= ~TXGBE_AUTOC_LMS_MASK;
			autoc |= TXGBE_AUTOC_LMS_10G;
		}
	} else if ((pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI) &&
		   (link_mode == TXGBE_AUTOC_LMS_10G)) {
		if (speed == TXGBE_LINK_SPEED_1GB_FULL &&
		    pma_pmd_1g == TXGBE_AUTOC_1G_SFI) {
			autoc &= ~TXGBE_AUTOC_LMS_MASK;
			if (autoneg || hw->phy.type == txgbe_phy_qsfp_intel)
				autoc |= TXGBE_AUTOC_LMS_1G_AN;
			else
				autoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN;
		}
	}
	if (autoc == current_autoc)
		return status;
	autoc &= ~TXGBE_AUTOC_SPEED_MASK;
	autoc |= TXGBE_AUTOC_SPEED(speed);
	autoc |= (autoneg ? TXGBE_AUTOC_AUTONEG : 0);
	hw->mac.autoc_write(hw, autoc);
	if (autoneg_wait_to_complete) {
		if (link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR ||
		    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
		    link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
			links_reg = 0; 
			for (i = 0; i < TXGBE_AUTO_NEG_TIME; i++) {
				links_reg = rd32(hw, TXGBE_PORTSTAT);
				if (links_reg & TXGBE_PORTSTAT_UP)
					break;
				msec_delay(100);
			}
			if (!(links_reg & TXGBE_PORTSTAT_UP)) {
				status = TXGBE_ERR_AUTONEG_NOT_COMPLETE;
				DEBUGOUT("Autoneg did not complete.\n");
			}
		}
	}
	msec_delay(50);
	return status;
}
s32 txgbe_setup_mac_link ( struct txgbe_hw * hw , u32 speed , bool autoneg_wait_to_complete ) { bool autoneg = false ; s32 status = 0 ; u64 autoc = hw -> mac . autoc_read ( hw ) ; u64 pma_pmd_10gs = autoc & TXGBE_AUTOC_10GS_PMA_PMD_MASK ; u64 pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK ; u64 link_mode = autoc & TXGBE_AUTOC_LMS_MASK ; u64 current_autoc = autoc ; u64 orig_autoc = 0 ; u32 links_reg ; u32 i ; u32 link_capabilities = TXGBE_LINK_SPEED_UNKNOWN ; DEBUGFUNC ( " " ) ; 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 ; if ( hw -> mac . orig_link_settings_stored ) orig_autoc = hw -> mac . orig_autoc ; else orig_autoc = autoc ; link_mode = autoc & TXGBE_AUTOC_LMS_MASK ; pma_pmd_1g = autoc & TXGBE_AUTOC_1G_PMA_PMD_MASK ; if ( link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR || link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII ) { autoc &= ~ ( TXGBE_AUTOC_KX_SUPP | TXGBE_AUTOC_KX4_SUPP | TXGBE_AUTOC_KR_SUPP ) ; if ( speed & TXGBE_LINK_SPEED_10GB_FULL ) { if ( orig_autoc & TXGBE_AUTOC_KX4_SUPP ) autoc |= TXGBE_AUTOC_KX4_SUPP ; if ( ( orig_autoc & TXGBE_AUTOC_KR_SUPP ) && ! hw -> phy . smart_speed_active ) autoc |= TXGBE_AUTOC_KR_SUPP ; } if ( speed & TXGBE_LINK_SPEED_1GB_FULL ) autoc |= TXGBE_AUTOC_KX_SUPP ; } else if ( ( pma_pmd_1g == TXGBE_AUTOC_1G_SFI ) && ( link_mode == TXGBE_AUTOC_LMS_1G_LINK_NO_AN || link_mode == TXGBE_AUTOC_LMS_1G_AN ) ) { if ( speed == TXGBE_LINK_SPEED_10GB_FULL && pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI ) { autoc &= ~ TXGBE_AUTOC_LMS_MASK ; autoc |= TXGBE_AUTOC_LMS_10G ; } } else if ( ( pma_pmd_10gs == TXGBE_AUTOC_10GS_SFI ) && ( link_mode == TXGBE_AUTOC_LMS_10G ) ) { if ( speed == TXGBE_LINK_SPEED_1GB_FULL && pma_pmd_1g == TXGBE_AUTOC_1G_SFI ) { autoc &= ~ TXGBE_AUTOC_LMS_MASK ; if ( autoneg || hw -> phy . type == txgbe_phy_qsfp_intel ) autoc |= TXGBE_AUTOC_LMS_1G_AN ; else autoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN ; } } if ( autoc == current_autoc ) return status ; autoc &= ~ TXGBE_AUTOC_SPEED_MASK ; autoc |= TXGBE_AUTOC_SPEED ( speed ) ; autoc |= ( autoneg ? TXGBE_AUTOC_AUTONEG : 0 ) ; hw -> mac . autoc_write ( hw , autoc ) ; if ( autoneg_wait_to_complete ) { if ( link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR || link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || link_mode == TXGBE_AUTOC_LMS_KX4_KX_KR_SGMII ) { links_reg = 0 ; for ( i = 0 ; i < TXGBE_AUTO_NEG_TIME ; i ++ ) { links_reg = rd32 ( hw , TXGBE_PORTSTAT ) ; if ( links_reg & TXGBE_PORTSTAT_UP ) break ; msec_delay ( 100 ) ; } if ( ! ( links_reg & TXGBE_PORTSTAT_UP ) ) { status = TXGBE_ERR_AUTONEG_NOT_COMPLETE ; DEBUGOUT ( " \n " ) ; } } } msec_delay ( 50 ) ; return status ; }
txgbe_setup_mac_link - Set MAC link speed
  @hw: pointer to hardware structure
  @speed: new link speed
  @autoneg_wait_to_complete: true when waiting for completion is needed
txgbe_setup_mac_link - Set MAC link speed @hw : pointer to hardware structure @speed : new link speed @autoneg_wait_to_complete : true when waiting for completion is needed
/* Check to see if speed passed in is supported. */ /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ /* Set KX4/KX/KR support according to speed requested */ /* Switch from 1G SFI to 10G SFI if requested */ /* Switch from 10G SFI to 1G SFI if requested */ /* Restart link */ /* Only poll for autoneg to complete if specified to do so */ /*Just in case Autoneg time=0*/ /* Add delay to filter out noises during initial link setup */