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