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