xref: /dragonfly/sys/dev/netif/ix/ixgbe_dcb.c (revision dd5ce676d9b4496101d795200cb99fd0ddf5b254)
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