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