linux/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  Intel 10 Gigabit PCI Express Linux driver
   4  Copyright(c) 1999 - 2016 Intel Corporation.
   5
   6  This program is free software; you can redistribute it and/or modify it
   7  under the terms and conditions of the GNU General Public License,
   8  version 2, as published by the Free Software Foundation.
   9
  10  This program is distributed in the hope it will be useful, but WITHOUT
  11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13  more details.
  14
  15  You should have received a copy of the GNU General Public License along with
  16  this program; if not, write to the Free Software Foundation, Inc.,
  17  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  18
  19  The full GNU General Public License is included in this distribution in
  20  the file called "COPYING".
  21
  22  Contact Information:
  23  Linux NICS <linux.nics@intel.com>
  24  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  25  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26
  27*******************************************************************************/
  28
  29
  30#include "ixgbe.h"
  31#include "ixgbe_type.h"
  32#include "ixgbe_dcb.h"
  33#include "ixgbe_dcb_82598.h"
  34#include "ixgbe_dcb_82599.h"
  35
  36/**
  37 * ixgbe_ieee_credits - This calculates the ieee traffic class
  38 * credits from the configured bandwidth percentages. Credits
  39 * are the smallest unit programmable into the underlying
  40 * hardware. The IEEE 802.1Qaz specification do not use bandwidth
  41 * groups so this is much simplified from the CEE case.
  42 */
  43static s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill,
  44                              __u16 *max, int max_frame)
  45{
  46        int min_percent = 100;
  47        int min_credit, multiplier;
  48        int i;
  49
  50        min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
  51                        DCB_CREDIT_QUANTUM;
  52
  53        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
  54                if (bw[i] < min_percent && bw[i])
  55                        min_percent = bw[i];
  56        }
  57
  58        multiplier = (min_credit / min_percent) + 1;
  59
  60        /* Find out the hw credits for each TC */
  61        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
  62                int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
  63
  64                if (val < min_credit)
  65                        val = min_credit;
  66                refill[i] = val;
  67
  68                max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
  69        }
  70        return 0;
  71}
  72
  73/**
  74 * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
  75 * @ixgbe_dcb_config: Struct containing DCB settings.
  76 * @direction: Configuring either Tx or Rx.
  77 *
  78 * This function calculates the credits allocated to each traffic class.
  79 * It should be called only after the rules are checked by
  80 * ixgbe_dcb_check_config().
  81 */
  82s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
  83                                   struct ixgbe_dcb_config *dcb_config,
  84                                   int max_frame, u8 direction)
  85{
  86        struct tc_bw_alloc *p;
  87        int min_credit;
  88        int min_multiplier;
  89        int min_percent = 100;
  90        /* Initialization values default for Tx settings */
  91        u32 credit_refill       = 0;
  92        u32 credit_max          = 0;
  93        u16 link_percentage     = 0;
  94        u8  bw_percent          = 0;
  95        u8  i;
  96
  97        if (!dcb_config)
  98                return DCB_ERR_CONFIG;
  99
 100        min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
 101                        DCB_CREDIT_QUANTUM;
 102
 103        /* Find smallest link percentage */
 104        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 105                p = &dcb_config->tc_config[i].path[direction];
 106                bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
 107                link_percentage = p->bwg_percent;
 108
 109                link_percentage = (link_percentage * bw_percent) / 100;
 110
 111                if (link_percentage && link_percentage < min_percent)
 112                        min_percent = link_percentage;
 113        }
 114
 115        /*
 116         * The ratio between traffic classes will control the bandwidth
 117         * percentages seen on the wire. To calculate this ratio we use
 118         * a multiplier. It is required that the refill credits must be
 119         * larger than the max frame size so here we find the smallest
 120         * multiplier that will allow all bandwidth percentages to be
 121         * greater than the max frame size.
 122         */
 123        min_multiplier = (min_credit / min_percent) + 1;
 124
 125        /* Find out the link percentage for each TC first */
 126        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 127                p = &dcb_config->tc_config[i].path[direction];
 128                bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
 129
 130                link_percentage = p->bwg_percent;
 131                /* Must be careful of integer division for very small nums */
 132                link_percentage = (link_percentage * bw_percent) / 100;
 133                if (p->bwg_percent > 0 && link_percentage == 0)
 134                        link_percentage = 1;
 135
 136                /* Save link_percentage for reference */
 137                p->link_percent = (u8)link_percentage;
 138
 139                /* Calculate credit refill ratio using multiplier */
 140                credit_refill = min(link_percentage * min_multiplier,
 141                                    MAX_CREDIT_REFILL);
 142
 143                /* Refill at least minimum credit */
 144                if (credit_refill < min_credit)
 145                        credit_refill = min_credit;
 146
 147                p->data_credits_refill = (u16)credit_refill;
 148
 149                /* Calculate maximum credit for the TC */
 150                credit_max = (link_percentage * MAX_CREDIT) / 100;
 151
 152                /*
 153                 * Adjustment based on rule checking, if the percentage
 154                 * of a TC is too small, the maximum credit may not be
 155                 * enough to send out a jumbo frame in data plane arbitration.
 156                 */
 157                if (credit_max < min_credit)
 158                        credit_max = min_credit;
 159
 160                if (direction == DCB_TX_CONFIG) {
 161                        /*
 162                         * Adjustment based on rule checking, if the
 163                         * percentage of a TC is too small, the maximum
 164                         * credit may not be enough to send out a TSO
 165                         * packet in descriptor plane arbitration.
 166                         */
 167                        if ((hw->mac.type == ixgbe_mac_82598EB) &&
 168                            credit_max &&
 169                            (credit_max < MINIMUM_CREDIT_FOR_TSO))
 170                                credit_max = MINIMUM_CREDIT_FOR_TSO;
 171
 172                        dcb_config->tc_config[i].desc_credits_max =
 173                                (u16)credit_max;
 174                }
 175
 176                p->data_credits_max = (u16)credit_max;
 177        }
 178
 179        return 0;
 180}
 181
 182void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
 183{
 184        struct tc_configuration *tc_config = &cfg->tc_config[0];
 185        int tc;
 186
 187        for (*pfc_en = 0, tc = 0; tc < MAX_TRAFFIC_CLASS; tc++) {
 188                if (tc_config[tc].dcb_pfc != pfc_disabled)
 189                        *pfc_en |= BIT(tc);
 190        }
 191}
 192
 193void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
 194                             u16 *refill)
 195{
 196        struct tc_configuration *tc_config = &cfg->tc_config[0];
 197        int tc;
 198
 199        for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
 200                refill[tc] = tc_config[tc].path[direction].data_credits_refill;
 201}
 202
 203void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
 204{
 205        struct tc_configuration *tc_config = &cfg->tc_config[0];
 206        int tc;
 207
 208        for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
 209                max[tc] = tc_config[tc].desc_credits_max;
 210}
 211
 212void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
 213                            u8 *bwgid)
 214{
 215        struct tc_configuration *tc_config = &cfg->tc_config[0];
 216        int tc;
 217
 218        for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
 219                bwgid[tc] = tc_config[tc].path[direction].bwg_id;
 220}
 221
 222void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
 223                            u8 *ptype)
 224{
 225        struct tc_configuration *tc_config = &cfg->tc_config[0];
 226        int tc;
 227
 228        for (tc = 0; tc < MAX_TRAFFIC_CLASS; tc++)
 229                ptype[tc] = tc_config[tc].path[direction].prio_type;
 230}
 231
 232u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
 233{
 234        struct tc_configuration *tc_config = &cfg->tc_config[0];
 235        u8 prio_mask = BIT(up);
 236        u8 tc = cfg->num_tcs.pg_tcs;
 237
 238        /* If tc is 0 then DCB is likely not enabled or supported */
 239        if (!tc)
 240                return 0;
 241
 242        /*
 243         * Test from maximum TC to 1 and report the first match we find.  If
 244         * we find no match we can assume that the TC is 0 since the TC must
 245         * be set for all user priorities
 246         */
 247        for (tc--; tc; tc--) {
 248                if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
 249                        break;
 250        }
 251
 252        return tc;
 253}
 254
 255void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map)
 256{
 257        u8 up;
 258
 259        for (up = 0; up < MAX_USER_PRIORITY; up++)
 260                map[up] = ixgbe_dcb_get_tc_from_up(cfg, direction, up);
 261}
 262
 263/**
 264 * ixgbe_dcb_hw_config - Config and enable DCB
 265 * @hw: pointer to hardware structure
 266 * @dcb_config: pointer to ixgbe_dcb_config structure
 267 *
 268 * Configure dcb settings and enable dcb mode.
 269 */
 270s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
 271                        struct ixgbe_dcb_config *dcb_config)
 272{
 273        u8 pfc_en;
 274        u8 ptype[MAX_TRAFFIC_CLASS];
 275        u8 bwgid[MAX_TRAFFIC_CLASS];
 276        u8 prio_tc[MAX_TRAFFIC_CLASS];
 277        u16 refill[MAX_TRAFFIC_CLASS];
 278        u16 max[MAX_TRAFFIC_CLASS];
 279
 280        /* Unpack CEE standard containers */
 281        ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
 282        ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
 283        ixgbe_dcb_unpack_max(dcb_config, max);
 284        ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
 285        ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
 286        ixgbe_dcb_unpack_map(dcb_config, DCB_TX_CONFIG, prio_tc);
 287
 288        switch (hw->mac.type) {
 289        case ixgbe_mac_82598EB:
 290                return ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
 291                                                 bwgid, ptype);
 292        case ixgbe_mac_82599EB:
 293        case ixgbe_mac_X540:
 294        case ixgbe_mac_X550:
 295        case ixgbe_mac_X550EM_x:
 296        case ixgbe_mac_x550em_a:
 297                return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
 298                                                 bwgid, ptype, prio_tc);
 299        default:
 300                break;
 301        }
 302        return 0;
 303}
 304
 305/* Helper routines to abstract HW specifics from DCB netlink ops */
 306s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
 307{
 308        switch (hw->mac.type) {
 309        case ixgbe_mac_82598EB:
 310                return ixgbe_dcb_config_pfc_82598(hw, pfc_en);
 311        case ixgbe_mac_82599EB:
 312        case ixgbe_mac_X540:
 313        case ixgbe_mac_X550:
 314        case ixgbe_mac_X550EM_x:
 315        case ixgbe_mac_x550em_a:
 316                return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
 317        default:
 318                break;
 319        }
 320        return -EINVAL;
 321}
 322
 323s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame)
 324{
 325        __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS];
 326        __u8 prio_type[IEEE_8021QAZ_MAX_TCS];
 327        int i;
 328
 329        /* naively give each TC a bwg to map onto CEE hardware */
 330        __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
 331
 332        /* Map TSA onto CEE prio type */
 333        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 334                switch (ets->tc_tsa[i]) {
 335                case IEEE_8021QAZ_TSA_STRICT:
 336                        prio_type[i] = 2;
 337                        break;
 338                case IEEE_8021QAZ_TSA_ETS:
 339                        prio_type[i] = 0;
 340                        break;
 341                default:
 342                        /* Hardware only supports priority strict or
 343                         * ETS transmission selection algorithms if
 344                         * we receive some other value from dcbnl
 345                         * throw an error
 346                         */
 347                        return -EINVAL;
 348                }
 349        }
 350
 351        ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
 352        return ixgbe_dcb_hw_ets_config(hw, refill, max,
 353                                       bwg_id, prio_type, ets->prio_tc);
 354}
 355
 356s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
 357                            u16 *refill, u16 *max, u8 *bwg_id,
 358                            u8 *prio_type, u8 *prio_tc)
 359{
 360        switch (hw->mac.type) {
 361        case ixgbe_mac_82598EB:
 362                ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
 363                                                        prio_type);
 364                ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
 365                                                             bwg_id, prio_type);
 366                ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
 367                                                             bwg_id, prio_type);
 368                break;
 369        case ixgbe_mac_82599EB:
 370        case ixgbe_mac_X540:
 371        case ixgbe_mac_X550:
 372        case ixgbe_mac_X550EM_x:
 373        case ixgbe_mac_x550em_a:
 374                ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
 375                                                  bwg_id, prio_type, prio_tc);
 376                ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
 377                                                       bwg_id, prio_type);
 378                ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
 379                                                       prio_type, prio_tc);
 380                break;
 381        default:
 382                break;
 383        }
 384        return 0;
 385}
 386
 387static void ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw *hw, u8 *map)
 388{
 389        u32 reg, i;
 390
 391        reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
 392        for (i = 0; i < MAX_USER_PRIORITY; i++)
 393                map[i] = IXGBE_RTRUP2TC_UP_MASK &
 394                        (reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
 395}
 396
 397void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
 398{
 399        switch (hw->mac.type) {
 400        case ixgbe_mac_82599EB:
 401        case ixgbe_mac_X540:
 402        case ixgbe_mac_X550:
 403        case ixgbe_mac_X550EM_x:
 404        case ixgbe_mac_x550em_a:
 405                ixgbe_dcb_read_rtrup2tc_82599(hw, map);
 406                break;
 407        default:
 408                break;
 409        }
 410}
 411