xref: /dragonfly/sys/dev/netif/ix/ixgbe_dcb.c (revision d8d5b238)
1 /******************************************************************************
2 
3   Copyright (c) 2001-2017, Intel Corporation
4   All rights reserved.
5 
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8 
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11 
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    3. Neither the name of the Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived from
18       this software without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 /*$FreeBSD$*/
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 
385 	return ret_val;
386 }
387 
388 /**
389  * ixgbe_dcb_get_tc_stats - Returns status of each traffic class
390  * @hw: pointer to hardware structure
391  * @stats: pointer to statistics structure
392  * @tc_count:  Number of elements in bwg_array.
393  *
394  * This function returns the status data for each of the Traffic Classes in use.
395  */
396 s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
397 			   u8 tc_count)
398 {
399 	s32 ret = IXGBE_NOT_IMPLEMENTED;
400 	switch (hw->mac.type) {
401 	case ixgbe_mac_82598EB:
402 		ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
403 		break;
404 	case ixgbe_mac_82599EB:
405 	case ixgbe_mac_X540:
406 	case ixgbe_mac_X550:
407 	case ixgbe_mac_X550EM_x:
408 	case ixgbe_mac_X550EM_a:
409 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
410 		ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
411 		break;
412 #endif
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 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
441 		ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
442 		break;
443 #endif
444 	default:
445 		break;
446 	}
447 	return ret;
448 }
449 
450 /**
451  * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
452  * @hw: pointer to hardware structure
453  * @dcb_config: pointer to ixgbe_dcb_config structure
454  *
455  * Configure Rx Data Arbiter and credits for each traffic class.
456  */
457 s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
458 				struct ixgbe_dcb_config *dcb_config)
459 {
460 	s32 ret = IXGBE_NOT_IMPLEMENTED;
461 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
462 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
463 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY]	= { 0 };
464 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
465 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]	= { 0 };
466 
467 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
468 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
469 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
470 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
471 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
472 
473 	switch (hw->mac.type) {
474 	case ixgbe_mac_82598EB:
475 		ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
476 		break;
477 	case ixgbe_mac_82599EB:
478 	case ixgbe_mac_X540:
479 	case ixgbe_mac_X550:
480 	case ixgbe_mac_X550EM_x:
481 	case ixgbe_mac_X550EM_a:
482 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
483 		ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
484 							tsa, map);
485 		break;
486 #endif
487 	default:
488 		break;
489 	}
490 	return ret;
491 }
492 
493 /**
494  * ixgbe_dcb_config_tx_desc_arbiter_cee - Config Tx Desc arbiter
495  * @hw: pointer to hardware structure
496  * @dcb_config: pointer to ixgbe_dcb_config structure
497  *
498  * Configure Tx Descriptor Arbiter and credits for each traffic class.
499  */
500 s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
501 				     struct ixgbe_dcb_config *dcb_config)
502 {
503 	s32 ret = IXGBE_NOT_IMPLEMENTED;
504 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
505 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
506 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
507 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
508 
509 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
510 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
511 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
512 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
513 
514 	switch (hw->mac.type) {
515 	case ixgbe_mac_82598EB:
516 		ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
517 							     bwgid, tsa);
518 		break;
519 	case ixgbe_mac_82599EB:
520 	case ixgbe_mac_X540:
521 	case ixgbe_mac_X550:
522 	case ixgbe_mac_X550EM_x:
523 	case ixgbe_mac_X550EM_a:
524 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
525 		ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
526 							     bwgid, tsa);
527 		break;
528 #endif
529 	default:
530 		break;
531 	}
532 	return ret;
533 }
534 
535 /**
536  * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
537  * @hw: pointer to hardware structure
538  * @dcb_config: pointer to ixgbe_dcb_config structure
539  *
540  * Configure Tx Data Arbiter and credits for each traffic class.
541  */
542 s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
543 				     struct ixgbe_dcb_config *dcb_config)
544 {
545 	s32 ret = IXGBE_NOT_IMPLEMENTED;
546 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
547 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
548 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
549 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
550 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
551 
552 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
553 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
554 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
555 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
556 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
557 
558 	switch (hw->mac.type) {
559 	case ixgbe_mac_82598EB:
560 		ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
561 							     bwgid, tsa);
562 		break;
563 	case ixgbe_mac_82599EB:
564 	case ixgbe_mac_X540:
565 	case ixgbe_mac_X550:
566 	case ixgbe_mac_X550EM_x:
567 	case ixgbe_mac_X550EM_a:
568 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
569 		ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
570 							     bwgid, tsa,
571 							     map);
572 		break;
573 #endif
574 	default:
575 		break;
576 	}
577 	return ret;
578 }
579 
580 /**
581  * ixgbe_dcb_config_pfc_cee - Config priority flow control
582  * @hw: pointer to hardware structure
583  * @dcb_config: pointer to ixgbe_dcb_config structure
584  *
585  * Configure Priority Flow Control for each traffic class.
586  */
587 s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
588 			 struct ixgbe_dcb_config *dcb_config)
589 {
590 	s32 ret = IXGBE_NOT_IMPLEMENTED;
591 	u8 pfc_en;
592 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
593 
594 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
595 	ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
596 
597 	switch (hw->mac.type) {
598 	case ixgbe_mac_82598EB:
599 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
600 		break;
601 	case ixgbe_mac_82599EB:
602 	case ixgbe_mac_X540:
603 	case ixgbe_mac_X550:
604 	case ixgbe_mac_X550EM_x:
605 	case ixgbe_mac_X550EM_a:
606 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
607 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
608 		break;
609 #endif
610 	default:
611 		break;
612 	}
613 	return ret;
614 }
615 
616 /**
617  * ixgbe_dcb_config_tc_stats - Config traffic class statistics
618  * @hw: pointer to hardware structure
619  *
620  * Configure queue statistics registers, all queues belonging to same traffic
621  * class uses a single set of queue statistics counters.
622  */
623 s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
624 {
625 	s32 ret = IXGBE_NOT_IMPLEMENTED;
626 	switch (hw->mac.type) {
627 	case ixgbe_mac_82598EB:
628 		ret = ixgbe_dcb_config_tc_stats_82598(hw);
629 		break;
630 	case ixgbe_mac_82599EB:
631 	case ixgbe_mac_X540:
632 	case ixgbe_mac_X550:
633 	case ixgbe_mac_X550EM_x:
634 	case ixgbe_mac_X550EM_a:
635 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
636 		ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
637 		break;
638 #endif
639 	default:
640 		break;
641 	}
642 	return ret;
643 }
644 
645 /**
646  * ixgbe_dcb_hw_config_cee - Config and enable DCB
647  * @hw: pointer to hardware structure
648  * @dcb_config: pointer to ixgbe_dcb_config structure
649  *
650  * Configure dcb settings and enable dcb mode.
651  */
652 s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
653 			struct ixgbe_dcb_config *dcb_config)
654 {
655 	s32 ret = IXGBE_NOT_IMPLEMENTED;
656 	u8 pfc_en;
657 	u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
658 	u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
659 	u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
660 	u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
661 	u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
662 
663 	/* Unpack CEE standard containers */
664 	ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
665 	ixgbe_dcb_unpack_max_cee(dcb_config, max);
666 	ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
667 	ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
668 	ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
669 
670 	hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
671 				0, dcb_config->rx_pba_cfg);
672 
673 	switch (hw->mac.type) {
674 	case ixgbe_mac_82598EB:
675 		ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
676 						refill, max, bwgid, tsa);
677 		break;
678 	case ixgbe_mac_82599EB:
679 	case ixgbe_mac_X540:
680 	case ixgbe_mac_X550:
681 	case ixgbe_mac_X550EM_x:
682 	case ixgbe_mac_X550EM_a:
683 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
684 		ixgbe_dcb_config_82599(hw, dcb_config);
685 		ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
686 						refill, max, bwgid,
687 						tsa, map);
688 
689 		ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
690 		break;
691 #endif
692 	default:
693 		break;
694 	}
695 
696 	if (!ret && dcb_config->pfc_mode_enable) {
697 		ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
698 		ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
699 	}
700 
701 	return ret;
702 }
703 
704 /* Helper routines to abstract HW specifics from DCB netlink ops */
705 s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
706 {
707 	int ret = IXGBE_ERR_PARAM;
708 
709 	switch (hw->mac.type) {
710 	case ixgbe_mac_82598EB:
711 		ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
712 		break;
713 	case ixgbe_mac_82599EB:
714 	case ixgbe_mac_X540:
715 	case ixgbe_mac_X550:
716 	case ixgbe_mac_X550EM_x:
717 	case ixgbe_mac_X550EM_a:
718 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
719 		ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
720 		break;
721 #endif
722 	default:
723 		break;
724 	}
725 	return ret;
726 }
727 
728 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
729 			    u8 *bwg_id, u8 *tsa, u8 *map)
730 {
731 	switch (hw->mac.type) {
732 	case ixgbe_mac_82598EB:
733 		ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
734 		ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
735 						       tsa);
736 		ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
737 						       tsa);
738 		break;
739 	case ixgbe_mac_82599EB:
740 	case ixgbe_mac_X540:
741 	case ixgbe_mac_X550:
742 	case ixgbe_mac_X550EM_x:
743 	case ixgbe_mac_X550EM_a:
744 #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
745 		ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
746 						  tsa, map);
747 		ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
748 						       tsa);
749 		ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
750 						       tsa, map);
751 		break;
752 #endif
753 	default:
754 		break;
755 	}
756 	return 0;
757 }
758