1251964Sjfv/******************************************************************************
2251964Sjfv
3251964Sjfv  Copyright (c) 2001-2013, Intel Corporation
4251964Sjfv  All rights reserved.
5251964Sjfv
6251964Sjfv  Redistribution and use in source and binary forms, with or without
7251964Sjfv  modification, are permitted provided that the following conditions are met:
8251964Sjfv
9251964Sjfv   1. Redistributions of source code must retain the above copyright notice,
10251964Sjfv      this list of conditions and the following disclaimer.
11251964Sjfv
12251964Sjfv   2. Redistributions in binary form must reproduce the above copyright
13251964Sjfv      notice, this list of conditions and the following disclaimer in the
14251964Sjfv      documentation and/or other materials provided with the distribution.
15251964Sjfv
16251964Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17251964Sjfv      contributors may be used to endorse or promote products derived from
18251964Sjfv      this software without specific prior written permission.
19251964Sjfv
20251964Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21251964Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22251964Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23251964Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24251964Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25251964Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26251964Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27251964Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28251964Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29251964Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30251964Sjfv  POSSIBILITY OF SUCH DAMAGE.
31251964Sjfv
32251964Sjfv******************************************************************************/
33251964Sjfv/*$FreeBSD$*/
34251964Sjfv
35251964Sjfv
36251964Sjfv#include "ixgbe_type.h"
37251964Sjfv#include "ixgbe_dcb.h"
38251964Sjfv#include "ixgbe_dcb_82599.h"
39251964Sjfv
40251964Sjfv/**
41251964Sjfv * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
42251964Sjfv * @hw: pointer to hardware structure
43251964Sjfv * @stats: pointer to statistics structure
44251964Sjfv * @tc_count:  Number of elements in bwg_array.
45251964Sjfv *
46251964Sjfv * This function returns the status data for each of the Traffic Classes in use.
47251964Sjfv */
48251964Sjfvs32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
49251964Sjfv				 struct ixgbe_hw_stats *stats,
50251964Sjfv				 u8 tc_count)
51251964Sjfv{
52251964Sjfv	int tc;
53251964Sjfv
54251964Sjfv	DEBUGFUNC("dcb_get_tc_stats");
55251964Sjfv
56251964Sjfv	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
57251964Sjfv		return IXGBE_ERR_PARAM;
58251964Sjfv
59251964Sjfv	/* Statistics pertaining to each traffic class */
60251964Sjfv	for (tc = 0; tc < tc_count; tc++) {
61251964Sjfv		/* Transmitted Packets */
62251964Sjfv		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
63251964Sjfv		/* Transmitted Bytes (read low first to prevent missed carry) */
64251964Sjfv		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(tc));
65251964Sjfv		stats->qbtc[tc] +=
66251964Sjfv			(((u64)(IXGBE_READ_REG(hw, IXGBE_QBTC_H(tc)))) << 32);
67251964Sjfv		/* Received Packets */
68251964Sjfv		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
69251964Sjfv		/* Received Bytes (read low first to prevent missed carry) */
70251964Sjfv		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC_L(tc));
71251964Sjfv		stats->qbrc[tc] +=
72251964Sjfv			(((u64)(IXGBE_READ_REG(hw, IXGBE_QBRC_H(tc)))) << 32);
73251964Sjfv
74251964Sjfv		/* Received Dropped Packet */
75251964Sjfv		stats->qprdc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRDC(tc));
76251964Sjfv	}
77251964Sjfv
78251964Sjfv	return IXGBE_SUCCESS;
79251964Sjfv}
80251964Sjfv
81251964Sjfv/**
82251964Sjfv * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
83251964Sjfv * @hw: pointer to hardware structure
84251964Sjfv * @stats: pointer to statistics structure
85251964Sjfv * @tc_count:  Number of elements in bwg_array.
86251964Sjfv *
87251964Sjfv * This function returns the CBFC status data for each of the Traffic Classes.
88251964Sjfv */
89251964Sjfvs32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
90251964Sjfv				  struct ixgbe_hw_stats *stats,
91251964Sjfv				  u8 tc_count)
92251964Sjfv{
93251964Sjfv	int tc;
94251964Sjfv
95251964Sjfv	DEBUGFUNC("dcb_get_pfc_stats");
96251964Sjfv
97251964Sjfv	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
98251964Sjfv		return IXGBE_ERR_PARAM;
99251964Sjfv
100251964Sjfv	for (tc = 0; tc < tc_count; tc++) {
101251964Sjfv		/* Priority XOFF Transmitted */
102251964Sjfv		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
103251964Sjfv		/* Priority XOFF Received */
104251964Sjfv		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
105251964Sjfv	}
106251964Sjfv
107251964Sjfv	return IXGBE_SUCCESS;
108251964Sjfv}
109251964Sjfv
110251964Sjfv/**
111251964Sjfv * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
112251964Sjfv * @hw: pointer to hardware structure
113251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
114251964Sjfv *
115251964Sjfv * Configure Rx Packet Arbiter and credits for each traffic class.
116251964Sjfv */
117251964Sjfvs32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
118251964Sjfv				      u16 *max, u8 *bwg_id, u8 *tsa,
119251964Sjfv				      u8 *map)
120251964Sjfv{
121251964Sjfv	u32 reg = 0;
122251964Sjfv	u32 credit_refill = 0;
123251964Sjfv	u32 credit_max = 0;
124251964Sjfv	u8  i = 0;
125251964Sjfv
126251964Sjfv	/*
127251964Sjfv	 * Disable the arbiter before changing parameters
128251964Sjfv	 * (always enable recycle mode; WSP)
129251964Sjfv	 */
130251964Sjfv	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS;
131251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
132251964Sjfv
133251964Sjfv	/*
134251964Sjfv	 * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding
135251964Sjfv	 * bits sets for the UPs that needs to be mappped to that TC.
136251964Sjfv	 * e.g if priorities 6 and 7 are to be mapped to a TC then the
137251964Sjfv	 * up_to_tc_bitmap value for that TC will be 11000000 in binary.
138251964Sjfv	 */
139251964Sjfv	reg = 0;
140251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
141251964Sjfv		reg |= (map[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT));
142251964Sjfv
143251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
144251964Sjfv
145251964Sjfv	/* Configure traffic class credits and priority */
146251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
147251964Sjfv		credit_refill = refill[i];
148251964Sjfv		credit_max = max[i];
149251964Sjfv		reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
150251964Sjfv
151251964Sjfv		reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT;
152251964Sjfv
153251964Sjfv		if (tsa[i] == ixgbe_dcb_tsa_strict)
154251964Sjfv			reg |= IXGBE_RTRPT4C_LSP;
155251964Sjfv
156251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
157251964Sjfv	}
158251964Sjfv
159251964Sjfv	/*
160251964Sjfv	 * Configure Rx packet plane (recycle mode; WSP) and
161251964Sjfv	 * enable arbiter
162251964Sjfv	 */
163251964Sjfv	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
164251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
165251964Sjfv
166251964Sjfv	return IXGBE_SUCCESS;
167251964Sjfv}
168251964Sjfv
169251964Sjfv/**
170251964Sjfv * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
171251964Sjfv * @hw: pointer to hardware structure
172251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
173251964Sjfv *
174251964Sjfv * Configure Tx Descriptor Arbiter and credits for each traffic class.
175251964Sjfv */
176251964Sjfvs32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
177251964Sjfv					   u16 *max, u8 *bwg_id, u8 *tsa)
178251964Sjfv{
179251964Sjfv	u32 reg, max_credits;
180251964Sjfv	u8  i;
181251964Sjfv
182251964Sjfv	/* Clear the per-Tx queue credits; we use per-TC instead */
183251964Sjfv	for (i = 0; i < 128; i++) {
184251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
185251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
186251964Sjfv	}
187251964Sjfv
188251964Sjfv	/* Configure traffic class credits and priority */
189251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
190251964Sjfv		max_credits = max[i];
191251964Sjfv		reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
192251964Sjfv		reg |= refill[i];
193251964Sjfv		reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT;
194251964Sjfv
195251964Sjfv		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
196251964Sjfv			reg |= IXGBE_RTTDT2C_GSP;
197251964Sjfv
198251964Sjfv		if (tsa[i] == ixgbe_dcb_tsa_strict)
199251964Sjfv			reg |= IXGBE_RTTDT2C_LSP;
200251964Sjfv
201251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
202251964Sjfv	}
203251964Sjfv
204251964Sjfv	/*
205251964Sjfv	 * Configure Tx descriptor plane (recycle mode; WSP) and
206251964Sjfv	 * enable arbiter
207251964Sjfv	 */
208251964Sjfv	reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
209251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
210251964Sjfv
211251964Sjfv	return IXGBE_SUCCESS;
212251964Sjfv}
213251964Sjfv
214251964Sjfv/**
215251964Sjfv * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
216251964Sjfv * @hw: pointer to hardware structure
217251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
218251964Sjfv *
219251964Sjfv * Configure Tx Packet Arbiter and credits for each traffic class.
220251964Sjfv */
221251964Sjfvs32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u16 *refill,
222251964Sjfv					   u16 *max, u8 *bwg_id, u8 *tsa,
223251964Sjfv					   u8 *map)
224251964Sjfv{
225251964Sjfv	u32 reg;
226251964Sjfv	u8 i;
227251964Sjfv
228251964Sjfv	/*
229251964Sjfv	 * Disable the arbiter before changing parameters
230251964Sjfv	 * (always enable recycle mode; SP; arb delay)
231251964Sjfv	 */
232251964Sjfv	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
233251964Sjfv	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) |
234251964Sjfv	      IXGBE_RTTPCS_ARBDIS;
235251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
236251964Sjfv
237251964Sjfv	/*
238251964Sjfv	 * map all UPs to TCs. up_to_tc_bitmap for each TC has corresponding
239251964Sjfv	 * bits sets for the UPs that needs to be mappped to that TC.
240251964Sjfv	 * e.g if priorities 6 and 7 are to be mapped to a TC then the
241251964Sjfv	 * up_to_tc_bitmap value for that TC will be 11000000 in binary.
242251964Sjfv	 */
243251964Sjfv	reg = 0;
244251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++)
245251964Sjfv		reg |= (map[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT));
246251964Sjfv
247251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
248251964Sjfv
249251964Sjfv	/* Configure traffic class credits and priority */
250251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
251251964Sjfv		reg = refill[i];
252251964Sjfv		reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT;
253251964Sjfv		reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT;
254251964Sjfv
255251964Sjfv		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
256251964Sjfv			reg |= IXGBE_RTTPT2C_GSP;
257251964Sjfv
258251964Sjfv		if (tsa[i] == ixgbe_dcb_tsa_strict)
259251964Sjfv			reg |= IXGBE_RTTPT2C_LSP;
260251964Sjfv
261251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
262251964Sjfv	}
263251964Sjfv
264251964Sjfv	/*
265251964Sjfv	 * Configure Tx packet plane (recycle mode; SP; arb delay) and
266251964Sjfv	 * enable arbiter
267251964Sjfv	 */
268251964Sjfv	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
269251964Sjfv	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
270251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
271251964Sjfv
272251964Sjfv	return IXGBE_SUCCESS;
273251964Sjfv}
274251964Sjfv
275251964Sjfv/**
276251964Sjfv * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
277251964Sjfv * @hw: pointer to hardware structure
278251964Sjfv * @pfc_en: enabled pfc bitmask
279251964Sjfv * @map: priority to tc assignments indexed by priority
280251964Sjfv *
281251964Sjfv * Configure Priority Flow Control (PFC) for each traffic class.
282251964Sjfv */
283251964Sjfvs32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
284251964Sjfv{
285251964Sjfv	u32 i, j, fcrtl, reg;
286251964Sjfv	u8 max_tc = 0;
287251964Sjfv
288251964Sjfv	/* Enable Transmit Priority Flow Control */
289251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY);
290251964Sjfv
291251964Sjfv	/* Enable Receive Priority Flow Control */
292251964Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
293251964Sjfv	reg |= IXGBE_MFLCN_DPF;
294251964Sjfv
295251964Sjfv	/*
296251964Sjfv	 * X540 supports per TC Rx priority flow control.  So
297251964Sjfv	 * clear all TCs and only enable those that should be
298251964Sjfv	 * enabled.
299251964Sjfv	 */
300251964Sjfv	reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
301251964Sjfv
302251964Sjfv	if (hw->mac.type == ixgbe_mac_X540)
303251964Sjfv		reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
304251964Sjfv
305251964Sjfv	if (pfc_en)
306251964Sjfv		reg |= IXGBE_MFLCN_RPFCE;
307251964Sjfv
308251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
309251964Sjfv
310251964Sjfv	for (i = 0; i < IXGBE_DCB_MAX_USER_PRIORITY; i++) {
311251964Sjfv		if (map[i] > max_tc)
312251964Sjfv			max_tc = map[i];
313251964Sjfv	}
314251964Sjfv
315251964Sjfv
316251964Sjfv	/* Configure PFC Tx thresholds per TC */
317251964Sjfv	for (i = 0; i <= max_tc; i++) {
318251964Sjfv		int enabled = 0;
319251964Sjfv
320251964Sjfv		for (j = 0; j < IXGBE_DCB_MAX_USER_PRIORITY; j++) {
321251964Sjfv			if ((map[j] == i) && (pfc_en & (1 << j))) {
322251964Sjfv				enabled = 1;
323251964Sjfv				break;
324251964Sjfv			}
325251964Sjfv		}
326251964Sjfv
327251964Sjfv		if (enabled) {
328251964Sjfv			reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
329251964Sjfv			fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
330251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
331251964Sjfv		} else {
332251964Sjfv			reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
333251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
334251964Sjfv		}
335251964Sjfv
336251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
337251964Sjfv	}
338251964Sjfv
339251964Sjfv	for (; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
340251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
341251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
342251964Sjfv	}
343251964Sjfv
344251964Sjfv	/* Configure pause time (2 TCs per register) */
345251964Sjfv	reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
346251964Sjfv	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
347251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
348251964Sjfv
349251964Sjfv	/* Configure flow control refresh threshold value */
350251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
351251964Sjfv
352251964Sjfv	return IXGBE_SUCCESS;
353251964Sjfv}
354251964Sjfv
355251964Sjfv/**
356251964Sjfv * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
357251964Sjfv * @hw: pointer to hardware structure
358251964Sjfv *
359251964Sjfv * Configure queue statistics registers, all queues belonging to same traffic
360251964Sjfv * class uses a single set of queue statistics counters.
361251964Sjfv */
362251964Sjfvs32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw,
363251964Sjfv				    struct ixgbe_dcb_config *dcb_config)
364251964Sjfv{
365251964Sjfv	u32 reg = 0;
366251964Sjfv	u8  i   = 0;
367251964Sjfv	u8 tc_count = 8;
368251964Sjfv	bool vt_mode = FALSE;
369251964Sjfv
370251964Sjfv	if (dcb_config != NULL) {
371251964Sjfv		tc_count = dcb_config->num_tcs.pg_tcs;
372251964Sjfv		vt_mode = dcb_config->vt_mode;
373251964Sjfv	}
374251964Sjfv
375251964Sjfv	if (!((tc_count == 8 && vt_mode == FALSE) || tc_count == 4))
376251964Sjfv		return IXGBE_ERR_PARAM;
377251964Sjfv
378251964Sjfv	if (tc_count == 8 && vt_mode == FALSE) {
379251964Sjfv		/*
380251964Sjfv		 * Receive Queues stats setting
381251964Sjfv		 * 32 RQSMR registers, each configuring 4 queues.
382251964Sjfv		 *
383251964Sjfv		 * Set all 16 queues of each TC to the same stat
384251964Sjfv		 * with TC 'n' going to stat 'n'.
385251964Sjfv		 */
386251964Sjfv		for (i = 0; i < 32; i++) {
387251964Sjfv			reg = 0x01010101 * (i / 4);
388251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
389251964Sjfv		}
390251964Sjfv		/*
391251964Sjfv		 * Transmit Queues stats setting
392251964Sjfv		 * 32 TQSM registers, each controlling 4 queues.
393251964Sjfv		 *
394251964Sjfv		 * Set all queues of each TC to the same stat
395251964Sjfv		 * with TC 'n' going to stat 'n'.
396251964Sjfv		 * Tx queues are allocated non-uniformly to TCs:
397251964Sjfv		 * 32, 32, 16, 16, 8, 8, 8, 8.
398251964Sjfv		 */
399251964Sjfv		for (i = 0; i < 32; i++) {
400251964Sjfv			if (i < 8)
401251964Sjfv				reg = 0x00000000;
402251964Sjfv			else if (i < 16)
403251964Sjfv				reg = 0x01010101;
404251964Sjfv			else if (i < 20)
405251964Sjfv				reg = 0x02020202;
406251964Sjfv			else if (i < 24)
407251964Sjfv				reg = 0x03030303;
408251964Sjfv			else if (i < 26)
409251964Sjfv				reg = 0x04040404;
410251964Sjfv			else if (i < 28)
411251964Sjfv				reg = 0x05050505;
412251964Sjfv			else if (i < 30)
413251964Sjfv				reg = 0x06060606;
414251964Sjfv			else
415251964Sjfv				reg = 0x07070707;
416251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
417251964Sjfv		}
418251964Sjfv	} else if (tc_count == 4 && vt_mode == FALSE) {
419251964Sjfv		/*
420251964Sjfv		 * Receive Queues stats setting
421251964Sjfv		 * 32 RQSMR registers, each configuring 4 queues.
422251964Sjfv		 *
423251964Sjfv		 * Set all 16 queues of each TC to the same stat
424251964Sjfv		 * with TC 'n' going to stat 'n'.
425251964Sjfv		 */
426251964Sjfv		for (i = 0; i < 32; i++) {
427251964Sjfv			if (i % 8 > 3)
428251964Sjfv				/* In 4 TC mode, odd 16-queue ranges are
429251964Sjfv				 *  not used.
430251964Sjfv				*/
431251964Sjfv				continue;
432251964Sjfv			reg = 0x01010101 * (i / 8);
433251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
434251964Sjfv		}
435251964Sjfv		/*
436251964Sjfv		 * Transmit Queues stats setting
437251964Sjfv		 * 32 TQSM registers, each controlling 4 queues.
438251964Sjfv		 *
439251964Sjfv		 * Set all queues of each TC to the same stat
440251964Sjfv		 * with TC 'n' going to stat 'n'.
441251964Sjfv		 * Tx queues are allocated non-uniformly to TCs:
442251964Sjfv		 * 64, 32, 16, 16.
443251964Sjfv		 */
444251964Sjfv		for (i = 0; i < 32; i++) {
445251964Sjfv			if (i < 16)
446251964Sjfv				reg = 0x00000000;
447251964Sjfv			else if (i < 24)
448251964Sjfv				reg = 0x01010101;
449251964Sjfv			else if (i < 28)
450251964Sjfv				reg = 0x02020202;
451251964Sjfv			else
452251964Sjfv				reg = 0x03030303;
453251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
454251964Sjfv		}
455251964Sjfv	} else if (tc_count == 4 && vt_mode == TRUE) {
456251964Sjfv		/*
457251964Sjfv		 * Receive Queues stats setting
458251964Sjfv		 * 32 RQSMR registers, each configuring 4 queues.
459251964Sjfv		 *
460251964Sjfv		 * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each
461251964Sjfv		 * pool. Set all 32 queues of each TC across pools to the same
462251964Sjfv		 * stat with TC 'n' going to stat 'n'.
463251964Sjfv		 */
464251964Sjfv		for (i = 0; i < 32; i++)
465251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), 0x03020100);
466251964Sjfv		/*
467251964Sjfv		 * Transmit Queues stats setting
468251964Sjfv		 * 32 TQSM registers, each controlling 4 queues.
469251964Sjfv		 *
470251964Sjfv		 * Queue Indexing in 32 VF with DCB mode maps 4 TC's to each
471251964Sjfv		 * pool. Set all 32 queues of each TC across pools to the same
472251964Sjfv		 * stat with TC 'n' going to stat 'n'.
473251964Sjfv		 */
474251964Sjfv		for (i = 0; i < 32; i++)
475251964Sjfv			IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), 0x03020100);
476251964Sjfv	}
477251964Sjfv
478251964Sjfv	return IXGBE_SUCCESS;
479251964Sjfv}
480251964Sjfv
481251964Sjfv/**
482251964Sjfv * ixgbe_dcb_config_82599 - Configure general DCB parameters
483251964Sjfv * @hw: pointer to hardware structure
484251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
485251964Sjfv *
486251964Sjfv * Configure general DCB parameters.
487251964Sjfv */
488251964Sjfvs32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw,
489251964Sjfv			   struct ixgbe_dcb_config *dcb_config)
490251964Sjfv{
491251964Sjfv	u32 reg;
492251964Sjfv	u32 q;
493251964Sjfv
494251964Sjfv	/* Disable the Tx desc arbiter so that MTQC can be changed */
495251964Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
496251964Sjfv	reg |= IXGBE_RTTDCS_ARBDIS;
497251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
498251964Sjfv
499251964Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
500251964Sjfv	if (dcb_config->num_tcs.pg_tcs == 8) {
501251964Sjfv		/* Enable DCB for Rx with 8 TCs */
502251964Sjfv		switch (reg & IXGBE_MRQC_MRQE_MASK) {
503251964Sjfv		case 0:
504251964Sjfv		case IXGBE_MRQC_RT4TCEN:
505251964Sjfv			/* RSS disabled cases */
506251964Sjfv			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
507251964Sjfv			      IXGBE_MRQC_RT8TCEN;
508251964Sjfv			break;
509251964Sjfv		case IXGBE_MRQC_RSSEN:
510251964Sjfv		case IXGBE_MRQC_RTRSS4TCEN:
511251964Sjfv			/* RSS enabled cases */
512251964Sjfv			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
513251964Sjfv			      IXGBE_MRQC_RTRSS8TCEN;
514251964Sjfv			break;
515251964Sjfv		default:
516251964Sjfv			/*
517251964Sjfv			 * Unsupported value, assume stale data,
518251964Sjfv			 * overwrite no RSS
519251964Sjfv			 */
520251964Sjfv			ASSERT(0);
521251964Sjfv			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
522251964Sjfv			      IXGBE_MRQC_RT8TCEN;
523251964Sjfv		}
524251964Sjfv	}
525251964Sjfv	if (dcb_config->num_tcs.pg_tcs == 4) {
526251964Sjfv		/* We support both VT-on and VT-off with 4 TCs. */
527251964Sjfv		if (dcb_config->vt_mode)
528251964Sjfv			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
529251964Sjfv			      IXGBE_MRQC_VMDQRT4TCEN;
530251964Sjfv		else
531251964Sjfv			reg = (reg & ~IXGBE_MRQC_MRQE_MASK) |
532251964Sjfv			      IXGBE_MRQC_RTRSS4TCEN;
533251964Sjfv	}
534251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
535251964Sjfv
536251964Sjfv	/* Enable DCB for Tx with 8 TCs */
537251964Sjfv	if (dcb_config->num_tcs.pg_tcs == 8)
538251964Sjfv		reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
539251964Sjfv	else {
540251964Sjfv		/* We support both VT-on and VT-off with 4 TCs. */
541251964Sjfv		reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_4TC_4TQ;
542251964Sjfv		if (dcb_config->vt_mode)
543251964Sjfv			reg |= IXGBE_MTQC_VT_ENA;
544251964Sjfv	}
545251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
546251964Sjfv
547251964Sjfv	/* Disable drop for all queues */
548251964Sjfv	for (q = 0; q < 128; q++)
549251964Sjfv		IXGBE_WRITE_REG(hw, IXGBE_QDE,
550251964Sjfv				(IXGBE_QDE_WRITE | (q << IXGBE_QDE_IDX_SHIFT)));
551251964Sjfv
552251964Sjfv	/* Enable the Tx desc arbiter */
553251964Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
554251964Sjfv	reg &= ~IXGBE_RTTDCS_ARBDIS;
555251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
556251964Sjfv
557251964Sjfv	/* Enable Security TX Buffer IFG for DCB */
558251964Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
559251964Sjfv	reg |= IXGBE_SECTX_DCB;
560251964Sjfv	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
561251964Sjfv
562251964Sjfv	return IXGBE_SUCCESS;
563251964Sjfv}
564251964Sjfv
565251964Sjfv/**
566251964Sjfv * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
567251964Sjfv * @hw: pointer to hardware structure
568251964Sjfv * @dcb_config: pointer to ixgbe_dcb_config structure
569251964Sjfv *
570251964Sjfv * Configure dcb settings and enable dcb mode.
571251964Sjfv */
572251964Sjfvs32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, int link_speed,
573251964Sjfv			      u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa,
574251964Sjfv			      u8 *map)
575251964Sjfv{
576251964Sjfv
577251964Sjfv	ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, tsa,
578251964Sjfv					  map);
579251964Sjfv	ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
580251964Sjfv					       tsa);
581251964Sjfv	ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
582251964Sjfv					       tsa, map);
583251964Sjfv
584251964Sjfv	return IXGBE_SUCCESS;
585251964Sjfv}
586251964Sjfv
587