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 */
ixgbe_dcb_calculate_tc_credits(u8 * bw,u16 * refill,u16 * max,int max_frame_size)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 */
ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config,u32 max_frame_size,u8 direction)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 */
ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config * cfg,u8 * map,u8 * pfc_up)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
ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config * cfg,int direction,u16 * refill)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
ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config * cfg,u16 * max)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
ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * bwgid)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
ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * tsa)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
ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config * cfg,int direction,u8 up)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
ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * map)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 */
ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_get_tc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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 */
ixgbe_dcb_get_pfc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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 */
ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_config_pfc_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_config_tc_stats(struct ixgbe_hw * hw)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 */
ixgbe_dcb_hw_config_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)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 */
ixgbe_dcb_config_pfc(struct ixgbe_hw * hw,u8 pfc_en,u8 * map)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
ixgbe_dcb_hw_config(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa,u8 * map)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