src/dpdk/drivers/net/ixgbe/base/ixgbe_82598.c
s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
{
	s32 ret_val = IXGBE_SUCCESS;
	u32 fctrl_reg;
	u32 rmcs_reg;
	u32 reg;
	u32 fcrtl, fcrth;
	u32 link_speed = 0;
	int i;
	bool link_up;

	DEBUGFUNC("ixgbe_fc_enable_82598");

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

	/* Low water mark of zero causes XOFF floods */
	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
		if ((hw->fc.current_mode & ixgbe_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");
				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
				goto out;
			}
		}
	}

	/*
	 * On 82598 having Rx FC on causes resets while doing 1G
	 * so if it's on turn it off once we know link_speed. For
	 * more details see 82598 Specification update.
	 */
	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
		switch (hw->fc.requested_mode) {
		case ixgbe_fc_full:
			hw->fc.requested_mode = ixgbe_fc_tx_pause;
			break;
		case ixgbe_fc_rx_pause:
			hw->fc.requested_mode = ixgbe_fc_none;
			break;
		default:
			/* no change */
			break;
		}
	}

	/* Negotiate the fc mode to use */
	ixgbe_fc_autoneg(hw);

	/* Disable any previous flow control settings */
	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);

	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);

	/*
	 * 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 ixgbe_fc_none:
		/*
		 * Flow control is disabled by software override or autoneg.
		 * The code below will actually disable it in the HW.
		 */
		break;
	case ixgbe_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.
		 */
		fctrl_reg |= IXGBE_FCTRL_RFCE;
		break;
	case ixgbe_fc_tx_pause:
		/*
		 * Tx Flow control is enabled, and Rx Flow control is
		 * disabled by software override.
		 */
		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
		break;
	case ixgbe_fc_full:
		/* Flow control (both Rx and Tx) is enabled by SW override. */
		fctrl_reg |= IXGBE_FCTRL_RFCE;
		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		ret_val = IXGBE_ERR_CONFIG;
		goto out;
		break;
	}

	/* Set 802.3x based flow control settings. */
	fctrl_reg |= IXGBE_FCTRL_DPF;
	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);

	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
		} else {
			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
		}

	}

	/* Configure pause time (2 TCs per register) */
	reg = hw->fc.pause_time * 0x00010001;
	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);

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

out:
	return ret_val;
}
/**
 * ixgbe_fc_enable_82598 - 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 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
{
	s32 ret_val = IXGBE_SUCCESS;
	u32 fctrl_reg;
	u32 rmcs_reg;
	u32 reg;
	u32 fcrtl, fcrth;
	u32 link_speed = 0;
	int i;
	bool link_up;
	DEBUGFUNC("ixgbe_fc_enable_82598");
	if (!hw->fc.pause_time) {
		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
	}
	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
		if ((hw->fc.current_mode & ixgbe_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");
				ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
				goto out;
			}
		}
	}
	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
	if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
		switch (hw->fc.requested_mode) {
		case ixgbe_fc_full:
			hw->fc.requested_mode = ixgbe_fc_tx_pause;
			break;
		case ixgbe_fc_rx_pause:
			hw->fc.requested_mode = ixgbe_fc_none;
			break;
		default:
			break;
		}
	}
	ixgbe_fc_autoneg(hw);
	fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
	fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
	rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
	rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
	switch (hw->fc.current_mode) {
	case ixgbe_fc_none:
		break;
	case ixgbe_fc_rx_pause:
		fctrl_reg |= IXGBE_FCTRL_RFCE;
		break;
	case ixgbe_fc_tx_pause:
		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
		break;
	case ixgbe_fc_full:
		fctrl_reg |= IXGBE_FCTRL_RFCE;
		rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
		break;
	default:
		DEBUGOUT("Flow control param set incorrectly\n");
		ret_val = IXGBE_ERR_CONFIG;
		goto out;
		break;
	}
	fctrl_reg |= IXGBE_FCTRL_DPF;
	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
	IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
		if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
		    hw->fc.high_water[i]) {
			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
			fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
		} else {
			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
		}
	}
	reg = hw->fc.pause_time * 0x00010001;
	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
out:
	return ret_val;
}
s32 ixgbe_fc_enable_82598 ( struct ixgbe_hw * hw ) { s32 ret_val = IXGBE_SUCCESS ; u32 fctrl_reg ; u32 rmcs_reg ; u32 reg ; u32 fcrtl , fcrth ; u32 link_speed = 0 ; int i ; bool link_up ; DEBUGFUNC ( " " ) ; if ( ! hw -> fc . pause_time ) { ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS ; goto out ; } for ( i = 0 ; i < IXGBE_DCB_MAX_TRAFFIC_CLASS ; i ++ ) { if ( ( hw -> fc . current_mode & ixgbe_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 " ) ; ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS ; goto out ; } } } hw -> mac . ops . check_link ( hw , & link_speed , & link_up , false ) ; if ( link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL ) { switch ( hw -> fc . requested_mode ) { case ixgbe_fc_full : hw -> fc . requested_mode = ixgbe_fc_tx_pause ; break ; case ixgbe_fc_rx_pause : hw -> fc . requested_mode = ixgbe_fc_none ; break ; default : break ; } } ixgbe_fc_autoneg ( hw ) ; fctrl_reg = IXGBE_READ_REG ( hw , IXGBE_FCTRL ) ; fctrl_reg &= ~ ( IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE ) ; rmcs_reg = IXGBE_READ_REG ( hw , IXGBE_RMCS ) ; rmcs_reg &= ~ ( IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X ) ; switch ( hw -> fc . current_mode ) { case ixgbe_fc_none : break ; case ixgbe_fc_rx_pause : fctrl_reg |= IXGBE_FCTRL_RFCE ; break ; case ixgbe_fc_tx_pause : rmcs_reg |= IXGBE_RMCS_TFCE_802_3X ; break ; case ixgbe_fc_full : fctrl_reg |= IXGBE_FCTRL_RFCE ; rmcs_reg |= IXGBE_RMCS_TFCE_802_3X ; break ; default : DEBUGOUT ( " \n " ) ; ret_val = IXGBE_ERR_CONFIG ; goto out ; break ; } fctrl_reg |= IXGBE_FCTRL_DPF ; IXGBE_WRITE_REG ( hw , IXGBE_FCTRL , fctrl_reg ) ; IXGBE_WRITE_REG ( hw , IXGBE_RMCS , rmcs_reg ) ; for ( i = 0 ; i < IXGBE_DCB_MAX_TRAFFIC_CLASS ; i ++ ) { if ( ( hw -> fc . current_mode & ixgbe_fc_tx_pause ) && hw -> fc . high_water [ i ] ) { fcrtl = ( hw -> fc . low_water [ i ] << 10 ) | IXGBE_FCRTL_XONE ; fcrth = ( hw -> fc . high_water [ i ] << 10 ) | IXGBE_FCRTH_FCEN ; IXGBE_WRITE_REG ( hw , IXGBE_FCRTL ( i ) , fcrtl ) ; IXGBE_WRITE_REG ( hw , IXGBE_FCRTH ( i ) , fcrth ) ; } else { IXGBE_WRITE_REG ( hw , IXGBE_FCRTL ( i ) , 0 ) ; IXGBE_WRITE_REG ( hw , IXGBE_FCRTH ( i ) , 0 ) ; } } reg = hw -> fc . pause_time * 0x00010001 ; for ( i = 0 ; i < ( IXGBE_DCB_MAX_TRAFFIC_CLASS / 2 ) ; i ++ ) IXGBE_WRITE_REG ( hw , IXGBE_FCTTV ( i ) , reg ) ; IXGBE_WRITE_REG ( hw , IXGBE_FCRTV , hw -> fc . pause_time / 2 ) ; out : return ret_val ; }
ixgbe_fc_enable_82598 - Enable flow control
 @hw: pointer to hardware structure
ixgbe_fc_enable_82598 - Enable flow control @hw : pointer to hardware structure
/* Validate the water mark configuration */ /* Low water mark of zero causes XOFF floods */ /*
	 * On 82598 having Rx FC on causes resets while doing 1G
	 * so if it's on turn it off once we know link_speed. For
	 * more details see 82598 Specification update.
	 */ /* no change */ /* 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. */ /* Configure pause time (2 TCs per register) */ /* Configure flow control refresh threshold value */