linux/drivers/net/ixgbe/ixgbe_dcb.c
<<
>>
Prefs
   1/*******************************************************************************
   2
   3  Intel 10 Gigabit PCI Express Linux driver
   4  Copyright(c) 1999 - 2011 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 */
  43s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame)
  44{
  45        int min_percent = 100;
  46        int min_credit, multiplier;
  47        int i;
  48
  49        min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
  50                        DCB_CREDIT_QUANTUM;
  51
  52        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
  53                if (bw[i] < min_percent && bw[i])
  54                        min_percent = bw[i];
  55        }
  56
  57        multiplier = (min_credit / min_percent) + 1;
  58
  59        /* Find out the hw credits for each TC */
  60        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
  61                int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
  62
  63                if (val < min_credit)
  64                        val = min_credit;
  65                refill[i] = val;
  66
  67                max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit;
  68        }
  69        return 0;
  70}
  71
  72/**
  73 * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
  74 * @ixgbe_dcb_config: Struct containing DCB settings.
  75 * @direction: Configuring either Tx or Rx.
  76 *
  77 * This function calculates the credits allocated to each traffic class.
  78 * It should be called only after the rules are checked by
  79 * ixgbe_dcb_check_config().
  80 */
  81s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
  82                                   struct ixgbe_dcb_config *dcb_config,
  83                                   int max_frame, u8 direction)
  84{
  85        struct tc_bw_alloc *p;
  86        int min_credit;
  87        int min_multiplier;
  88        int min_percent = 100;
  89        s32 ret_val = 0;
  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 == NULL) {
  98                ret_val = DCB_ERR_CONFIG;
  99                goto out;
 100        }
 101
 102        min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
 103                        DCB_CREDIT_QUANTUM;
 104
 105        /* Find smallest link percentage */
 106        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 107                p = &dcb_config->tc_config[i].path[direction];
 108                bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
 109                link_percentage = p->bwg_percent;
 110
 111                link_percentage = (link_percentage * bw_percent) / 100;
 112
 113                if (link_percentage && link_percentage < min_percent)
 114                        min_percent = link_percentage;
 115        }
 116
 117        /*
 118         * The ratio between traffic classes will control the bandwidth
 119         * percentages seen on the wire. To calculate this ratio we use
 120         * a multiplier. It is required that the refill credits must be
 121         * larger than the max frame size so here we find the smallest
 122         * multiplier that will allow all bandwidth percentages to be
 123         * greater than the max frame size.
 124         */
 125        min_multiplier = (min_credit / min_percent) + 1;
 126
 127        /* Find out the link percentage for each TC first */
 128        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 129                p = &dcb_config->tc_config[i].path[direction];
 130                bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
 131
 132                link_percentage = p->bwg_percent;
 133                /* Must be careful of integer division for very small nums */
 134                link_percentage = (link_percentage * bw_percent) / 100;
 135                if (p->bwg_percent > 0 && link_percentage == 0)
 136                        link_percentage = 1;
 137
 138                /* Save link_percentage for reference */
 139                p->link_percent = (u8)link_percentage;
 140
 141                /* Calculate credit refill ratio using multiplier */
 142                credit_refill = min(link_percentage * min_multiplier,
 143                                    MAX_CREDIT_REFILL);
 144                p->data_credits_refill = (u16)credit_refill;
 145
 146                /* Calculate maximum credit for the TC */
 147                credit_max = (link_percentage * MAX_CREDIT) / 100;
 148
 149                /*
 150                 * Adjustment based on rule checking, if the percentage
 151                 * of a TC is too small, the maximum credit may not be
 152                 * enough to send out a jumbo frame in data plane arbitration.
 153                 */
 154                if (credit_max && (credit_max < min_credit))
 155                        credit_max = min_credit;
 156
 157                if (direction == DCB_TX_CONFIG) {
 158                        /*
 159                         * Adjustment based on rule checking, if the
 160                         * percentage of a TC is too small, the maximum
 161                         * credit may not be enough to send out a TSO
 162                         * packet in descriptor plane arbitration.
 163                         */
 164                        if ((hw->mac.type == ixgbe_mac_82598EB) &&
 165                            credit_max &&
 166                            (credit_max < MINIMUM_CREDIT_FOR_TSO))
 167                                credit_max = MINIMUM_CREDIT_FOR_TSO;
 168
 169                        dcb_config->tc_config[i].desc_credits_max =
 170                                (u16)credit_max;
 171                }
 172
 173                p->data_credits_max = (u16)credit_max;
 174        }
 175
 176out:
 177        return ret_val;
 178}
 179
 180void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
 181{
 182        int i;
 183
 184        *pfc_en = 0;
 185        for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
 186                *pfc_en |= (cfg->tc_config[i].dcb_pfc & 0xF) << i;
 187}
 188
 189void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
 190                             u16 *refill)
 191{
 192        struct tc_bw_alloc *p;
 193        int i;
 194
 195        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 196                p = &cfg->tc_config[i].path[direction];
 197                refill[i] = p->data_credits_refill;
 198        }
 199}
 200
 201void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
 202{
 203        int i;
 204
 205        for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
 206                max[i] = cfg->tc_config[i].desc_credits_max;
 207}
 208
 209void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
 210                            u8 *bwgid)
 211{
 212        struct tc_bw_alloc *p;
 213        int i;
 214
 215        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 216                p = &cfg->tc_config[i].path[direction];
 217                bwgid[i] = p->bwg_id;
 218        }
 219}
 220
 221void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
 222                            u8 *ptype)
 223{
 224        struct tc_bw_alloc *p;
 225        int i;
 226
 227        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 228                p = &cfg->tc_config[i].path[direction];
 229                ptype[i] = p->prio_type;
 230        }
 231}
 232
 233/**
 234 * ixgbe_dcb_hw_config - Config and enable DCB
 235 * @hw: pointer to hardware structure
 236 * @dcb_config: pointer to ixgbe_dcb_config structure
 237 *
 238 * Configure dcb settings and enable dcb mode.
 239 */
 240s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
 241                        struct ixgbe_dcb_config *dcb_config)
 242{
 243        s32 ret = 0;
 244        u8 pfc_en;
 245        u8 ptype[MAX_TRAFFIC_CLASS];
 246        u8 bwgid[MAX_TRAFFIC_CLASS];
 247        u16 refill[MAX_TRAFFIC_CLASS];
 248        u16 max[MAX_TRAFFIC_CLASS];
 249        /* CEE does not define a priority to tc mapping so map 1:1 */
 250        u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7};
 251
 252        /* Unpack CEE standard containers */
 253        ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
 254        ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
 255        ixgbe_dcb_unpack_max(dcb_config, max);
 256        ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
 257        ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
 258
 259        switch (hw->mac.type) {
 260        case ixgbe_mac_82598EB:
 261                ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->rx_pba_cfg,
 262                                                pfc_en, refill, max, bwgid,
 263                                                ptype);
 264                break;
 265        case ixgbe_mac_82599EB:
 266        case ixgbe_mac_X540:
 267                ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->rx_pba_cfg,
 268                                                pfc_en, refill, max, bwgid,
 269                                                ptype, prio_tc);
 270                break;
 271        default:
 272                break;
 273        }
 274        return ret;
 275}
 276
 277/* Helper routines to abstract HW specifics from DCB netlink ops */
 278s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en)
 279{
 280        int ret = -EINVAL;
 281
 282        switch (hw->mac.type) {
 283        case ixgbe_mac_82598EB:
 284                ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
 285                break;
 286        case ixgbe_mac_82599EB:
 287        case ixgbe_mac_X540:
 288                ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en);
 289                break;
 290        default:
 291                break;
 292        }
 293        return ret;
 294}
 295
 296s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
 297                            u16 *refill, u16 *max, u8 *bwg_id,
 298                            u8 *prio_type, u8 *prio_tc)
 299{
 300        switch (hw->mac.type) {
 301        case ixgbe_mac_82598EB:
 302                ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
 303                                                        prio_type);
 304                ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
 305                                                             bwg_id, prio_type);
 306                ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
 307                                                             bwg_id, prio_type);
 308                break;
 309        case ixgbe_mac_82599EB:
 310        case ixgbe_mac_X540:
 311                ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
 312                                                  bwg_id, prio_type, prio_tc);
 313                ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
 314                                                       bwg_id, prio_type);
 315                ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id,
 316                                                       prio_type, prio_tc);
 317                break;
 318        default:
 319                break;
 320        }
 321        return 0;
 322}
 323