ixgbe_dcb_82599.c revision 315333
136285Sbrian/******************************************************************************
236285Sbrian
336285Sbrian  Copyright (c) 2001-2017, Intel Corporation
436285Sbrian  All rights reserved.
536285Sbrian
636285Sbrian  Redistribution and use in source and binary forms, with or without
736285Sbrian  modification, are permitted provided that the following conditions are met:
836285Sbrian
936285Sbrian   1. Redistributions of source code must retain the above copyright notice,
1036285Sbrian      this list of conditions and the following disclaimer.
1136285Sbrian
1236285Sbrian   2. Redistributions in binary form must reproduce the above copyright
1336285Sbrian      notice, this list of conditions and the following disclaimer in the
1436285Sbrian      documentation and/or other materials provided with the distribution.
1536285Sbrian
1636285Sbrian   3. Neither the name of the Intel Corporation nor the names of its
1736285Sbrian      contributors may be used to endorse or promote products derived from
1836285Sbrian      this software without specific prior written permission.
1936285Sbrian
2036285Sbrian  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2136285Sbrian  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2236285Sbrian  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2336285Sbrian  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2436285Sbrian  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2536285Sbrian  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2650479Speter  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2736285Sbrian  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2836285Sbrian  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2943313Sbrian  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3036285Sbrian  POSSIBILITY OF SUCH DAMAGE.
3136285Sbrian
3236285Sbrian******************************************************************************/
3381634Sbrian/*$FreeBSD: stable/10/sys/dev/ixgbe/ixgbe_dcb_82599.c 315333 2017-03-15 21:20:17Z erj $*/
3436285Sbrian
3536285Sbrian
3636285Sbrian#include "ixgbe_type.h"
37102500Sbrian#include "ixgbe_dcb.h"
3836285Sbrian#include "ixgbe_dcb_82599.h"
3936285Sbrian
4036285Sbrian/**
4136285Sbrian * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
4236285Sbrian * @hw: pointer to hardware structure
4336285Sbrian * @stats: pointer to statistics structure
4446686Sbrian * @tc_count:  Number of elements in bwg_array.
4536285Sbrian *
4636285Sbrian * This function returns the status data for each of the Traffic Classes in use.
4736285Sbrian */
4836285Sbrians32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
4936285Sbrian				 struct ixgbe_hw_stats *stats,
5036285Sbrian				 u8 tc_count)
5136285Sbrian{
5236285Sbrian	int tc;
5363484Sbrian
5436285Sbrian	DEBUGFUNC("dcb_get_tc_stats");
5536285Sbrian
5636285Sbrian	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
5736285Sbrian		return IXGBE_ERR_PARAM;
5836285Sbrian
5936285Sbrian	/* Statistics pertaining to each traffic class */
6036285Sbrian	for (tc = 0; tc < tc_count; tc++) {
6181634Sbrian		/* Transmitted Packets */
6236285Sbrian		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
6336285Sbrian		/* Transmitted Bytes (read low first to prevent missed carry) */
6436285Sbrian		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(tc));
6543313Sbrian		stats->qbtc[tc] +=
6643313Sbrian			(((u64)(IXGBE_READ_REG(hw, IXGBE_QBTC_H(tc)))) << 32);
6743313Sbrian		/* Received Packets */
6881634Sbrian		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
6981634Sbrian		/* Received Bytes (read low first to prevent missed carry) */
7036285Sbrian		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(tc));
7136285Sbrian		stats->qbrc[tc] +=
7236285Sbrian			(((u64)(IXGBE_READ_REG(hw, IXGBE_QBRC_H(tc)))) << 32);
7336285Sbrian
7446686Sbrian		/* Received Dropped Packet */
7536285Sbrian		stats->qprdc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRDC(tc));
7636285Sbrian	}
7736285Sbrian
7838174Sbrian	return IXGBE_SUCCESS;
7936285Sbrian}
8036285Sbrian
8136285Sbrian/**
82134789Sbrian * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
83136375Sbrian * @hw: pointer to hardware structure
8436285Sbrian * @stats: pointer to statistics structure
8536285Sbrian * @tc_count:  Number of elements in bwg_array.
8636285Sbrian *
8736285Sbrian * This function returns the CBFC status data for each of the Traffic Classes.
8836285Sbrian */
8936285Sbrians32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
9044468Sbrian				  struct ixgbe_hw_stats *stats,
9136285Sbrian				  u8 tc_count)
9259084Sbrian{
9336285Sbrian	int tc;
9436285Sbrian
9544261Sbrian	DEBUGFUNC("dcb_get_pfc_stats");
9636285Sbrian
9736285Sbrian	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
9844261Sbrian		return IXGBE_ERR_PARAM;
9944261Sbrian
10044468Sbrian	for (tc = 0; tc < tc_count; tc++) {
10185362Sbrian		/* Priority XOFF Transmitted */
10285362Sbrian		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
10385362Sbrian		/* Priority XOFF Received */
10485362Sbrian		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
10585362Sbrian	}
10685362Sbrian
10785362Sbrian	return IXGBE_SUCCESS;
10885362Sbrian}
10985362Sbrian
11085362Sbrian/**
11144261Sbrian * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
11236285Sbrian * @hw: pointer to hardware structure
11336285Sbrian * @dcb_config: pointer to ixgbe_dcb_config structure
11436285Sbrian *
11536285Sbrian * Configure Rx Packet Arbiter and credits for each traffic class.
11636285Sbrian */
11736285Sbrians32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
11846686Sbrian				      u16 *max, u8 *bwg_id, u8 *tsa,
11946686Sbrian				      u8 *map)
12036285Sbrian{
12136285Sbrian	u32 reg = 0;
12236285Sbrian	u32 credit_refill = 0;
12336285Sbrian	u32 credit_max = 0;
12454055Sbrian	u8  i = 0;
12546686Sbrian
12636285Sbrian	/*
12736285Sbrian	 * Disable the arbiter before changing parameters
12838174Sbrian	 * (always enable recycle mode; WSP)
12938174Sbrian	 */
13038174Sbrian	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS;
13138174Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
13238174Sbrian
13338174Sbrian	/*
13438174Sbrian	 * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding
13538174Sbrian	 * bits sets for the UPs that needs to be mappped to that TC.
13644468Sbrian	 * e.g if priorities 6 and 7 are to be mapped to a TC then the
13744468Sbrian	 * up_to_tc_bitmap value for that TC will be 11000000 in binary.
13838174Sbrian	 */
13938174Sbrian	reg = 0;
14038174Sbrian	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
14138174Sbrian		reg |= (map[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT));
14238174Sbrian
14344468Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
14438174Sbrian
14538174Sbrian	/* Configure traffic class credits and priority */
14638174Sbrian	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
14738174Sbrian		credit_refill = refill[i];
14838174Sbrian		credit_max = max[i];
14952412Sbrian		reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
15052412Sbrian
15145385Sbrian		reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT;
15238174Sbrian
15336285Sbrian		if (tsa[i] == ixgbe_dcb_tsa_strict)
15444468Sbrian			reg |= IXGBE_RTRPT4C_LSP;
15536465Sbrian
15636285Sbrian		IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
15744468Sbrian	}
15844468Sbrian
15936285Sbrian	/*
16036285Sbrian	 * Configure Rx packet plane (recycle mode; WSP) and
16158455Sbrian	 * enable arbiter
16258455Sbrian	 */
16344468Sbrian	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
16436285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
16536285Sbrian
16652412Sbrian	return IXGBE_SUCCESS;
16752412Sbrian}
16845385Sbrian
16944468Sbrian/**
17036285Sbrian * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
17144468Sbrian * @hw: pointer to hardware structure
17244468Sbrian * @dcb_config: pointer to ixgbe_dcb_config structure
17336285Sbrian *
17459084Sbrian * Configure Tx Descriptor Arbiter and credits for each traffic class.
17559084Sbrian */
17659084Sbrians32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
17759084Sbrian					   u16 *max, u8 *bwg_id, u8 *tsa)
17836285Sbrian{
17936285Sbrian	u32 reg, max_credits;
18044468Sbrian	u8  i;
18136285Sbrian
18236285Sbrian	/* Clear the per-Tx queue credits; we use per-TC instead */
18359084Sbrian	for (i = 0; i < 128; i++) {
18436285Sbrian		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
18536285Sbrian		IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
18636285Sbrian	}
18736285Sbrian
18849472Sbrian	/* Configure traffic class credits and priority */
18936285Sbrian	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
19036285Sbrian		max_credits = max[i];
19136285Sbrian		reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
19236285Sbrian		reg |= refill[i];
19336285Sbrian		reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT;
19436285Sbrian
19536285Sbrian		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
19636285Sbrian			reg |= IXGBE_RTTDT2C_GSP;
19748003Sbrian
19848003Sbrian		if (tsa[i] == ixgbe_dcb_tsa_strict)
19936285Sbrian			reg |= IXGBE_RTTDT2C_LSP;
20036285Sbrian
20136285Sbrian		IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
20236285Sbrian	}
20336285Sbrian
20436285Sbrian	/*
20536285Sbrian	 * Configure Tx descriptor plane (recycle mode; WSP) and
20659084Sbrian	 * enable arbiter
20736285Sbrian	 */
20836285Sbrian	reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
20936285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
21036285Sbrian
21136285Sbrian	return IXGBE_SUCCESS;
21236285Sbrian}
21354055Sbrian
21452488Sbrian/**
21598243Sbrian * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
21644468Sbrian * @hw: pointer to hardware structure
21744468Sbrian * @dcb_config: pointer to ixgbe_dcb_config structure
21836285Sbrian *
21946686Sbrian * Configure Tx Packet Arbiter and credits for each traffic class.
22044468Sbrian */
22136285Sbrians32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
22298243Sbrian					   u16 *max, u8 *bwg_id, u8 *tsa,
22352488Sbrian					   u8 *map)
22454914Sbrian{
22554914Sbrian	u32 reg;
22636285Sbrian	u8 i;
22747061Sbrian
22836285Sbrian	/*
22936285Sbrian	 * Disable the arbiter before changing parameters
23046686Sbrian	 * (always enable recycle mode; SP; arb delay)
23136285Sbrian	 */
23236285Sbrian	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
23336285Sbrian	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) |
23444468Sbrian	      IXGBE_RTTPCS_ARBDIS;
23544468Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
23636285Sbrian
23736285Sbrian	/*
23891623Sbrian	 * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding
23936285Sbrian	 * bits sets for the UPs that needs to be mappped to that TC.
24036285Sbrian	 * e.g if priorities 6 and 7 are to be mapped to a TC then the
24136285Sbrian	 * up_to_tc_bitmap value for that TC will be 11000000 in binary.
24236285Sbrian	 */
24336285Sbrian	reg = 0;
24436285Sbrian	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
24536285Sbrian		reg |= (map[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT));
24636285Sbrian
24736285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
24836285Sbrian
24936285Sbrian	/* Configure traffic class credits and priority */
25036285Sbrian	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
25158028Sbrian		reg = refill[i];
25236285Sbrian		reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT;
25336285Sbrian		reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT;
25436285Sbrian
25536285Sbrian		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
25636285Sbrian			reg |= IXGBE_RTTPT2C_GSP;
25736285Sbrian
25836285Sbrian		if (tsa[i] == ixgbe_dcb_tsa_strict)
25936285Sbrian			reg |= IXGBE_RTTPT2C_LSP;
26053830Sbrian
26153830Sbrian		IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
26247863Sbrian	}
26336285Sbrian
26436465Sbrian	/*
26553830Sbrian	 * Configure Tx packet plane (recycle mode; SP; arb delay) and
26653830Sbrian	 * enable arbiter
26753830Sbrian	 */
26836285Sbrian	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
26936285Sbrian	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
27036285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
27136285Sbrian
272102413Scharnier	return IXGBE_SUCCESS;
27336285Sbrian}
27436285Sbrian
27544468Sbrian/**
27644468Sbrian * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
27744468Sbrian * @hw: pointer to hardware structure
278134789Sbrian * @pfc_en: enabled pfc bitmask
27938200Sbrian * @map: priority to tc assignments indexed by priority
28038200Sbrian *
28138200Sbrian * Configure Priority Flow Control (PFC) for each traffic class.
28236285Sbrian */
28336285Sbrians32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
28454914Sbrian{
28554914Sbrian	u32 i, j, fcrtl, reg;
28654914Sbrian	u8 max_tc = 0;
28754914Sbrian
28836465Sbrian	/* Enable Transmit Priority Flow Control */
28936285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY);
29036285Sbrian
29144468Sbrian	/* Enable Receive Priority Flow Control */
29236285Sbrian	reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
29336285Sbrian	reg |= IXGBE_MFLCN_DPF;
29451978Sbrian
29541830Sbrian	/*
29636285Sbrian	 * X540 supports per TC Rx priority flow control.  So
29736465Sbrian	 * clear all TCs and only enable those that should be
29836285Sbrian	 * enabled.
29946686Sbrian	 */
30044468Sbrian	reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
30136285Sbrian
30246686Sbrian	if (hw->mac.type >= ixgbe_mac_X540)
30336285Sbrian		reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
30436285Sbrian
30536465Sbrian	if (pfc_en)
30644468Sbrian		reg |= IXGBE_MFLCN_RPFCE;
30736285Sbrian
30836285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
30944468Sbrian
31038200Sbrian	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) {
31138200Sbrian		if (map[i] > max_tc)
31236285Sbrian			max_tc = map[i];
31336285Sbrian	}
31438200Sbrian
31544468Sbrian
31644468Sbrian	/* Configure PFC Tx thresholds per TC */
31744468Sbrian	for (i = 0; i <= max_tc; i++) {
31859084Sbrian		int enabled = 0;
31938200Sbrian
32044261Sbrian		for (j = 0; j < IXGBE_DCB_MAX_USER_PRIORITY; j++) {
32138200Sbrian			if ((map[j] == i) && (pfc_en & (1 << j))) {
32236285Sbrian				enabled = 1;
32336285Sbrian				break;
32436285Sbrian			}
32536285Sbrian		}
32649472Sbrian
32749472Sbrian		if (enabled) {
32849472Sbrian			reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
32949472Sbrian			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
33049472Sbrian			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
33149472Sbrian		} else {
33249472Sbrian			/*
33349472Sbrian			 * In order to prevent Tx hangs when the internal Tx
33451978Sbrian			 * switch is enabled we must set the high water mark
33551978Sbrian			 * to the Rx packet buffer size - 24KB.  This allows
33654914Sbrian			 * the Tx switch to function even under heavy Rx
33754914Sbrian			 * workloads.
33851978Sbrian			 */
33951978Sbrian			reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
34049472Sbrian			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
34149472Sbrian		}
34249472Sbrian
34349472Sbrian		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
34498243Sbrian	}
34551978Sbrian
34654914Sbrian	for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
34754914Sbrian		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
34853070Sbrian		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
34953070Sbrian	}
35051978Sbrian
35153070Sbrian	/* Configure pause time (2 TCs per register) */
35253070Sbrian	reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
35349472Sbrian	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
35449472Sbrian		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
35536285Sbrian
35636285Sbrian	/* Configure flow control refresh threshold value */
35752488Sbrian	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
35836285Sbrian
35936285Sbrian	return IXGBE_SUCCESS;
36036285Sbrian}
36136285Sbrian
36236285Sbrian/**
36336285Sbrian * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
36436285Sbrian * @hw: pointer to hardware structure
36536285Sbrian *
36636285Sbrian * Configure queue statistics registers, all queues belonging to same traffic
36736285Sbrian * class uses a single set of queue statistics counters.
36849472Sbrian */
36936285Sbrians32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw,
37052488Sbrian				    struct ixgbe_dcb_config *dcb_config)
37152488Sbrian{
37252488Sbrian	u32 reg = 0;
37354914Sbrian	u8  i   = 0;
37454914Sbrian	u8 tc_count = 8;
37552488Sbrian	bool vt_mode = FALSE;
37636285Sbrian
37742390Sbrian	if (dcb_config != NULL) {
37836285Sbrian		tc_count = dcb_config->num_tcs.pg_tcs;
37942905Sbrian		vt_mode = dcb_config->vt_mode;
38036285Sbrian	}
38136285Sbrian
38236285Sbrian	if (!((tc_count == 8 && vt_mode == FALSE) || tc_count == 4))
38336285Sbrian		return IXGBE_ERR_PARAM;
38436285Sbrian
38536285Sbrian	if (tc_count == 8 && vt_mode == FALSE) {
38636285Sbrian		/*
38736285Sbrian		 * Receive Queues stats setting
38836285Sbrian		 * 32 RQSMR registers, each configuring 4 queues.
38936285Sbrian		 *
39052488Sbrian		 * Set all 16 queues of each TC to the same stat
39136285Sbrian		 * with TC 'n' going to stat 'n'.
39236285Sbrian		 */
39352488Sbrian		for (i = 0; i < 32; i++) {
39454914Sbrian			reg = 0x01010101 * (i / 4);
39554914Sbrian			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
39636285Sbrian		}
39736285Sbrian		/*
39836285Sbrian		 * Transmit Queues stats setting
39936285Sbrian		 * 32 TQSM registers, each controlling 4 queues.
40036285Sbrian		 *
40136285Sbrian		 * Set all queues of each TC to the same stat
40236285Sbrian		 * with TC 'n' going to stat 'n'.
40336285Sbrian		 * Tx queues are allocated non-uniformly to TCs:
40436285Sbrian		 * 32, 32, 16, 16, 8, 8, 8, 8.
40538174Sbrian		 */
40636285Sbrian		for (i = 0; i < 32; i++) {
40743888Sbrian			if (i < 8)
40843888Sbrian				reg = 0x00000000;
40936285Sbrian			else if (i < 16)
41036285Sbrian				reg = 0x01010101;
41136285Sbrian			else if (i < 20)
41236285Sbrian				reg = 0x02020202;
41336285Sbrian			else if (i < 24)
41436285Sbrian				reg = 0x03030303;
41536285Sbrian			else if (i < 26)
41636285Sbrian				reg = 0x04040404;
41736285Sbrian			else if (i < 28)
41836285Sbrian				reg = 0x05050505;
41936285Sbrian			else if (i < 30)
42036285Sbrian				reg = 0x06060606;
42158028Sbrian			else
42236285Sbrian				reg = 0x07070707;
42336285Sbrian			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
42436285Sbrian		}
42536285Sbrian	} else if (tc_count == 4 && vt_mode == FALSE) {
42636285Sbrian		/*
42736285Sbrian		 * Receive Queues stats setting
42836285Sbrian		 * 32 RQSMR registers, each configuring 4 queues.
42936285Sbrian		 *
43036285Sbrian		 * Set all 16 queues of each TC to the same stat
43136285Sbrian		 * with TC 'n' going to stat 'n'.
43252488Sbrian		 */
43336285Sbrian		for (i = 0; i < 32; i++) {
43436285Sbrian			if (i % 8 > 3)
43536285Sbrian				/* In 4 TC mode, odd 16-queue ranges are
43636285Sbrian				 *  not used.
43736285Sbrian				*/
43836285Sbrian				continue;
43938174Sbrian			reg = 0x01010101 * (i / 8);
44036285Sbrian			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
44143888Sbrian		}
44243888Sbrian		/*
44336285Sbrian		 * Transmit Queues stats setting
44436285Sbrian		 * 32 TQSM registers, each controlling 4 queues.
44536285Sbrian		 *
44636285Sbrian		 * Set all queues of each TC to the same stat
44736285Sbrian		 * with TC 'n' going to stat 'n'.
44858028Sbrian		 * Tx queues are allocated non-uniformly to TCs:
44936285Sbrian		 * 64, 32, 16, 16.
45036285Sbrian		 */
45136285Sbrian		for (i = 0; i < 32; i++) {
45236285Sbrian			if (i < 16)
45336285Sbrian				reg = 0x00000000;
45436285Sbrian			else if (i < 24)
45536285Sbrian				reg = 0x01010101;
45636285Sbrian			else if (i < 28)
45736285Sbrian				reg = 0x02020202;
45836285Sbrian			else
45952488Sbrian				reg = 0x03030303;
46036285Sbrian			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
46136285Sbrian		}
46236285Sbrian	} else if (tc_count == 4 && vt_mode == TRUE) {
46336285Sbrian		/*
46436285Sbrian		 * Receive Queues stats setting
46536285Sbrian		 * 32 RQSMR registers, each configuring 4 queues.
46636285Sbrian		 *
46738174Sbrian		 * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each
46836285Sbrian		 * pool. Set all 32 queues of each TC across pools to the same
46943888Sbrian		 * stat with TC 'n' going to stat 'n'.
47043888Sbrian		 */
47143888Sbrian		for (i = 0; i < 32; i++)
47243888Sbrian			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), 0x03020100);
47336285Sbrian		/*
47436285Sbrian		 * Transmit Queues stats setting
47536285Sbrian		 * 32 TQSM registers, each controlling 4 queues.
47636285Sbrian		 *
47737141Sbrian		 * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each
47867912Sbrian		 * pool. Set all 32 queues of each TC across pools to the same
47967912Sbrian		 * stat with TC 'n' going to stat 'n'.
48036285Sbrian		 */
48136285Sbrian		for (i = 0; i < 32; i++)
48237141Sbrian			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), 0x03020100);
48336285Sbrian	}
48436285Sbrian
48536285Sbrian	return IXGBE_SUCCESS;
48636285Sbrian}
48736285Sbrian
48836285Sbrian/**
48936285Sbrian * ixgbe_dcb_config_82599 - Configure general DCB parameters
49036285Sbrian * @hw: pointer to hardware structure
49152488Sbrian * @dcb_config: pointer to ixgbe_dcb_config structure
49236285Sbrian *
49393418Sbrian * Configure general DCB parameters.
49493418Sbrian */
49593418Sbrians32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw,
49693418Sbrian			   struct ixgbe_dcb_config *dcb_config)
49736285Sbrian{
49836285Sbrian	u32 reg;
49936285Sbrian	u32 q;
50036285Sbrian
50136285Sbrian	/* Disable the Tx desc arbiter so that MTQC can be changed */
50238174Sbrian	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
50336285Sbrian	reg |= IXGBE_RTTDCS_ARBDIS;
50443888Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
50593418Sbrian
50693418Sbrian	reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
50793418Sbrian	if (dcb_config->num_tcs.pg_tcs == 8) {
50893418Sbrian		/* Enable DCB for Rx with 8 TCs */
50993418Sbrian		switch (reg & IXGBE_MRQC_MRQE_MASK) {
51093418Sbrian		case 0:
51193418Sbrian		case IXGBE_MRQC_RT4TCEN:
51243888Sbrian			/* RSS disabled cases */
51393418Sbrian			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
51493418Sbrian			      IXGBE_MRQC_RT8TCEN;
51593418Sbrian			break;
51693418Sbrian		case IXGBE_MRQC_RSSEN:
51793418Sbrian		case IXGBE_MRQC_RTRSS4TCEN:
51893418Sbrian			/* RSS enabled cases */
51993418Sbrian			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
52036285Sbrian			      IXGBE_MRQC_RTRSS8TCEN;
52136285Sbrian			break;
52237141Sbrian		default:
52337141Sbrian			/*
52436285Sbrian			 * Unsupported value, assume stale data,
52536285Sbrian			 * overwrite no RSS
52693418Sbrian			 */
52737007Sbrian			ASSERT(0);
52836285Sbrian			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
52971970Sbrian			      IXGBE_MRQC_RT8TCEN;
53036285Sbrian		}
53171970Sbrian	}
53271970Sbrian	if (dcb_config->num_tcs.pg_tcs == 4) {
53371970Sbrian		/* We support both VT-on and VT-off with 4 TCs. */
53471970Sbrian		if (dcb_config->vt_mode)
53571970Sbrian			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
53671970Sbrian			      IXGBE_MRQC_VMDQRT4TCEN;
53771970Sbrian		else
53871970Sbrian			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
53971970Sbrian			      IXGBE_MRQC_RTRSS4TCEN;
54047061Sbrian	}
54137007Sbrian	IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
54237007Sbrian
54346686Sbrian	/* Enable DCB for Tx with 8 TCs */
54436285Sbrian	if (dcb_config->num_tcs.pg_tcs == 8)
54552488Sbrian		reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
54652488Sbrian	else {
54754914Sbrian		/* We support both VT-on and VT-off with 4 TCs. */
54854914Sbrian		reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ;
54952488Sbrian		if (dcb_config->vt_mode)
55052488Sbrian			reg |= IXGBE_MTQC_VT_ENA;
55154914Sbrian	}
55254914Sbrian	IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
55352488Sbrian
55436285Sbrian	/* Disable drop for all queues */
55536285Sbrian	for (q = 0; q < 128; q++)
55636285Sbrian		IXGBE_WRITE_REG(hw, IXGBE_QDE,
55736285Sbrian				(IXGBE_QDE_WRITE | (q << IXGBE_QDE_IDX_SHIFT)));
55836285Sbrian
55936285Sbrian	/* Enable the Tx desc arbiter */
56036285Sbrian	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
56136285Sbrian	reg &= ~IXGBE_RTTDCS_ARBDIS;
56236285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
56336285Sbrian
56436285Sbrian	/* Enable Security TX Buffer IFG for DCB */
56536285Sbrian	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
56636285Sbrian	reg |= IXGBE_SECTX_DCB;
56736285Sbrian	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
56836285Sbrian
56936285Sbrian	return IXGBE_SUCCESS;
57036285Sbrian}
57136285Sbrian
57236285Sbrian/**
57336285Sbrian * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
57444106Sbrian * @hw: pointer to hardware structure
57536285Sbrian * @dcb_config: pointer to ixgbe_dcb_config structure
57636285Sbrian *
57743693Sbrian * Configure dcb settings and enable dcb mode.
57844106Sbrian */
57944106Sbrians32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, int link_speed,
58044106Sbrian			      u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa,
58145350Sbrian			      u8 *map)
58236285Sbrian{
58336285Sbrian	UNREFERENCED_1PARAMETER(link_speed);
58444106Sbrian
58544106Sbrian	ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, tsa,
58644106Sbrian					  map);
58743693Sbrian	ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
58844106Sbrian					       tsa);
58943693Sbrian	ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
59036285Sbrian					       tsa, map);
59136285Sbrian
59279165Sbrian	return IXGBE_SUCCESS;
59379165Sbrian}
59436285Sbrian
59536285Sbrian