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