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