1dc0cb1cdSDale Ghent /******************************************************************************
2*48ed61a7SRobert Mustacchi   SPDX-License-Identifier: BSD-3-Clause
3dc0cb1cdSDale Ghent 
4*48ed61a7SRobert Mustacchi   Copyright (c) 2001-2017, Intel Corporation
5dc0cb1cdSDale Ghent   All rights reserved.
6*48ed61a7SRobert Mustacchi 
7*48ed61a7SRobert Mustacchi   Redistribution and use in source and binary forms, with or without
8dc0cb1cdSDale Ghent   modification, are permitted provided that the following conditions are met:
9*48ed61a7SRobert Mustacchi 
10*48ed61a7SRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
11dc0cb1cdSDale Ghent       this list of conditions and the following disclaimer.
12*48ed61a7SRobert Mustacchi 
13*48ed61a7SRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
14*48ed61a7SRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
15dc0cb1cdSDale Ghent       documentation and/or other materials provided with the distribution.
16*48ed61a7SRobert Mustacchi 
17*48ed61a7SRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
18*48ed61a7SRobert Mustacchi       contributors may be used to endorse or promote products derived from
19dc0cb1cdSDale Ghent       this software without specific prior written permission.
20*48ed61a7SRobert Mustacchi 
21dc0cb1cdSDale Ghent   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22*48ed61a7SRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*48ed61a7SRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*48ed61a7SRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25*48ed61a7SRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26*48ed61a7SRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27*48ed61a7SRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*48ed61a7SRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29*48ed61a7SRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30dc0cb1cdSDale Ghent   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31dc0cb1cdSDale Ghent   POSSIBILITY OF SUCH DAMAGE.
32dc0cb1cdSDale Ghent 
33dc0cb1cdSDale Ghent ******************************************************************************/
34dc0cb1cdSDale Ghent /*$FreeBSD$*/
35dc0cb1cdSDale Ghent 
36dc0cb1cdSDale Ghent 
37dc0cb1cdSDale Ghent #include "ixgbe_type.h"
38dc0cb1cdSDale Ghent #include "ixgbe_dcb.h"
39dc0cb1cdSDale Ghent #include "ixgbe_dcb_82598.h"
40dc0cb1cdSDale Ghent #include "ixgbe_dcb_82599.h"
41dc0cb1cdSDale Ghent 
42dc0cb1cdSDale Ghent /**
43dc0cb1cdSDale Ghent  * ixgbe_dcb_calculate_tc_credits - This calculates the ieee traffic class
44dc0cb1cdSDale Ghent  * credits from the configured bandwidth percentages. Credits
45dc0cb1cdSDale Ghent  * are the smallest unit programmable into the underlying
46dc0cb1cdSDale Ghent  * hardware. The IEEE 802.1Qaz specification do not use bandwidth
47dc0cb1cdSDale Ghent  * groups so this is much simplified from the CEE case.
48*48ed61a7SRobert Mustacchi  * @bw: bandwidth index by traffic class
49*48ed61a7SRobert Mustacchi  * @refill: refill credits index by traffic class
50*48ed61a7SRobert Mustacchi  * @max: max credits by traffic class
51*48ed61a7SRobert Mustacchi  * @max_frame_size: maximum frame size
52dc0cb1cdSDale Ghent  */
ixgbe_dcb_calculate_tc_credits(u8 * bw,u16 * refill,u16 * max,int max_frame_size)53dc0cb1cdSDale Ghent s32 ixgbe_dcb_calculate_tc_credits(u8 *bw, u16 *refill, u16 *max,
54dc0cb1cdSDale Ghent 				   int max_frame_size)
55dc0cb1cdSDale Ghent {
56dc0cb1cdSDale Ghent 	int min_percent = 100;
57dc0cb1cdSDale Ghent 	int min_credit, multiplier;
58dc0cb1cdSDale Ghent 	int i;
59dc0cb1cdSDale Ghent 
60dc0cb1cdSDale Ghent 	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
61dc0cb1cdSDale Ghent 			IXGBE_DCB_CREDIT_QUANTUM;
62dc0cb1cdSDale Ghent 
63dc0cb1cdSDale Ghent 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
64dc0cb1cdSDale Ghent 		if (bw[i] < min_percent && bw[i])
65dc0cb1cdSDale Ghent 			min_percent = bw[i];
66dc0cb1cdSDale Ghent 	}
67dc0cb1cdSDale Ghent 
68dc0cb1cdSDale Ghent 	multiplier = (min_credit / min_percent) + 1;
69dc0cb1cdSDale Ghent 
70dc0cb1cdSDale Ghent 	/* Find out the hw credits for each TC */
71dc0cb1cdSDale Ghent 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
72dc0cb1cdSDale Ghent 		int val = min(bw[i] * multiplier, IXGBE_DCB_MAX_CREDIT_REFILL);
73dc0cb1cdSDale Ghent 
74dc0cb1cdSDale Ghent 		if (val < min_credit)
75dc0cb1cdSDale Ghent 			val = min_credit;
76dc0cb1cdSDale Ghent 		refill[i] = (u16)val;
77dc0cb1cdSDale Ghent 
78dc0cb1cdSDale Ghent 		max[i] = bw[i] ? (bw[i]*IXGBE_DCB_MAX_CREDIT)/100 : min_credit;
79dc0cb1cdSDale Ghent 	}
80dc0cb1cdSDale Ghent 
81dc0cb1cdSDale Ghent 	return 0;
82dc0cb1cdSDale Ghent }
83dc0cb1cdSDale Ghent 
84dc0cb1cdSDale Ghent /**
85dc0cb1cdSDale Ghent  * ixgbe_dcb_calculate_tc_credits_cee - Calculates traffic class credits
86*48ed61a7SRobert Mustacchi  * @hw: pointer to hardware structure
87*48ed61a7SRobert Mustacchi  * @dcb_config: Struct containing DCB settings
88*48ed61a7SRobert Mustacchi  * @max_frame_size: Maximum frame size
89*48ed61a7SRobert Mustacchi  * @direction: Configuring either Tx or Rx
90dc0cb1cdSDale Ghent  *
91dc0cb1cdSDale Ghent  * This function calculates the credits allocated to each traffic class.
92dc0cb1cdSDale Ghent  * It should be called only after the rules are checked by
93dc0cb1cdSDale Ghent  * ixgbe_dcb_check_config_cee().
94dc0cb1cdSDale Ghent  */
ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config,u32 max_frame_size,u8 direction)95dc0cb1cdSDale Ghent s32 ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw *hw,
96dc0cb1cdSDale Ghent 				   struct ixgbe_dcb_config *dcb_config,
97dc0cb1cdSDale Ghent 				   u32 max_frame_size, u8 direction)
98dc0cb1cdSDale Ghent {
99dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_path *p;
100dc0cb1cdSDale Ghent 	u32 min_multiplier	= 0;
101dc0cb1cdSDale Ghent 	u16 min_percent		= 100;
102dc0cb1cdSDale Ghent 	s32 ret_val =		IXGBE_SUCCESS;
103dc0cb1cdSDale Ghent 	/* Initialization values default for Tx settings */
104dc0cb1cdSDale Ghent 	u32 min_credit		= 0;
105dc0cb1cdSDale Ghent 	u32 credit_refill	= 0;
106dc0cb1cdSDale Ghent 	u32 credit_max		= 0;
107dc0cb1cdSDale Ghent 	u16 link_percentage	= 0;
108dc0cb1cdSDale Ghent 	u8  bw_percent		= 0;
109dc0cb1cdSDale Ghent 	u8  i;
110dc0cb1cdSDale Ghent 
111dc0cb1cdSDale Ghent 	if (dcb_config == NULL) {
112dc0cb1cdSDale Ghent 		ret_val = IXGBE_ERR_CONFIG;
113dc0cb1cdSDale Ghent 		goto out;
114dc0cb1cdSDale Ghent 	}
115dc0cb1cdSDale Ghent 
116dc0cb1cdSDale Ghent 	min_credit = ((max_frame_size / 2) + IXGBE_DCB_CREDIT_QUANTUM - 1) /
117dc0cb1cdSDale Ghent 		     IXGBE_DCB_CREDIT_QUANTUM;
118dc0cb1cdSDale Ghent 
119dc0cb1cdSDale Ghent 	/* Find smallest link percentage */
120dc0cb1cdSDale Ghent 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
121dc0cb1cdSDale Ghent 		p = &dcb_config->tc_config[i].path[direction];
122dc0cb1cdSDale Ghent 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
123dc0cb1cdSDale Ghent 		link_percentage = p->bwg_percent;
124dc0cb1cdSDale Ghent 
125dc0cb1cdSDale Ghent 		link_percentage = (link_percentage * bw_percent) / 100;
126dc0cb1cdSDale Ghent 
127dc0cb1cdSDale Ghent 		if (link_percentage && link_percentage < min_percent)
128dc0cb1cdSDale Ghent 			min_percent = link_percentage;
129dc0cb1cdSDale Ghent 	}
130dc0cb1cdSDale Ghent 
131dc0cb1cdSDale Ghent 	/*
132dc0cb1cdSDale Ghent 	 * The ratio between traffic classes will control the bandwidth
133dc0cb1cdSDale Ghent 	 * percentages seen on the wire. To calculate this ratio we use
134dc0cb1cdSDale Ghent 	 * a multiplier. It is required that the refill credits must be
135dc0cb1cdSDale Ghent 	 * larger than the max frame size so here we find the smallest
136dc0cb1cdSDale Ghent 	 * multiplier that will allow all bandwidth percentages to be
137dc0cb1cdSDale Ghent 	 * greater than the max frame size.
138dc0cb1cdSDale Ghent 	 */
139dc0cb1cdSDale Ghent 	min_multiplier = (min_credit / min_percent) + 1;
140dc0cb1cdSDale Ghent 
141dc0cb1cdSDale Ghent 	/* Find out the link percentage for each TC first */
142dc0cb1cdSDale Ghent 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
143dc0cb1cdSDale Ghent 		p = &dcb_config->tc_config[i].path[direction];
144dc0cb1cdSDale Ghent 		bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
145dc0cb1cdSDale Ghent 
146dc0cb1cdSDale Ghent 		link_percentage = p->bwg_percent;
147dc0cb1cdSDale Ghent 		/* Must be careful of integer division for very small nums */
148dc0cb1cdSDale Ghent 		link_percentage = (link_percentage * bw_percent) / 100;
149dc0cb1cdSDale Ghent 		if (p->bwg_percent > 0 && link_percentage == 0)
150dc0cb1cdSDale Ghent 			link_percentage = 1;
151dc0cb1cdSDale Ghent 
152dc0cb1cdSDale Ghent 		/* Save link_percentage for reference */
153dc0cb1cdSDale Ghent 		p->link_percent = (u8)link_percentage;
154dc0cb1cdSDale Ghent 
155dc0cb1cdSDale Ghent 		/* Calculate credit refill ratio using multiplier */
156dc0cb1cdSDale Ghent 		credit_refill = min(link_percentage * min_multiplier,
157dc0cb1cdSDale Ghent 				    (u32)IXGBE_DCB_MAX_CREDIT_REFILL);
158dc0cb1cdSDale Ghent 
159dc0cb1cdSDale Ghent 		/* Refill at least minimum credit */
160dc0cb1cdSDale Ghent 		if (credit_refill < min_credit)
161dc0cb1cdSDale Ghent 			credit_refill = min_credit;
162dc0cb1cdSDale Ghent 
163dc0cb1cdSDale Ghent 		p->data_credits_refill = (u16)credit_refill;
164dc0cb1cdSDale Ghent 
165dc0cb1cdSDale Ghent 		/* Calculate maximum credit for the TC */
166dc0cb1cdSDale Ghent 		credit_max = (link_percentage * IXGBE_DCB_MAX_CREDIT) / 100;
167dc0cb1cdSDale Ghent 
168dc0cb1cdSDale Ghent 		/*
169dc0cb1cdSDale Ghent 		 * Adjustment based on rule checking, if the percentage
170dc0cb1cdSDale Ghent 		 * of a TC is too small, the maximum credit may not be
171dc0cb1cdSDale Ghent 		 * enough to send out a jumbo frame in data plane arbitration.
172dc0cb1cdSDale Ghent 		 */
173dc0cb1cdSDale Ghent 		if (credit_max < min_credit)
174dc0cb1cdSDale Ghent 			credit_max = min_credit;
175dc0cb1cdSDale Ghent 
176dc0cb1cdSDale Ghent 		if (direction == IXGBE_DCB_TX_CONFIG) {
177dc0cb1cdSDale Ghent 			/*
178dc0cb1cdSDale Ghent 			 * Adjustment based on rule checking, if the
179dc0cb1cdSDale Ghent 			 * percentage of a TC is too small, the maximum
180dc0cb1cdSDale Ghent 			 * credit may not be enough to send out a TSO
181dc0cb1cdSDale Ghent 			 * packet in descriptor plane arbitration.
182dc0cb1cdSDale Ghent 			 */
183dc0cb1cdSDale Ghent 			if (credit_max && (credit_max <
184dc0cb1cdSDale Ghent 			    IXGBE_DCB_MIN_TSO_CREDIT)
185dc0cb1cdSDale Ghent 			    && (hw->mac.type == ixgbe_mac_82598EB))
186dc0cb1cdSDale Ghent 				credit_max = IXGBE_DCB_MIN_TSO_CREDIT;
187dc0cb1cdSDale Ghent 
188dc0cb1cdSDale Ghent 			dcb_config->tc_config[i].desc_credits_max =
189dc0cb1cdSDale Ghent 								(u16)credit_max;
190dc0cb1cdSDale Ghent 		}
191dc0cb1cdSDale Ghent 
192dc0cb1cdSDale Ghent 		p->data_credits_max = (u16)credit_max;
193dc0cb1cdSDale Ghent 	}
194dc0cb1cdSDale Ghent 
195dc0cb1cdSDale Ghent out:
196dc0cb1cdSDale Ghent 	return ret_val;
197dc0cb1cdSDale Ghent }
198dc0cb1cdSDale Ghent 
199dc0cb1cdSDale Ghent /**
200dc0cb1cdSDale Ghent  * ixgbe_dcb_unpack_pfc_cee - Unpack dcb_config PFC info
201dc0cb1cdSDale Ghent  * @cfg: dcb configuration to unpack into hardware consumable fields
202dc0cb1cdSDale Ghent  * @map: user priority to traffic class map
203dc0cb1cdSDale Ghent  * @pfc_up: u8 to store user priority PFC bitmask
204dc0cb1cdSDale Ghent  *
205dc0cb1cdSDale Ghent  * This unpacks the dcb configuration PFC info which is stored per
206dc0cb1cdSDale Ghent  * traffic class into a 8bit user priority bitmask that can be
207dc0cb1cdSDale Ghent  * consumed by hardware routines. The priority to tc map must be
208dc0cb1cdSDale Ghent  * updated before calling this routine to use current up-to maps.
209dc0cb1cdSDale Ghent  */
ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config * cfg,u8 * map,u8 * pfc_up)210dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config *cfg, u8 *map, u8 *pfc_up)
211dc0cb1cdSDale Ghent {
212dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
213dc0cb1cdSDale Ghent 	int up;
214dc0cb1cdSDale Ghent 
215dc0cb1cdSDale Ghent 	/*
216dc0cb1cdSDale Ghent 	 * If the TC for this user priority has PFC enabled then set the
217dc0cb1cdSDale Ghent 	 * matching bit in 'pfc_up' to reflect that PFC is enabled.
218dc0cb1cdSDale Ghent 	 */
219dc0cb1cdSDale Ghent 	for (*pfc_up = 0, up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++) {
220dc0cb1cdSDale Ghent 		if (tc_config[map[up]].pfc != ixgbe_dcb_pfc_disabled)
221dc0cb1cdSDale Ghent 			*pfc_up |= 1 << up;
222dc0cb1cdSDale Ghent 	}
223dc0cb1cdSDale Ghent }
224dc0cb1cdSDale Ghent 
ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config * cfg,int direction,u16 * refill)225dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config *cfg, int direction,
226dc0cb1cdSDale Ghent 			     u16 *refill)
227dc0cb1cdSDale Ghent {
228dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
229dc0cb1cdSDale Ghent 	int tc;
230dc0cb1cdSDale Ghent 
231dc0cb1cdSDale Ghent 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
232dc0cb1cdSDale Ghent 		refill[tc] = tc_config[tc].path[direction].data_credits_refill;
233dc0cb1cdSDale Ghent }
234dc0cb1cdSDale Ghent 
ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config * cfg,u16 * max)235dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config *cfg, u16 *max)
236dc0cb1cdSDale Ghent {
237dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
238dc0cb1cdSDale Ghent 	int tc;
239dc0cb1cdSDale Ghent 
240dc0cb1cdSDale Ghent 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
241dc0cb1cdSDale Ghent 		max[tc] = tc_config[tc].desc_credits_max;
242dc0cb1cdSDale Ghent }
243dc0cb1cdSDale Ghent 
ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * bwgid)244dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config *cfg, int direction,
245dc0cb1cdSDale Ghent 			    u8 *bwgid)
246dc0cb1cdSDale Ghent {
247dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
248dc0cb1cdSDale Ghent 	int tc;
249dc0cb1cdSDale Ghent 
250dc0cb1cdSDale Ghent 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
251dc0cb1cdSDale Ghent 		bwgid[tc] = tc_config[tc].path[direction].bwg_id;
252dc0cb1cdSDale Ghent }
253dc0cb1cdSDale Ghent 
ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * tsa)254dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config *cfg, int direction,
255dc0cb1cdSDale Ghent 			   u8 *tsa)
256dc0cb1cdSDale Ghent {
257dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
258dc0cb1cdSDale Ghent 	int tc;
259dc0cb1cdSDale Ghent 
260dc0cb1cdSDale Ghent 	for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++)
261dc0cb1cdSDale Ghent 		tsa[tc] = tc_config[tc].path[direction].tsa;
262dc0cb1cdSDale Ghent }
263dc0cb1cdSDale Ghent 
ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config * cfg,int direction,u8 up)264dc0cb1cdSDale Ghent u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
265dc0cb1cdSDale Ghent {
266dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_config *tc_config = &cfg->tc_config[0];
267dc0cb1cdSDale Ghent 	u8 prio_mask = 1 << up;
268dc0cb1cdSDale Ghent 	u8 tc = cfg->num_tcs.pg_tcs;
269dc0cb1cdSDale Ghent 
270dc0cb1cdSDale Ghent 	/* If tc is 0 then DCB is likely not enabled or supported */
271dc0cb1cdSDale Ghent 	if (!tc)
272dc0cb1cdSDale Ghent 		goto out;
273dc0cb1cdSDale Ghent 
274dc0cb1cdSDale Ghent 	/*
275dc0cb1cdSDale Ghent 	 * Test from maximum TC to 1 and report the first match we find.  If
276dc0cb1cdSDale Ghent 	 * we find no match we can assume that the TC is 0 since the TC must
277dc0cb1cdSDale Ghent 	 * be set for all user priorities
278dc0cb1cdSDale Ghent 	 */
279dc0cb1cdSDale Ghent 	for (tc--; tc; tc--) {
280dc0cb1cdSDale Ghent 		if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
281dc0cb1cdSDale Ghent 			break;
282dc0cb1cdSDale Ghent 	}
283dc0cb1cdSDale Ghent out:
284dc0cb1cdSDale Ghent 	return tc;
285dc0cb1cdSDale Ghent }
286dc0cb1cdSDale Ghent 
ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * map)287dc0cb1cdSDale Ghent void ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config *cfg, int direction,
288dc0cb1cdSDale Ghent 			      u8 *map)
289dc0cb1cdSDale Ghent {
290dc0cb1cdSDale Ghent 	u8 up;
291dc0cb1cdSDale Ghent 
292dc0cb1cdSDale Ghent 	for (up = 0; up < IXGBE_DCB_MAX_USER_PRIORITY; up++)
293dc0cb1cdSDale Ghent 		map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
294dc0cb1cdSDale Ghent }
295dc0cb1cdSDale Ghent 
296dc0cb1cdSDale Ghent /**
297dc0cb1cdSDale Ghent  * ixgbe_dcb_config - Struct containing DCB settings.
298dc0cb1cdSDale Ghent  * @dcb_config: Pointer to DCB config structure
299dc0cb1cdSDale Ghent  *
300dc0cb1cdSDale Ghent  * This function checks DCB rules for DCB settings.
301dc0cb1cdSDale Ghent  * The following rules are checked:
302dc0cb1cdSDale Ghent  * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%.
303dc0cb1cdSDale Ghent  * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth
304dc0cb1cdSDale Ghent  *    Group must total 100.
305dc0cb1cdSDale Ghent  * 3. A Traffic Class should not be set to both Link Strict Priority
306dc0cb1cdSDale Ghent  *    and Group Strict Priority.
307dc0cb1cdSDale Ghent  * 4. Link strict Bandwidth Groups can only have link strict traffic classes
308dc0cb1cdSDale Ghent  *    with zero bandwidth.
309dc0cb1cdSDale Ghent  */
ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config * dcb_config)310dc0cb1cdSDale Ghent s32 ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config *dcb_config)
311dc0cb1cdSDale Ghent {
312dc0cb1cdSDale Ghent 	struct ixgbe_dcb_tc_path *p;
313dc0cb1cdSDale Ghent 	s32 ret_val = IXGBE_SUCCESS;
314dc0cb1cdSDale Ghent 	u8 i, j, bw = 0, bw_id;
315dc0cb1cdSDale Ghent 	u8 bw_sum[2][IXGBE_DCB_MAX_BW_GROUP];
316dc0cb1cdSDale Ghent 	bool link_strict[2][IXGBE_DCB_MAX_BW_GROUP];
317dc0cb1cdSDale Ghent 
318dc0cb1cdSDale Ghent 	memset(bw_sum, 0, sizeof(bw_sum));
319dc0cb1cdSDale Ghent 	memset(link_strict, 0, sizeof(link_strict));
320dc0cb1cdSDale Ghent 
321dc0cb1cdSDale Ghent 	/* First Tx, then Rx */
322dc0cb1cdSDale Ghent 	for (i = 0; i < 2; i++) {
323dc0cb1cdSDale Ghent 		/* Check each traffic class for rule violation */
324dc0cb1cdSDale Ghent 		for (j = 0; j < IXGBE_DCB_MAX_TRAFFIC_CLASS; j++) {
325dc0cb1cdSDale Ghent 			p = &dcb_config->tc_config[j].path[i];
326dc0cb1cdSDale Ghent 
327dc0cb1cdSDale Ghent 			bw = p->bwg_percent;
328dc0cb1cdSDale Ghent 			bw_id = p->bwg_id;
329dc0cb1cdSDale Ghent 
330dc0cb1cdSDale Ghent 			if (bw_id >= IXGBE_DCB_MAX_BW_GROUP) {
331dc0cb1cdSDale Ghent 				ret_val = IXGBE_ERR_CONFIG;
332dc0cb1cdSDale Ghent 				goto err_config;
333dc0cb1cdSDale Ghent 			}
334dc0cb1cdSDale Ghent 			if (p->tsa == ixgbe_dcb_tsa_strict) {
335dc0cb1cdSDale Ghent 				link_strict[i][bw_id] = TRUE;
336dc0cb1cdSDale Ghent 				/* Link strict should have zero bandwidth */
337dc0cb1cdSDale Ghent 				if (bw) {
338dc0cb1cdSDale Ghent 					ret_val = IXGBE_ERR_CONFIG;
339dc0cb1cdSDale Ghent 					goto err_config;
340dc0cb1cdSDale Ghent 				}
341dc0cb1cdSDale Ghent 			} else if (!bw) {
342dc0cb1cdSDale Ghent 				/*
343dc0cb1cdSDale Ghent 				 * Traffic classes without link strict
344dc0cb1cdSDale Ghent 				 * should have non-zero bandwidth.
345dc0cb1cdSDale Ghent 				 */
346dc0cb1cdSDale Ghent 				ret_val = IXGBE_ERR_CONFIG;
347dc0cb1cdSDale Ghent 				goto err_config;
348dc0cb1cdSDale Ghent 			}
349dc0cb1cdSDale Ghent 			bw_sum[i][bw_id] += bw;
350dc0cb1cdSDale Ghent 		}
351dc0cb1cdSDale Ghent 
352dc0cb1cdSDale Ghent 		bw = 0;
353dc0cb1cdSDale Ghent 
354dc0cb1cdSDale Ghent 		/* Check each bandwidth group for rule violation */
355dc0cb1cdSDale Ghent 		for (j = 0; j < IXGBE_DCB_MAX_BW_GROUP; j++) {
356dc0cb1cdSDale Ghent 			bw += dcb_config->bw_percentage[i][j];
357dc0cb1cdSDale Ghent 			/*
358dc0cb1cdSDale Ghent 			 * Sum of bandwidth percentages of all traffic classes
359dc0cb1cdSDale Ghent 			 * within a Bandwidth Group must total 100 except for
360dc0cb1cdSDale Ghent 			 * link strict group (zero bandwidth).
361dc0cb1cdSDale Ghent 			 */
362dc0cb1cdSDale Ghent 			if (link_strict[i][j]) {
363dc0cb1cdSDale Ghent 				if (bw_sum[i][j]) {
364dc0cb1cdSDale Ghent 					/*
365dc0cb1cdSDale Ghent 					 * Link strict group should have zero
366dc0cb1cdSDale Ghent 					 * bandwidth.
367dc0cb1cdSDale Ghent 					 */
368dc0cb1cdSDale Ghent 					ret_val = IXGBE_ERR_CONFIG;
369dc0cb1cdSDale Ghent 					goto err_config;
370dc0cb1cdSDale Ghent 				}
371dc0cb1cdSDale Ghent 			} else if (bw_sum[i][j] != IXGBE_DCB_BW_PERCENT &&
372dc0cb1cdSDale Ghent 				   bw_sum[i][j] != 0) {
373dc0cb1cdSDale Ghent 				ret_val = IXGBE_ERR_CONFIG;
374dc0cb1cdSDale Ghent 				goto err_config;
375dc0cb1cdSDale Ghent 			}
376dc0cb1cdSDale Ghent 		}
377dc0cb1cdSDale Ghent 
378dc0cb1cdSDale Ghent 		if (bw != IXGBE_DCB_BW_PERCENT) {
379dc0cb1cdSDale Ghent 			ret_val = IXGBE_ERR_CONFIG;
380dc0cb1cdSDale Ghent 			goto err_config;
381dc0cb1cdSDale Ghent 		}
382dc0cb1cdSDale Ghent 	}
383dc0cb1cdSDale Ghent 
384dc0cb1cdSDale Ghent err_config:
385dc0cb1cdSDale Ghent 	DEBUGOUT2("DCB error code %d while checking %s settings.\n",
386dc0cb1cdSDale Ghent 		  ret_val, (i == IXGBE_DCB_TX_CONFIG) ? "Tx" : "Rx");
387dc0cb1cdSDale Ghent 
388dc0cb1cdSDale Ghent 	return ret_val;
389dc0cb1cdSDale Ghent }
390dc0cb1cdSDale Ghent 
391dc0cb1cdSDale Ghent /**
392dc0cb1cdSDale Ghent  * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
393dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
394dc0cb1cdSDale Ghent  * @stats: pointer to statistics structure
395dc0cb1cdSDale Ghent  * @tc_count:  Number of elements in bwg_array.
396dc0cb1cdSDale Ghent  *
397dc0cb1cdSDale Ghent  * This function returns the status data for each of the Traffic Classes in use.
398dc0cb1cdSDale Ghent  */
ixgbe_dcb_get_tc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)399dc0cb1cdSDale Ghent s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
400dc0cb1cdSDale Ghent 			   u8 tc_count)
401dc0cb1cdSDale Ghent {
402dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
403dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
404dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
405dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
406dc0cb1cdSDale Ghent 		break;
407dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
408dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
409dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
410dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
411*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
412dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
413dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
414dc0cb1cdSDale Ghent 		break;
415dc0cb1cdSDale Ghent #endif
416dc0cb1cdSDale Ghent 	default:
417dc0cb1cdSDale Ghent 		break;
418dc0cb1cdSDale Ghent 	}
419dc0cb1cdSDale Ghent 	return ret;
420dc0cb1cdSDale Ghent }
421dc0cb1cdSDale Ghent 
422dc0cb1cdSDale Ghent /**
423dc0cb1cdSDale Ghent  * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class
424dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
425dc0cb1cdSDale Ghent  * @stats: pointer to statistics structure
426dc0cb1cdSDale Ghent  * @tc_count:  Number of elements in bwg_array.
427dc0cb1cdSDale Ghent  *
428dc0cb1cdSDale Ghent  * This function returns the CBFC status data for each of the Traffic Classes.
429dc0cb1cdSDale Ghent  */
ixgbe_dcb_get_pfc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)430dc0cb1cdSDale Ghent s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
431dc0cb1cdSDale Ghent 			    u8 tc_count)
432dc0cb1cdSDale Ghent {
433dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
434dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
435dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
436dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
437dc0cb1cdSDale Ghent 		break;
438dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
439dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
440dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
441dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
442*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
443dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
444dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
445dc0cb1cdSDale Ghent 		break;
446dc0cb1cdSDale Ghent #endif
447dc0cb1cdSDale Ghent 	default:
448dc0cb1cdSDale Ghent 		break;
449dc0cb1cdSDale Ghent 	}
450dc0cb1cdSDale Ghent 	return ret;
451dc0cb1cdSDale Ghent }
452dc0cb1cdSDale Ghent 
453dc0cb1cdSDale Ghent /**
454dc0cb1cdSDale Ghent  * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
455dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
456dc0cb1cdSDale Ghent  * @dcb_config: pointer to ixgbe_dcb_config structure
457dc0cb1cdSDale Ghent  *
458dc0cb1cdSDale Ghent  * Configure Rx Data Arbiter and credits for each traffic class.
459dc0cb1cdSDale Ghent  */
ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)460dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
461dc0cb1cdSDale Ghent 				struct ixgbe_dcb_config *dcb_config)
462dc0cb1cdSDale Ghent {
463dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
464dc0cb1cdSDale Ghent 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
465dc0cb1cdSDale Ghent 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
466dc0cb1cdSDale Ghent 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY]	= { 0 };
467dc0cb1cdSDale Ghent 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
468dc0cb1cdSDale Ghent 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
469dc0cb1cdSDale Ghent 
470dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
471dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
472dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
473dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
474dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
475dc0cb1cdSDale Ghent 
476dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
477dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
478dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
479dc0cb1cdSDale Ghent 		break;
480dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
481dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
482dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
483dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
484*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
485dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
486dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
487dc0cb1cdSDale Ghent 							tsa, map);
488dc0cb1cdSDale Ghent 		break;
489dc0cb1cdSDale Ghent #endif
490dc0cb1cdSDale Ghent 	default:
491dc0cb1cdSDale Ghent 		break;
492dc0cb1cdSDale Ghent 	}
493dc0cb1cdSDale Ghent 	return ret;
494dc0cb1cdSDale Ghent }
495dc0cb1cdSDale Ghent 
496dc0cb1cdSDale Ghent /**
497dc0cb1cdSDale Ghent  * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter
498dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
499dc0cb1cdSDale Ghent  * @dcb_config: pointer to ixgbe_dcb_config structure
500dc0cb1cdSDale Ghent  *
501dc0cb1cdSDale Ghent  * Configure Tx Descriptor Arbiter and credits for each traffic class.
502dc0cb1cdSDale Ghent  */
ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)503dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
504dc0cb1cdSDale Ghent 				     struct ixgbe_dcb_config *dcb_config)
505dc0cb1cdSDale Ghent {
506dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
507dc0cb1cdSDale Ghent 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
508dc0cb1cdSDale Ghent 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
509dc0cb1cdSDale Ghent 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
510dc0cb1cdSDale Ghent 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
511dc0cb1cdSDale Ghent 
512dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
513dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
514dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
515dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
516dc0cb1cdSDale Ghent 
517dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
518dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
519dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
520dc0cb1cdSDale Ghent 							     bwgid, tsa);
521dc0cb1cdSDale Ghent 		break;
522dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
523dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
524dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
525dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
526*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
527dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
528dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
529dc0cb1cdSDale Ghent 							     bwgid, tsa);
530dc0cb1cdSDale Ghent 		break;
531dc0cb1cdSDale Ghent #endif
532dc0cb1cdSDale Ghent 	default:
533dc0cb1cdSDale Ghent 		break;
534dc0cb1cdSDale Ghent 	}
535dc0cb1cdSDale Ghent 	return ret;
536dc0cb1cdSDale Ghent }
537dc0cb1cdSDale Ghent 
538dc0cb1cdSDale Ghent /**
539dc0cb1cdSDale Ghent  * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
540dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
541dc0cb1cdSDale Ghent  * @dcb_config: pointer to ixgbe_dcb_config structure
542dc0cb1cdSDale Ghent  *
543dc0cb1cdSDale Ghent  * Configure Tx Data Arbiter and credits for each traffic class.
544dc0cb1cdSDale Ghent  */
ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)545dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
546dc0cb1cdSDale Ghent 				     struct ixgbe_dcb_config *dcb_config)
547dc0cb1cdSDale Ghent {
548dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
549dc0cb1cdSDale Ghent 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
550dc0cb1cdSDale Ghent 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
551dc0cb1cdSDale Ghent 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
552dc0cb1cdSDale Ghent 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
553dc0cb1cdSDale Ghent 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
554dc0cb1cdSDale Ghent 
555dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
556dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
557dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
558dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
559dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
560dc0cb1cdSDale Ghent 
561dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
562dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
563dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
564dc0cb1cdSDale Ghent 							     bwgid, tsa);
565dc0cb1cdSDale Ghent 		break;
566dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
567dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
568dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
569dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
570*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
571dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
572dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
573dc0cb1cdSDale Ghent 							     bwgid, tsa,
574dc0cb1cdSDale Ghent 							     map);
575dc0cb1cdSDale Ghent 		break;
576dc0cb1cdSDale Ghent #endif
577dc0cb1cdSDale Ghent 	default:
578dc0cb1cdSDale Ghent 		break;
579dc0cb1cdSDale Ghent 	}
580dc0cb1cdSDale Ghent 	return ret;
581dc0cb1cdSDale Ghent }
582dc0cb1cdSDale Ghent 
583dc0cb1cdSDale Ghent /**
584dc0cb1cdSDale Ghent  * ixgbe_dcb_config_pfc_cee - Config priority flow control
585dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
586dc0cb1cdSDale Ghent  * @dcb_config: pointer to ixgbe_dcb_config structure
587dc0cb1cdSDale Ghent  *
588dc0cb1cdSDale Ghent  * Configure Priority Flow Control for each traffic class.
589dc0cb1cdSDale Ghent  */
ixgbe_dcb_config_pfc_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)590dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
591dc0cb1cdSDale Ghent 			 struct ixgbe_dcb_config *dcb_config)
592dc0cb1cdSDale Ghent {
593dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
594dc0cb1cdSDale Ghent 	u8 pfc_en;
595dc0cb1cdSDale Ghent 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
596dc0cb1cdSDale Ghent 
597dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
598dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
599dc0cb1cdSDale Ghent 
600dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
601dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
602dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
603dc0cb1cdSDale Ghent 		break;
604dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
605dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
606dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
607dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
608*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
609dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
610dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
611dc0cb1cdSDale Ghent 		break;
612dc0cb1cdSDale Ghent #endif
613dc0cb1cdSDale Ghent 	default:
614dc0cb1cdSDale Ghent 		break;
615dc0cb1cdSDale Ghent 	}
616dc0cb1cdSDale Ghent 	return ret;
617dc0cb1cdSDale Ghent }
618dc0cb1cdSDale Ghent 
619dc0cb1cdSDale Ghent /**
620dc0cb1cdSDale Ghent  * ixgbe_dcb_config_tc_stats - Config traffic class statistics
621dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
622dc0cb1cdSDale Ghent  *
623dc0cb1cdSDale Ghent  * Configure queue statistics registers, all queues belonging to same traffic
624dc0cb1cdSDale Ghent  * class uses a single set of queue statistics counters.
625dc0cb1cdSDale Ghent  */
ixgbe_dcb_config_tc_stats(struct ixgbe_hw * hw)626dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
627dc0cb1cdSDale Ghent {
628dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
629dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
630dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
631dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tc_stats_82598(hw);
632dc0cb1cdSDale Ghent 		break;
633dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
634dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
635dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
636dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
637*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
638dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
639dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
640dc0cb1cdSDale Ghent 		break;
641dc0cb1cdSDale Ghent #endif
642dc0cb1cdSDale Ghent 	default:
643dc0cb1cdSDale Ghent 		break;
644dc0cb1cdSDale Ghent 	}
645dc0cb1cdSDale Ghent 	return ret;
646dc0cb1cdSDale Ghent }
647dc0cb1cdSDale Ghent 
648dc0cb1cdSDale Ghent /**
649dc0cb1cdSDale Ghent  * ixgbe_dcb_hw_config_cee - Config and enable DCB
650dc0cb1cdSDale Ghent  * @hw: pointer to hardware structure
651dc0cb1cdSDale Ghent  * @dcb_config: pointer to ixgbe_dcb_config structure
652dc0cb1cdSDale Ghent  *
653dc0cb1cdSDale Ghent  * Configure dcb settings and enable dcb mode.
654dc0cb1cdSDale Ghent  */
ixgbe_dcb_hw_config_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)655dc0cb1cdSDale Ghent s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
656dc0cb1cdSDale Ghent 			struct ixgbe_dcb_config *dcb_config)
657dc0cb1cdSDale Ghent {
658dc0cb1cdSDale Ghent 	s32 ret = IXGBE_NOT_IMPLEMENTED;
659dc0cb1cdSDale Ghent 	u8 pfc_en;
660dc0cb1cdSDale Ghent 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
661dc0cb1cdSDale Ghent 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
662dc0cb1cdSDale Ghent 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
663dc0cb1cdSDale Ghent 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
664dc0cb1cdSDale Ghent 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
665dc0cb1cdSDale Ghent 
666dc0cb1cdSDale Ghent 	/* Unpack CEE standard containers */
667dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
668dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
669dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
670dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
671dc0cb1cdSDale Ghent 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
672dc0cb1cdSDale Ghent 
673dc0cb1cdSDale Ghent 	hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
674dc0cb1cdSDale Ghent 				0, dcb_config->rx_pba_cfg);
675dc0cb1cdSDale Ghent 
676dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
677dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
678dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
679dc0cb1cdSDale Ghent 						refill, max, bwgid, tsa);
680dc0cb1cdSDale Ghent 		break;
681dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
682dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
683dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
684dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
685*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
686dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
687dc0cb1cdSDale Ghent 		ixgbe_dcb_config_82599(hw, dcb_config);
688dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
689dc0cb1cdSDale Ghent 						refill, max, bwgid,
690dc0cb1cdSDale Ghent 						tsa, map);
691dc0cb1cdSDale Ghent 
692dc0cb1cdSDale Ghent 		ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
693dc0cb1cdSDale Ghent 		break;
694dc0cb1cdSDale Ghent #endif
695dc0cb1cdSDale Ghent 	default:
696dc0cb1cdSDale Ghent 		break;
697dc0cb1cdSDale Ghent 	}
698dc0cb1cdSDale Ghent 
699dc0cb1cdSDale Ghent 	if (!ret && dcb_config->pfc_mode_enable) {
700dc0cb1cdSDale Ghent 		ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
701dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
702dc0cb1cdSDale Ghent 	}
703dc0cb1cdSDale Ghent 
704dc0cb1cdSDale Ghent 	return ret;
705dc0cb1cdSDale Ghent }
706dc0cb1cdSDale Ghent 
707dc0cb1cdSDale Ghent /* Helper routines to abstract HW specifics from DCB netlink ops */
ixgbe_dcb_config_pfc(struct ixgbe_hw * hw,u8 pfc_en,u8 * map)708dc0cb1cdSDale Ghent s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
709dc0cb1cdSDale Ghent {
710dc0cb1cdSDale Ghent 	int ret = IXGBE_ERR_PARAM;
711dc0cb1cdSDale Ghent 
712dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
713dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
714dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
715dc0cb1cdSDale Ghent 		break;
716dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
717dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
718dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
719dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
720*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
721dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
722dc0cb1cdSDale Ghent 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
723dc0cb1cdSDale Ghent 		break;
724dc0cb1cdSDale Ghent #endif
725dc0cb1cdSDale Ghent 	default:
726dc0cb1cdSDale Ghent 		break;
727dc0cb1cdSDale Ghent 	}
728dc0cb1cdSDale Ghent 	return ret;
729dc0cb1cdSDale Ghent }
730dc0cb1cdSDale Ghent 
ixgbe_dcb_hw_config(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa,u8 * map)731dc0cb1cdSDale Ghent s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
732dc0cb1cdSDale Ghent 			    u8 *bwg_id, u8 *tsa, u8 *map)
733dc0cb1cdSDale Ghent {
734dc0cb1cdSDale Ghent 	switch (hw->mac.type) {
735dc0cb1cdSDale Ghent 	case ixgbe_mac_82598EB:
736dc0cb1cdSDale Ghent 		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
737dc0cb1cdSDale Ghent 		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
738dc0cb1cdSDale Ghent 						       tsa);
739dc0cb1cdSDale Ghent 		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
740dc0cb1cdSDale Ghent 						       tsa);
741dc0cb1cdSDale Ghent 		break;
742dc0cb1cdSDale Ghent 	case ixgbe_mac_82599EB:
743dc0cb1cdSDale Ghent 	case ixgbe_mac_X540:
744dc0cb1cdSDale Ghent 	case ixgbe_mac_X550:
745dc0cb1cdSDale Ghent 	case ixgbe_mac_X550EM_x:
746*48ed61a7SRobert Mustacchi 	case ixgbe_mac_X550EM_a:
747dc0cb1cdSDale Ghent #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
748dc0cb1cdSDale Ghent 		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
749dc0cb1cdSDale Ghent 						  tsa, map);
750dc0cb1cdSDale Ghent 		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
751dc0cb1cdSDale Ghent 						       tsa);
752dc0cb1cdSDale Ghent 		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
753dc0cb1cdSDale Ghent 						       tsa, map);
754dc0cb1cdSDale Ghent 		break;
755dc0cb1cdSDale Ghent #endif
756dc0cb1cdSDale Ghent 	default:
757dc0cb1cdSDale Ghent 		break;
758dc0cb1cdSDale Ghent 	}
759dc0cb1cdSDale Ghent 	return 0;
760dc0cb1cdSDale Ghent }
761