src/dpdk/drivers/net/txgbe/base/txgbe_hw.c
s32 txgbe_setup_fc(struct txgbe_hw *hw)
{
	s32 err = 0;
	u32 reg = 0;
	u16 reg_cu = 0;
	u32 value = 0;
	u64 reg_bp = 0;
	bool locked = false;

	DEBUGFUNC("txgbe_setup_fc");

	/* Validate the requested mode */
	if (hw->fc.strict_ieee && hw->fc.requested_mode == txgbe_fc_rx_pause) {
		DEBUGOUT("txgbe_fc_rx_pause not valid in strict IEEE mode\n");
		err = TXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
	}

	/*
	 * 10gig parts do not have a word in the EEPROM to determine the
	 * default flow control setting, so we explicitly set it to full.
	 */
	if (hw->fc.requested_mode == txgbe_fc_default)
		hw->fc.requested_mode = txgbe_fc_full;

	/*
	 * Set up the 1G and 10G flow control advertisement registers so the
	 * HW will be able to do fc autoneg once the cable is plugged in.  If
	 * we link at 10G, the 1G advertisement is harmless and vice versa.
	 */
	switch (hw->phy.media_type) {
	case txgbe_media_type_backplane:
		/* some MAC's need RMW protection on AUTOC */
		err = hw->mac.prot_autoc_read(hw, &locked, &reg_bp);
		if (err != 0)
			goto out;

		/* fall through - only backplane uses autoc */
	case txgbe_media_type_fiber_qsfp:
	case txgbe_media_type_fiber:
	case txgbe_media_type_copper:
		hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
				     TXGBE_MD_DEV_AUTO_NEG, &reg_cu);
		break;
	default:
		break;
	}

	/*
	 * The possible values of fc.requested_mode are:
	 * 0: Flow control is completely disabled
	 * 1: Rx flow control is enabled (we can receive pause frames,
	 *    but not send pause frames).
	 * 2: Tx flow control is enabled (we can send pause frames but
	 *    we do not support receiving pause frames).
	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
	 * other: Invalid.
	 */
	switch (hw->fc.requested_mode) {
	case txgbe_fc_none:
		/* Flow control completely disabled by software override. */
		reg &= ~(SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM);
		if (hw->phy.media_type == txgbe_media_type_backplane)
			reg_bp &= ~(TXGBE_AUTOC_SYM_PAUSE |
				    TXGBE_AUTOC_ASM_PAUSE);
		else if (hw->phy.media_type == txgbe_media_type_copper)
			reg_cu &= ~(TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE);
		break;
	case txgbe_fc_tx_pause:
		/*
		 * Tx Flow control is enabled, and Rx Flow control is
		 * disabled by software override.
		 */
		reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg &= ~SR_MII_MMD_AN_ADV_PAUSE_SYM;
		if (hw->phy.media_type == txgbe_media_type_backplane) {
			reg_bp |= TXGBE_AUTOC_ASM_PAUSE;
			reg_bp &= ~TXGBE_AUTOC_SYM_PAUSE;
		} else if (hw->phy.media_type == txgbe_media_type_copper) {
			reg_cu |= TXGBE_TAF_ASM_PAUSE;
			reg_cu &= ~TXGBE_TAF_SYM_PAUSE;
		}
		reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_ASM;
		break;
	case txgbe_fc_rx_pause:
		/*
		 * Rx Flow control is enabled and Tx Flow control is
		 * disabled by software override. Since there really
		 * isn't a way to advertise that we are capable of RX
		 * Pause ONLY, we will advertise that we support both
		 * symmetric and asymmetric Rx PAUSE, as such we fall
		 * through to the fc_full statement.  Later, we will
		 * disable the adapter's ability to send PAUSE frames.
		 */
	case txgbe_fc_full:
		/* Flow control (both Rx and Tx) is enabled by SW override. */
		reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM;
		if (hw->phy.media_type == txgbe_media_type_backplane)
			reg_bp |= TXGBE_AUTOC_SYM_PAUSE |
				  TXGBE_AUTOC_ASM_PAUSE;
		else if (hw->phy.media_type == txgbe_media_type_copper)
			reg_cu |= TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE;
		reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_SYM |
			SR_AN_MMD_ADV_REG1_PAUSE_ASM;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		err = TXGBE_ERR_CONFIG;
		goto out;
	}

	/*
	 * Enable auto-negotiation between the MAC & PHY;
	 * the MAC will advertise clause 37 flow control.
	 */
	value = rd32_epcs(hw, SR_MII_MMD_AN_ADV);
	value = (value & ~(SR_MII_MMD_AN_ADV_PAUSE_ASM |
		SR_MII_MMD_AN_ADV_PAUSE_SYM)) | reg;
	wr32_epcs(hw, SR_MII_MMD_AN_ADV, value);

	/*
	 * AUTOC restart handles negotiation of 1G and 10G on backplane
	 * and copper. There is no need to set the PCS1GCTL register.
	 *
	 */
	if (hw->phy.media_type == txgbe_media_type_backplane) {
		value = rd32_epcs(hw, SR_AN_MMD_ADV_REG1);
		value = (value & ~(SR_AN_MMD_ADV_REG1_PAUSE_ASM |
			SR_AN_MMD_ADV_REG1_PAUSE_SYM)) |
			reg_bp;
		wr32_epcs(hw, SR_AN_MMD_ADV_REG1, value);
	} else if ((hw->phy.media_type == txgbe_media_type_copper) &&
		    (txgbe_device_supports_autoneg_fc(hw))) {
		hw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
				      TXGBE_MD_DEV_AUTO_NEG, reg_cu);
	}

	DEBUGOUT("Set up FC; reg = 0x%08X\n", reg);
out:
	return err;
}
/**
 *  txgbe_setup_fc - Set up flow control
 *  @hw: pointer to hardware structure
 *
 *  Called at init time to set up flow control.
 **/
Set up flow control
@hw: pointer to hardware structure

Called at init time to set up flow control.
Set up flow control @hw : pointer to hardware structure Called at init time to set up flow control .
s32 txgbe_setup_fc(struct txgbe_hw *hw)
{
	s32 err = 0;
	u32 reg = 0;
	u16 reg_cu = 0;
	u32 value = 0;
	u64 reg_bp = 0;
	bool locked = false;
	DEBUGFUNC("txgbe_setup_fc");
	if (hw->fc.strict_ieee && hw->fc.requested_mode == txgbe_fc_rx_pause) {
		DEBUGOUT("txgbe_fc_rx_pause not valid in strict IEEE mode\n");
		err = TXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
	}
	if (hw->fc.requested_mode == txgbe_fc_default)
		hw->fc.requested_mode = txgbe_fc_full;
	switch (hw->phy.media_type) {
	case txgbe_media_type_backplane:
		err = hw->mac.prot_autoc_read(hw, &locked, &reg_bp);
		if (err != 0)
			goto out;
	case txgbe_media_type_fiber_qsfp:
	case txgbe_media_type_fiber:
	case txgbe_media_type_copper:
		hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
				     TXGBE_MD_DEV_AUTO_NEG, &reg_cu);
		break;
	default:
		break;
	}
	switch (hw->fc.requested_mode) {
	case txgbe_fc_none:
		reg &= ~(SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM);
		if (hw->phy.media_type == txgbe_media_type_backplane)
			reg_bp &= ~(TXGBE_AUTOC_SYM_PAUSE |
				    TXGBE_AUTOC_ASM_PAUSE);
		else if (hw->phy.media_type == txgbe_media_type_copper)
			reg_cu &= ~(TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE);
		break;
	case txgbe_fc_tx_pause:
		reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg &= ~SR_MII_MMD_AN_ADV_PAUSE_SYM;
		if (hw->phy.media_type == txgbe_media_type_backplane) {
			reg_bp |= TXGBE_AUTOC_ASM_PAUSE;
			reg_bp &= ~TXGBE_AUTOC_SYM_PAUSE;
		} else if (hw->phy.media_type == txgbe_media_type_copper) {
			reg_cu |= TXGBE_TAF_ASM_PAUSE;
			reg_cu &= ~TXGBE_TAF_SYM_PAUSE;
		}
		reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_ASM;
		break;
	case txgbe_fc_rx_pause:
	case txgbe_fc_full:
		reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM;
		if (hw->phy.media_type == txgbe_media_type_backplane)
			reg_bp |= TXGBE_AUTOC_SYM_PAUSE |
				  TXGBE_AUTOC_ASM_PAUSE;
		else if (hw->phy.media_type == txgbe_media_type_copper)
			reg_cu |= TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE;
		reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM |
			SR_MII_MMD_AN_ADV_PAUSE_ASM;
		reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_SYM |
			SR_AN_MMD_ADV_REG1_PAUSE_ASM;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		err = TXGBE_ERR_CONFIG;
		goto out;
	}
	value = rd32_epcs(hw, SR_MII_MMD_AN_ADV);
	value = (value & ~(SR_MII_MMD_AN_ADV_PAUSE_ASM |
		SR_MII_MMD_AN_ADV_PAUSE_SYM)) | reg;
	wr32_epcs(hw, SR_MII_MMD_AN_ADV, value);
	if (hw->phy.media_type == txgbe_media_type_backplane) {
		value = rd32_epcs(hw, SR_AN_MMD_ADV_REG1);
		value = (value & ~(SR_AN_MMD_ADV_REG1_PAUSE_ASM |
			SR_AN_MMD_ADV_REG1_PAUSE_SYM)) |
			reg_bp;
		wr32_epcs(hw, SR_AN_MMD_ADV_REG1, value);
	} else if ((hw->phy.media_type == txgbe_media_type_copper) &&
		    (txgbe_device_supports_autoneg_fc(hw))) {
		hw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_ADVT,
				      TXGBE_MD_DEV_AUTO_NEG, reg_cu);
	}
	DEBUGOUT("Set up FC; reg = 0x%08X\n", reg);
out:
	return err;
}
s32 txgbe_setup_fc ( struct txgbe_hw * hw ) { s32 err = 0 ; u32 reg = 0 ; u16 reg_cu = 0 ; u32 value = 0 ; u64 reg_bp = 0 ; bool locked = false ; DEBUGFUNC ( " " ) ; if ( hw -> fc . strict_ieee && hw -> fc . requested_mode == txgbe_fc_rx_pause ) { DEBUGOUT ( " \n " ) ; err = TXGBE_ERR_INVALID_LINK_SETTINGS ; goto out ; } if ( hw -> fc . requested_mode == txgbe_fc_default ) hw -> fc . requested_mode = txgbe_fc_full ; switch ( hw -> phy . media_type ) { case txgbe_media_type_backplane : err = hw -> mac . prot_autoc_read ( hw , & locked , & reg_bp ) ; if ( err != 0 ) goto out ; case txgbe_media_type_fiber_qsfp : case txgbe_media_type_fiber : case txgbe_media_type_copper : hw -> phy . read_reg ( hw , TXGBE_MD_AUTO_NEG_ADVT , TXGBE_MD_DEV_AUTO_NEG , & reg_cu ) ; break ; default : break ; } switch ( hw -> fc . requested_mode ) { case txgbe_fc_none : reg &= ~ ( SR_MII_MMD_AN_ADV_PAUSE_SYM | SR_MII_MMD_AN_ADV_PAUSE_ASM ) ; if ( hw -> phy . media_type == txgbe_media_type_backplane ) reg_bp &= ~ ( TXGBE_AUTOC_SYM_PAUSE | TXGBE_AUTOC_ASM_PAUSE ) ; else if ( hw -> phy . media_type == txgbe_media_type_copper ) reg_cu &= ~ ( TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE ) ; break ; case txgbe_fc_tx_pause : reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM ; reg &= ~ SR_MII_MMD_AN_ADV_PAUSE_SYM ; if ( hw -> phy . media_type == txgbe_media_type_backplane ) { reg_bp |= TXGBE_AUTOC_ASM_PAUSE ; reg_bp &= ~ TXGBE_AUTOC_SYM_PAUSE ; } else if ( hw -> phy . media_type == txgbe_media_type_copper ) { reg_cu |= TXGBE_TAF_ASM_PAUSE ; reg_cu &= ~ TXGBE_TAF_SYM_PAUSE ; } reg |= SR_MII_MMD_AN_ADV_PAUSE_ASM ; reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_ASM ; break ; case txgbe_fc_rx_pause : case txgbe_fc_full : reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM | SR_MII_MMD_AN_ADV_PAUSE_ASM ; if ( hw -> phy . media_type == txgbe_media_type_backplane ) reg_bp |= TXGBE_AUTOC_SYM_PAUSE | TXGBE_AUTOC_ASM_PAUSE ; else if ( hw -> phy . media_type == txgbe_media_type_copper ) reg_cu |= TXGBE_TAF_SYM_PAUSE | TXGBE_TAF_ASM_PAUSE ; reg |= SR_MII_MMD_AN_ADV_PAUSE_SYM | SR_MII_MMD_AN_ADV_PAUSE_ASM ; reg_bp |= SR_AN_MMD_ADV_REG1_PAUSE_SYM | SR_AN_MMD_ADV_REG1_PAUSE_ASM ; break ; default : DEBUGOUT ( " \n " ) ; err = TXGBE_ERR_CONFIG ; goto out ; } value = rd32_epcs ( hw , SR_MII_MMD_AN_ADV ) ; value = ( value & ~ ( SR_MII_MMD_AN_ADV_PAUSE_ASM | SR_MII_MMD_AN_ADV_PAUSE_SYM ) ) | reg ; wr32_epcs ( hw , SR_MII_MMD_AN_ADV , value ) ; if ( hw -> phy . media_type == txgbe_media_type_backplane ) { value = rd32_epcs ( hw , SR_AN_MMD_ADV_REG1 ) ; value = ( value & ~ ( SR_AN_MMD_ADV_REG1_PAUSE_ASM | SR_AN_MMD_ADV_REG1_PAUSE_SYM ) ) | reg_bp ; wr32_epcs ( hw , SR_AN_MMD_ADV_REG1 , value ) ; } else if ( ( hw -> phy . media_type == txgbe_media_type_copper ) && ( txgbe_device_supports_autoneg_fc ( hw ) ) ) { hw -> phy . write_reg ( hw , TXGBE_MD_AUTO_NEG_ADVT , TXGBE_MD_DEV_AUTO_NEG , reg_cu ) ; } DEBUGOUT ( " \n " , reg ) ; out : return err ; }
txgbe_setup_fc - Set up flow control
  @hw: pointer to hardware structure
txgbe_setup_fc - Set up flow control @hw : pointer to hardware structure
/* Validate the requested mode */ /*
	 * 10gig parts do not have a word in the EEPROM to determine the
	 * default flow control setting, so we explicitly set it to full.
	 */ /*
	 * Set up the 1G and 10G flow control advertisement registers so the
	 * HW will be able to do fc autoneg once the cable is plugged in.  If
	 * we link at 10G, the 1G advertisement is harmless and vice versa.
	 */ /* some MAC's need RMW protection on AUTOC */ /* fall through - only backplane uses autoc */ /*
	 * The possible values of fc.requested_mode are:
	 * 0: Flow control is completely disabled
	 * 1: Rx flow control is enabled (we can receive pause frames,
	 *    but not send pause frames).
	 * 2: Tx flow control is enabled (we can send pause frames but
	 *    we do not support receiving pause frames).
	 * 3: Both Rx and Tx flow control (symmetric) are enabled.
	 * other: Invalid.
	 */ /* Flow control completely disabled by software override. */ /*
		 * Tx Flow control is enabled, and Rx Flow control is
		 * disabled by software override.
		 */ /*
		 * Rx Flow control is enabled and Tx Flow control is
		 * disabled by software override. Since there really
		 * isn't a way to advertise that we are capable of RX
		 * Pause ONLY, we will advertise that we support both
		 * symmetric and asymmetric Rx PAUSE, as such we fall
		 * through to the fc_full statement.  Later, we will
		 * disable the adapter's ability to send PAUSE frames.
		 */ /* Flow control (both Rx and Tx) is enabled by SW override. */ /*
	 * Enable auto-negotiation between the MAC & PHY;
	 * the MAC will advertise clause 37 flow control.
	 */ /*
	 * AUTOC restart handles negotiation of 1G and 10G on backplane
	 * and copper. There is no need to set the PCS1GCTL register.
	 *
	 */