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