src/dpdk/drivers/net/txgbe/base/txgbe_hw.c
s32 txgbe_fc_enable(struct txgbe_hw *hw)
{
	s32 err = 0;
	u32 mflcn_reg, fccfg_reg;
	u32 pause_time;
	u32 fcrtl, fcrth;
	int i;

	DEBUGFUNC("txgbe_fc_enable");

	/* Validate the water mark configuration */
	if (!hw->fc.pause_time) {
		err = TXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
	}

	/* Low water mark of zero causes XOFF floods */
	for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
		if ((hw->fc.current_mode & txgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			if (!hw->fc.low_water[i] ||
			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
				DEBUGOUT("Invalid water mark configuration\n");
				err = TXGBE_ERR_INVALID_LINK_SETTINGS;
				goto out;
			}
		}
	}

	/* Negotiate the fc mode to use */
	hw->mac.fc_autoneg(hw);

	/* Disable any previous flow control settings */
	mflcn_reg = rd32(hw, TXGBE_RXFCCFG);
	mflcn_reg &= ~(TXGBE_RXFCCFG_FC | TXGBE_RXFCCFG_PFC);

	fccfg_reg = rd32(hw, TXGBE_TXFCCFG);
	fccfg_reg &= ~(TXGBE_TXFCCFG_FC | TXGBE_TXFCCFG_PFC);

	/*
	 * The possible values of fc.current_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.current_mode) {
	case txgbe_fc_none:
		/*
		 * Flow control is disabled by software override or autoneg.
		 * The code below will actually disable it in the HW.
		 */
		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.  Later, we will
		 * disable the adapter's ability to send PAUSE frames.
		 */
		mflcn_reg |= TXGBE_RXFCCFG_FC;
		break;
	case txgbe_fc_tx_pause:
		/*
		 * Tx Flow control is enabled, and Rx Flow control is
		 * disabled by software override.
		 */
		fccfg_reg |= TXGBE_TXFCCFG_FC;
		break;
	case txgbe_fc_full:
		/* Flow control (both Rx and Tx) is enabled by SW override. */
		mflcn_reg |= TXGBE_RXFCCFG_FC;
		fccfg_reg |= TXGBE_TXFCCFG_FC;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		err = TXGBE_ERR_CONFIG;
		goto out;
	}

	/* Set 802.3x based flow control settings. */
	wr32(hw, TXGBE_RXFCCFG, mflcn_reg);
	wr32(hw, TXGBE_TXFCCFG, fccfg_reg);

	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
	for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
		if ((hw->fc.current_mode & txgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			fcrtl = TXGBE_FCWTRLO_TH(hw->fc.low_water[i]) |
				TXGBE_FCWTRLO_XON;
			fcrth = TXGBE_FCWTRHI_TH(hw->fc.high_water[i]) |
				TXGBE_FCWTRHI_XOFF;
		} else {
			/*
			 * In order to prevent Tx hangs when the internal Tx
			 * switch is enabled we must set the high water mark
			 * to the Rx packet buffer size - 24KB.  This allows
			 * the Tx switch to function even under heavy Rx
			 * workloads.
			 */
			fcrtl = 0;
			fcrth = rd32(hw, TXGBE_PBRXSIZE(i)) - 24576;
		}
		wr32(hw, TXGBE_FCWTRLO(i), fcrtl);
		wr32(hw, TXGBE_FCWTRHI(i), fcrth);
	}

	/* Configure pause time (2 TCs per register) */
	pause_time = TXGBE_RXFCFSH_TIME(hw->fc.pause_time);
	for (i = 0; i < (TXGBE_DCB_TC_MAX / 2); i++)
		wr32(hw, TXGBE_FCXOFFTM(i), pause_time * 0x00010001);

	/* Configure flow control refresh threshold value */
	wr32(hw, TXGBE_RXFCRFSH, hw->fc.pause_time / 2);

out:
	return err;
}
/**
 *  txgbe_fc_enable - Enable flow control
 *  @hw: pointer to hardware structure
 *
 *  Enable flow control according to the current settings.
 **/
Enable flow control
@hw: pointer to hardware structure

Enable flow control according to the current settings.
Enable flow control @hw : pointer to hardware structure Enable flow control according to the current settings .
s32 txgbe_fc_enable(struct txgbe_hw *hw)
{
	s32 err = 0;
	u32 mflcn_reg, fccfg_reg;
	u32 pause_time;
	u32 fcrtl, fcrth;
	int i;
	DEBUGFUNC("txgbe_fc_enable");
	if (!hw->fc.pause_time) {
		err = TXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
	}
	for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
		if ((hw->fc.current_mode & txgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			if (!hw->fc.low_water[i] ||
			    hw->fc.low_water[i] >= hw->fc.high_water[i]) {
				DEBUGOUT("Invalid water mark configuration\n");
				err = TXGBE_ERR_INVALID_LINK_SETTINGS;
				goto out;
			}
		}
	}
	hw->mac.fc_autoneg(hw);
	mflcn_reg = rd32(hw, TXGBE_RXFCCFG);
	mflcn_reg &= ~(TXGBE_RXFCCFG_FC | TXGBE_RXFCCFG_PFC);
	fccfg_reg = rd32(hw, TXGBE_TXFCCFG);
	fccfg_reg &= ~(TXGBE_TXFCCFG_FC | TXGBE_TXFCCFG_PFC);
	switch (hw->fc.current_mode) {
	case txgbe_fc_none:
		break;
	case txgbe_fc_rx_pause:
		mflcn_reg |= TXGBE_RXFCCFG_FC;
		break;
	case txgbe_fc_tx_pause:
		fccfg_reg |= TXGBE_TXFCCFG_FC;
		break;
	case txgbe_fc_full:
		mflcn_reg |= TXGBE_RXFCCFG_FC;
		fccfg_reg |= TXGBE_TXFCCFG_FC;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		err = TXGBE_ERR_CONFIG;
		goto out;
	}
	wr32(hw, TXGBE_RXFCCFG, mflcn_reg);
	wr32(hw, TXGBE_TXFCCFG, fccfg_reg);
	for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
		if ((hw->fc.current_mode & txgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			fcrtl = TXGBE_FCWTRLO_TH(hw->fc.low_water[i]) |
				TXGBE_FCWTRLO_XON;
			fcrth = TXGBE_FCWTRHI_TH(hw->fc.high_water[i]) |
				TXGBE_FCWTRHI_XOFF;
		} else {
			fcrtl = 0;
			fcrth = rd32(hw, TXGBE_PBRXSIZE(i)) - 24576;
		}
		wr32(hw, TXGBE_FCWTRLO(i), fcrtl);
		wr32(hw, TXGBE_FCWTRHI(i), fcrth);
	}
	pause_time = TXGBE_RXFCFSH_TIME(hw->fc.pause_time);
	for (i = 0; i < (TXGBE_DCB_TC_MAX / 2); i++)
		wr32(hw, TXGBE_FCXOFFTM(i), pause_time * 0x00010001);
	wr32(hw, TXGBE_RXFCRFSH, hw->fc.pause_time / 2);
out:
	return err;
}
s32 txgbe_fc_enable ( struct txgbe_hw * hw ) { s32 err = 0 ; u32 mflcn_reg , fccfg_reg ; u32 pause_time ; u32 fcrtl , fcrth ; int i ; DEBUGFUNC ( " " ) ; if ( ! hw -> fc . pause_time ) { err = TXGBE_ERR_INVALID_LINK_SETTINGS ; goto out ; } for ( i = 0 ; i < TXGBE_DCB_TC_MAX ; i ++ ) { if ( ( hw -> fc . current_mode & txgbe_fc_tx_pause ) && hw -> fc . high_water [ i ] ) { if ( ! hw -> fc . low_water [ i ] || hw -> fc . low_water [ i ] >= hw -> fc . high_water [ i ] ) { DEBUGOUT ( " \n " ) ; err = TXGBE_ERR_INVALID_LINK_SETTINGS ; goto out ; } } } hw -> mac . fc_autoneg ( hw ) ; mflcn_reg = rd32 ( hw , TXGBE_RXFCCFG ) ; mflcn_reg &= ~ ( TXGBE_RXFCCFG_FC | TXGBE_RXFCCFG_PFC ) ; fccfg_reg = rd32 ( hw , TXGBE_TXFCCFG ) ; fccfg_reg &= ~ ( TXGBE_TXFCCFG_FC | TXGBE_TXFCCFG_PFC ) ; switch ( hw -> fc . current_mode ) { case txgbe_fc_none : break ; case txgbe_fc_rx_pause : mflcn_reg |= TXGBE_RXFCCFG_FC ; break ; case txgbe_fc_tx_pause : fccfg_reg |= TXGBE_TXFCCFG_FC ; break ; case txgbe_fc_full : mflcn_reg |= TXGBE_RXFCCFG_FC ; fccfg_reg |= TXGBE_TXFCCFG_FC ; break ; default : DEBUGOUT ( " \n " ) ; err = TXGBE_ERR_CONFIG ; goto out ; } wr32 ( hw , TXGBE_RXFCCFG , mflcn_reg ) ; wr32 ( hw , TXGBE_TXFCCFG , fccfg_reg ) ; for ( i = 0 ; i < TXGBE_DCB_TC_MAX ; i ++ ) { if ( ( hw -> fc . current_mode & txgbe_fc_tx_pause ) && hw -> fc . high_water [ i ] ) { fcrtl = TXGBE_FCWTRLO_TH ( hw -> fc . low_water [ i ] ) | TXGBE_FCWTRLO_XON ; fcrth = TXGBE_FCWTRHI_TH ( hw -> fc . high_water [ i ] ) | TXGBE_FCWTRHI_XOFF ; } else { fcrtl = 0 ; fcrth = rd32 ( hw , TXGBE_PBRXSIZE ( i ) ) - 24576 ; } wr32 ( hw , TXGBE_FCWTRLO ( i ) , fcrtl ) ; wr32 ( hw , TXGBE_FCWTRHI ( i ) , fcrth ) ; } pause_time = TXGBE_RXFCFSH_TIME ( hw -> fc . pause_time ) ; for ( i = 0 ; i < ( TXGBE_DCB_TC_MAX / 2 ) ; i ++ ) wr32 ( hw , TXGBE_FCXOFFTM ( i ) , pause_time * 0x00010001 ) ; wr32 ( hw , TXGBE_RXFCRFSH , hw -> fc . pause_time / 2 ) ; out : return err ; }
txgbe_fc_enable - Enable flow control
  @hw: pointer to hardware structure
txgbe_fc_enable - Enable flow control @hw : pointer to hardware structure
/* Validate the water mark configuration */ /* Low water mark of zero causes XOFF floods */ /* Negotiate the fc mode to use */ /* Disable any previous flow control settings */ /*
	 * The possible values of fc.current_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 is disabled by software override or autoneg.
		 * The code below will actually disable it in the HW.
		 */ /*
		 * 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.  Later, we will
		 * disable the adapter's ability to send PAUSE frames.
		 */ /*
		 * Tx Flow control is enabled, and Rx Flow control is
		 * disabled by software override.
		 */ /* Flow control (both Rx and Tx) is enabled by SW override. */ /* Set 802.3x based flow control settings. */ /* Set up and enable Rx high/low water mark thresholds, enable XON. */ /*
			 * In order to prevent Tx hangs when the internal Tx
			 * switch is enabled we must set the high water mark
			 * to the Rx packet buffer size - 24KB.  This allows
			 * the Tx switch to function even under heavy Rx
			 * workloads.
			 */ /* Configure pause time (2 TCs per register) */ /* Configure flow control refresh threshold value */