Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9da712d2 authored by John Fastabend's avatar John Fastabend Committed by Jeff Kirsher
Browse files

ixgbe: update {P}FC thresholds to account for X540 and loopback



Revise high and low threshold marks wrt flow control to account
for the X540 devices and latency introduced by the loopback
switch.

Without this it was in theory possible to drop frames on a
supposedly lossless link with X540 or SR-IOV enabled.

Previously we used a magic number in a define to calculate the
threshold values. This made it difficult to sort out exactly
which latencies were or were not being accounted for. Here
I was overly explicit and tried to used #define names that would
be recognizable after reading the IEEE 802.1Qbb specification.

Signed-off-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Tested-by: default avatarRoss Brattain <ross.b.brattain@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 934c18cc
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -358,7 +358,6 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
	u32 fctrl_reg;
	u32 rmcs_reg;
	u32 reg;
	u32 rx_pba_size;
	u32 link_speed = 0;
	bool link_up;

@@ -461,16 +460,13 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)

	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
		rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
		rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;

		reg = (rx_pba_size - hw->fc.low_water) << 6;
		reg = hw->fc.low_water << 6;
		if (hw->fc.send_xon)
			reg |= IXGBE_FCRTL_XONE;

		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);

		reg = (rx_pba_size - hw->fc.high_water) << 6;
		reg = hw->fc.high_water[packetbuf_num] << 6;
		reg |= IXGBE_FCRTH_FCEN;

		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
+5 −7
Original line number Diff line number Diff line
@@ -1932,7 +1932,6 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
	s32 ret_val = 0;
	u32 mflcn_reg, fccfg_reg;
	u32 reg;
	u32 rx_pba_size;
	u32 fcrtl, fcrth;

#ifdef CONFIG_DCB
@@ -2012,11 +2011,8 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);

	rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
	rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;

	fcrth = (rx_pba_size - hw->fc.high_water) << 10;
	fcrtl = (rx_pba_size - hw->fc.low_water) << 10;
	fcrth = hw->fc.high_water[packetbuf_num] << 10;
	fcrtl = hw->fc.low_water << 10;

	if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
		fcrth |= IXGBE_FCRTH_FCEN;
@@ -2293,7 +2289,9 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
	 * Validate the water mark configuration.  Zero water marks are invalid
	 * because it causes the controller to just blast out fc packets.
	 */
	if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
	if (!hw->fc.low_water ||
	    !hw->fc.high_water[packetbuf_num] ||
	    !hw->fc.pause_time) {
		hw_dbg(hw, "Invalid water mark configuration\n");
		ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
		goto out;
+0 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@

#define IXGBE_MAX_PACKET_BUFFERS 8
#define MAX_USER_PRIORITY        8
#define MAX_TRAFFIC_CLASS        8
#define MAX_BW_GROUP             8
#define BW_PERCENT               100

+4 −5
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
 */
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
{
	u32 reg, rx_pba_size;
	u32 reg;
	u8  i;

	if (pfc_en) {
@@ -222,9 +222,8 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
	 */
	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
		int enabled = pfc_en & (1 << i);
		rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
		rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
		reg = (rx_pba_size - hw->fc.low_water) << 10;

		reg = hw->fc.low_water << 10;

		if (enabled == pfc_enabled_tx ||
		    enabled == pfc_enabled_full)
@@ -232,7 +231,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)

		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);

		reg = (rx_pba_size - hw->fc.high_water) << 10;
		reg = hw->fc.high_water[i] << 10;
		if (enabled == pfc_enabled_tx ||
		    enabled == pfc_enabled_full)
			reg |= IXGBE_FCRTH_FCEN;
+3 −5
Original line number Diff line number Diff line
@@ -210,21 +210,19 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
 */
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
{
	u32 i, reg, rx_pba_size;
	u32 i, reg;

	/* Configure PFC Tx thresholds per TC */
	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
		int enabled = pfc_en & (1 << i);
		rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
		rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;

		reg = (rx_pba_size - hw->fc.low_water) << 10;
		reg = hw->fc.low_water << 10;

		if (enabled)
			reg |= IXGBE_FCRTL_XONE;
		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);

		reg = (rx_pba_size - hw->fc.high_water) << 10;
		reg = hw->fc.high_water[i] << 10;
		if (enabled)
			reg |= IXGBE_FCRTH_FCEN;
		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
Loading