1 /* $NetBSD: ixgbe_dcb.c,v 1.15 2023/10/06 14:48:08 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.15 2023/10/06 14:48:08 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  */
ixgbe_dcb_calculate_tc_credits(u8 * bw,u16 * refill,u16 * max,int max_frame_size)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  */
ixgbe_dcb_calculate_tc_credits_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config,u32 max_frame_size,u8 direction)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  */
ixgbe_dcb_unpack_pfc_cee(struct ixgbe_dcb_config * cfg,u8 * map,u8 * pfc_up)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 
ixgbe_dcb_unpack_refill_cee(struct ixgbe_dcb_config * cfg,int direction,u16 * refill)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 
ixgbe_dcb_unpack_max_cee(struct ixgbe_dcb_config * cfg,u16 * max)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 
ixgbe_dcb_unpack_bwgid_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * bwgid)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 
ixgbe_dcb_unpack_tsa_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * tsa)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 
ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config * cfg,int direction,u8 up)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 
ixgbe_dcb_unpack_map_cee(struct ixgbe_dcb_config * cfg,int direction,u8 * map)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_check_config_cee - 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  */
ixgbe_dcb_check_config_cee(struct ixgbe_dcb_config * dcb_config)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  */
ixgbe_dcb_get_tc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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                     ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
416                     break;
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  */
ixgbe_dcb_get_pfc_stats(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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                     ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
445                     break;
446           default:
447                     break;
448           }
449           return ret;
450 }
451 
452 /**
453  * ixgbe_dcb_config_rx_arbiter_cee - Config Rx arbiter
454  * @hw: pointer to hardware structure
455  * @dcb_config: pointer to ixgbe_dcb_config structure
456  *
457  * Configure Rx Data Arbiter and credits for each traffic class.
458  */
ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)459 s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
460                                         struct ixgbe_dcb_config *dcb_config)
461 {
462           s32 ret = IXGBE_NOT_IMPLEMENTED;
463           u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]     = { 0 };
464           u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]   = { 0 };
465           u8 map[IXGBE_DCB_MAX_USER_PRIORITY]     = { 0 };
466           u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS] = { 0 };
467           u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]    = { 0 };
468 
469           ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
470           ixgbe_dcb_unpack_max_cee(dcb_config, max);
471           ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
472           ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
473           ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
474 
475           switch (hw->mac.type) {
476           case ixgbe_mac_82598EB:
477                     ret = ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
478                     break;
479           case ixgbe_mac_82599EB:
480           case ixgbe_mac_X540:
481           case ixgbe_mac_X550:
482           case ixgbe_mac_X550EM_x:
483           case ixgbe_mac_X550EM_a:
484                     ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
485                                                                       tsa, map);
486                     break;
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                     ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
525                                                                            bwgid, tsa);
526                     break;
527           default:
528                     break;
529           }
530           return ret;
531 }
532 
533 /**
534  * ixgbe_dcb_config_tx_data_arbiter_cee - Config Tx data arbiter
535  * @hw: pointer to hardware structure
536  * @dcb_config: pointer to ixgbe_dcb_config structure
537  *
538  * Configure Tx Data Arbiter and credits for each traffic class.
539  */
ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)540 s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
541                                              struct ixgbe_dcb_config *dcb_config)
542 {
543           s32 ret = IXGBE_NOT_IMPLEMENTED;
544           u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
545           u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
546           u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
547           u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
548           u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
549 
550           ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
551           ixgbe_dcb_unpack_max_cee(dcb_config, max);
552           ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
553           ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
554           ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
555 
556           switch (hw->mac.type) {
557           case ixgbe_mac_82598EB:
558                     ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
559                                                                            bwgid, tsa);
560                     break;
561           case ixgbe_mac_82599EB:
562           case ixgbe_mac_X540:
563           case ixgbe_mac_X550:
564           case ixgbe_mac_X550EM_x:
565           case ixgbe_mac_X550EM_a:
566                     ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
567                                                                            bwgid, tsa,
568                                                                            map);
569                     break;
570           default:
571                     break;
572           }
573           return ret;
574 }
575 
576 /**
577  * ixgbe_dcb_config_pfc_cee - Config priority flow control
578  * @hw: pointer to hardware structure
579  * @dcb_config: pointer to ixgbe_dcb_config structure
580  *
581  * Configure Priority Flow Control for each traffic class.
582  */
ixgbe_dcb_config_pfc_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)583 s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
584                                struct ixgbe_dcb_config *dcb_config)
585 {
586           s32 ret = IXGBE_NOT_IMPLEMENTED;
587           u8 pfc_en;
588           u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
589 
590           ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
591           ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
592 
593           switch (hw->mac.type) {
594           case ixgbe_mac_82598EB:
595                     ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
596                     break;
597           case ixgbe_mac_82599EB:
598           case ixgbe_mac_X540:
599           case ixgbe_mac_X550:
600           case ixgbe_mac_X550EM_x:
601           case ixgbe_mac_X550EM_a:
602                     ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
603                     break;
604           default:
605                     break;
606           }
607           return ret;
608 }
609 
610 /**
611  * ixgbe_dcb_config_tc_stats - Config traffic class statistics
612  * @hw: pointer to hardware structure
613  *
614  * Configure queue statistics registers, all queues belonging to same traffic
615  * class uses a single set of queue statistics counters.
616  */
ixgbe_dcb_config_tc_stats(struct ixgbe_hw * hw)617 s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
618 {
619           s32 ret = IXGBE_NOT_IMPLEMENTED;
620           switch (hw->mac.type) {
621           case ixgbe_mac_82598EB:
622                     ret = ixgbe_dcb_config_tc_stats_82598(hw);
623                     break;
624           case ixgbe_mac_82599EB:
625           case ixgbe_mac_X540:
626           case ixgbe_mac_X550:
627           case ixgbe_mac_X550EM_x:
628           case ixgbe_mac_X550EM_a:
629                     ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
630                     break;
631           default:
632                     break;
633           }
634           return ret;
635 }
636 
637 /**
638  * ixgbe_dcb_hw_config_cee - Config and enable DCB
639  * @hw: pointer to hardware structure
640  * @dcb_config: pointer to ixgbe_dcb_config structure
641  *
642  * Configure dcb settings and enable dcb mode.
643  */
ixgbe_dcb_hw_config_cee(struct ixgbe_hw * hw,struct ixgbe_dcb_config * dcb_config)644 s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
645                               struct ixgbe_dcb_config *dcb_config)
646 {
647           s32 ret = IXGBE_NOT_IMPLEMENTED;
648           u8 pfc_en;
649           u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS];
650           u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS];
651           u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 };
652           u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS];
653           u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS];
654 
655           /* Unpack CEE standard containers */
656           ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill);
657           ixgbe_dcb_unpack_max_cee(dcb_config, max);
658           ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid);
659           ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa);
660           ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map);
661 
662           hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs,
663                                         0, dcb_config->rx_pba_cfg);
664 
665           switch (hw->mac.type) {
666           case ixgbe_mac_82598EB:
667                     ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed,
668                                                             refill, max, bwgid, tsa);
669                     break;
670           case ixgbe_mac_82599EB:
671           case ixgbe_mac_X540:
672           case ixgbe_mac_X550:
673           case ixgbe_mac_X550EM_x:
674           case ixgbe_mac_X550EM_a:
675                     ixgbe_dcb_config_82599(hw, dcb_config);
676                     ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
677                                                             refill, max, bwgid,
678                                                             tsa, map);
679 
680                     ixgbe_dcb_config_tc_stats_82599(hw, dcb_config);
681                     break;
682           default:
683                     break;
684           }
685 
686           if (!ret && dcb_config->pfc_mode_enable) {
687                     ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en);
688                     ret = ixgbe_dcb_config_pfc(hw, pfc_en, map);
689           }
690 
691           return ret;
692 }
693 
694 /* Helper routines to abstract HW specifics from DCB netlink ops */
ixgbe_dcb_config_pfc(struct ixgbe_hw * hw,u8 pfc_en,u8 * map)695 s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
696 {
697           int ret = IXGBE_ERR_PARAM;
698 
699           switch (hw->mac.type) {
700           case ixgbe_mac_82598EB:
701                     ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
702                     break;
703           case ixgbe_mac_82599EB:
704           case ixgbe_mac_X540:
705           case ixgbe_mac_X550:
706           case ixgbe_mac_X550EM_x:
707           case ixgbe_mac_X550EM_a:
708                     ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
709                     break;
710           default:
711                     break;
712           }
713           return ret;
714 }
715 
ixgbe_dcb_hw_config(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa,u8 * map)716 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
717                                   u8 *bwg_id, u8 *tsa, u8 *map)
718 {
719           switch (hw->mac.type) {
720           case ixgbe_mac_82598EB:
721                     ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
722                     ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
723                                                                    tsa);
724                     ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
725                                                                    tsa);
726                     break;
727           case ixgbe_mac_82599EB:
728           case ixgbe_mac_X540:
729           case ixgbe_mac_X550:
730           case ixgbe_mac_X550EM_x:
731           case ixgbe_mac_X550EM_a:
732                     ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
733                                                               tsa, map);
734                     ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id,
735                                                                    tsa);
736                     ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
737                                                                    tsa, map);
738                     break;
739           default:
740                     break;
741           }
742           return 0;
743 }
744