linux/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 1999 - 2018 Intel Corporation. */
   3
   4#include "ixgbe.h"
   5#include <linux/dcbnl.h>
   6#include "ixgbe_dcb_82598.h"
   7#include "ixgbe_dcb_82599.h"
   8#include "ixgbe_sriov.h"
   9
  10/* Callbacks for DCB netlink in the kernel */
  11#define BIT_DCB_MODE    0x01
  12#define BIT_PFC         0x02
  13#define BIT_PG_RX       0x04
  14#define BIT_PG_TX       0x08
  15#define BIT_APP_UPCHG   0x10
  16#define BIT_LINKSPEED   0x80
  17
  18/* Responses for the DCB_C_SET_ALL command */
  19#define DCB_HW_CHG_RST  0  /* DCB configuration changed with reset */
  20#define DCB_NO_HW_CHG   1  /* DCB configuration did not change */
  21#define DCB_HW_CHG      2  /* DCB configuration changed, no reset */
  22
  23static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max)
  24{
  25        struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg;
  26        struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg;
  27        struct tc_configuration *src = NULL;
  28        struct tc_configuration *dst = NULL;
  29        int i, j;
  30        int tx = DCB_TX_CONFIG;
  31        int rx = DCB_RX_CONFIG;
  32        int changes = 0;
  33#ifdef IXGBE_FCOE
  34        struct dcb_app app = {
  35                              .selector = DCB_APP_IDTYPE_ETHTYPE,
  36                              .protocol = ETH_P_FCOE,
  37                             };
  38        u8 up = dcb_getapp(adapter->netdev, &app);
  39
  40        if (up && !(up & BIT(adapter->fcoe.up)))
  41                changes |= BIT_APP_UPCHG;
  42#endif
  43
  44        for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) {
  45                src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0];
  46                dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0];
  47
  48                if (dst->path[tx].prio_type != src->path[tx].prio_type) {
  49                        dst->path[tx].prio_type = src->path[tx].prio_type;
  50                        changes |= BIT_PG_TX;
  51                }
  52
  53                if (dst->path[tx].bwg_id != src->path[tx].bwg_id) {
  54                        dst->path[tx].bwg_id = src->path[tx].bwg_id;
  55                        changes |= BIT_PG_TX;
  56                }
  57
  58                if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) {
  59                        dst->path[tx].bwg_percent = src->path[tx].bwg_percent;
  60                        changes |= BIT_PG_TX;
  61                }
  62
  63                if (dst->path[tx].up_to_tc_bitmap !=
  64                                src->path[tx].up_to_tc_bitmap) {
  65                        dst->path[tx].up_to_tc_bitmap =
  66                                src->path[tx].up_to_tc_bitmap;
  67                        changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG);
  68                }
  69
  70                if (dst->path[rx].prio_type != src->path[rx].prio_type) {
  71                        dst->path[rx].prio_type = src->path[rx].prio_type;
  72                        changes |= BIT_PG_RX;
  73                }
  74
  75                if (dst->path[rx].bwg_id != src->path[rx].bwg_id) {
  76                        dst->path[rx].bwg_id = src->path[rx].bwg_id;
  77                        changes |= BIT_PG_RX;
  78                }
  79
  80                if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) {
  81                        dst->path[rx].bwg_percent = src->path[rx].bwg_percent;
  82                        changes |= BIT_PG_RX;
  83                }
  84
  85                if (dst->path[rx].up_to_tc_bitmap !=
  86                                src->path[rx].up_to_tc_bitmap) {
  87                        dst->path[rx].up_to_tc_bitmap =
  88                                src->path[rx].up_to_tc_bitmap;
  89                        changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG);
  90                }
  91        }
  92
  93        for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) {
  94                j = i - DCB_PG_ATTR_BW_ID_0;
  95                if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) {
  96                        dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j];
  97                        changes |= BIT_PG_TX;
  98                }
  99                if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) {
 100                        dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j];
 101                        changes |= BIT_PG_RX;
 102                }
 103        }
 104
 105        for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) {
 106                j = i - DCB_PFC_UP_ATTR_0;
 107                if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) {
 108                        dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc;
 109                        changes |= BIT_PFC;
 110                }
 111        }
 112
 113        if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) {
 114                dcfg->pfc_mode_enable = scfg->pfc_mode_enable;
 115                changes |= BIT_PFC;
 116        }
 117
 118        return changes;
 119}
 120
 121static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
 122{
 123        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 124
 125        return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
 126}
 127
 128static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 129{
 130        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 131
 132        /* Fail command if not in CEE mode */
 133        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
 134                return 1;
 135
 136        /* verify there is something to do, if not then exit */
 137        if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
 138                return 0;
 139
 140        return !!ixgbe_setup_tc(netdev,
 141                                state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0);
 142}
 143
 144static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
 145                                         u8 *perm_addr)
 146{
 147        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 148        int i, j;
 149
 150        memset(perm_addr, 0xff, MAX_ADDR_LEN);
 151
 152        for (i = 0; i < netdev->addr_len; i++)
 153                perm_addr[i] = adapter->hw.mac.perm_addr[i];
 154
 155        switch (adapter->hw.mac.type) {
 156        case ixgbe_mac_82599EB:
 157        case ixgbe_mac_X540:
 158        case ixgbe_mac_X550:
 159                for (j = 0; j < netdev->addr_len; j++, i++)
 160                        perm_addr[i] = adapter->hw.mac.san_addr[j];
 161                break;
 162        default:
 163                break;
 164        }
 165}
 166
 167static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
 168                                         u8 prio, u8 bwg_id, u8 bw_pct,
 169                                         u8 up_map)
 170{
 171        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 172
 173        if (prio != DCB_ATTR_VALUE_UNDEFINED)
 174                adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio;
 175        if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
 176                adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id;
 177        if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
 178                adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent =
 179                        bw_pct;
 180        if (up_map != DCB_ATTR_VALUE_UNDEFINED)
 181                adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap =
 182                        up_map;
 183}
 184
 185static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
 186                                          u8 bw_pct)
 187{
 188        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 189
 190        adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
 191}
 192
 193static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
 194                                         u8 prio, u8 bwg_id, u8 bw_pct,
 195                                         u8 up_map)
 196{
 197        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 198
 199        if (prio != DCB_ATTR_VALUE_UNDEFINED)
 200                adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio;
 201        if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
 202                adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id;
 203        if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
 204                adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent =
 205                        bw_pct;
 206        if (up_map != DCB_ATTR_VALUE_UNDEFINED)
 207                adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap =
 208                        up_map;
 209}
 210
 211static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
 212                                          u8 bw_pct)
 213{
 214        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 215
 216        adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
 217}
 218
 219static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
 220                                         u8 *prio, u8 *bwg_id, u8 *bw_pct,
 221                                         u8 *up_map)
 222{
 223        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 224
 225        *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type;
 226        *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id;
 227        *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent;
 228        *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap;
 229}
 230
 231static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
 232                                          u8 *bw_pct)
 233{
 234        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 235
 236        *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id];
 237}
 238
 239static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc,
 240                                         u8 *prio, u8 *bwg_id, u8 *bw_pct,
 241                                         u8 *up_map)
 242{
 243        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 244
 245        *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type;
 246        *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id;
 247        *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent;
 248        *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap;
 249}
 250
 251static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
 252                                          u8 *bw_pct)
 253{
 254        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 255
 256        *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id];
 257}
 258
 259static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority,
 260                                    u8 setting)
 261{
 262        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 263
 264        adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
 265        if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
 266            adapter->dcb_cfg.tc_config[priority].dcb_pfc)
 267                adapter->temp_dcb_cfg.pfc_mode_enable = true;
 268}
 269
 270static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
 271                                    u8 *setting)
 272{
 273        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 274
 275        *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc;
 276}
 277
 278static void ixgbe_dcbnl_devreset(struct net_device *dev)
 279{
 280        struct ixgbe_adapter *adapter = netdev_priv(dev);
 281
 282        while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 283                usleep_range(1000, 2000);
 284
 285        if (netif_running(dev))
 286                dev->netdev_ops->ndo_stop(dev);
 287
 288        ixgbe_clear_interrupt_scheme(adapter);
 289        ixgbe_init_interrupt_scheme(adapter);
 290
 291        if (netif_running(dev))
 292                dev->netdev_ops->ndo_open(dev);
 293
 294        clear_bit(__IXGBE_RESETTING, &adapter->state);
 295}
 296
 297static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 298{
 299        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 300        struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg;
 301        struct ixgbe_hw *hw = &adapter->hw;
 302        int ret = DCB_NO_HW_CHG;
 303        int i;
 304
 305        /* Fail command if not in CEE mode */
 306        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
 307                return DCB_NO_HW_CHG;
 308
 309        adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter,
 310                                                      MAX_TRAFFIC_CLASS);
 311        if (!adapter->dcb_set_bitmap)
 312                return DCB_NO_HW_CHG;
 313
 314        if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
 315                u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
 316                u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
 317                /* Priority to TC mapping in CEE case default to 1:1 */
 318                u8 prio_tc[MAX_USER_PRIORITY];
 319                int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 320
 321#ifdef IXGBE_FCOE
 322                if (adapter->netdev->features & NETIF_F_FCOE_MTU)
 323                        max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
 324#endif
 325
 326                ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
 327                                               DCB_TX_CONFIG);
 328                ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
 329                                               DCB_RX_CONFIG);
 330
 331                ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill);
 332                ixgbe_dcb_unpack_max(dcb_cfg, max);
 333                ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id);
 334                ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type);
 335                ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
 336
 337                ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id,
 338                                        prio_type, prio_tc);
 339
 340                for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 341                        netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
 342
 343                ret = DCB_HW_CHG_RST;
 344        }
 345
 346        if (adapter->dcb_set_bitmap & BIT_PFC) {
 347                if (dcb_cfg->pfc_mode_enable) {
 348                        u8 pfc_en;
 349                        u8 prio_tc[MAX_USER_PRIORITY];
 350
 351                        ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
 352                        ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en);
 353                        ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc);
 354                } else {
 355                        hw->mac.ops.fc_enable(hw);
 356                }
 357
 358                ixgbe_set_rx_drop_en(adapter);
 359
 360                ret = DCB_HW_CHG;
 361        }
 362
 363#ifdef IXGBE_FCOE
 364        /* Reprogram FCoE hardware offloads when the traffic class
 365         * FCoE is using changes. This happens if the APP info
 366         * changes or the up2tc mapping is updated.
 367         */
 368        if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
 369                struct dcb_app app = {
 370                                      .selector = DCB_APP_IDTYPE_ETHTYPE,
 371                                      .protocol = ETH_P_FCOE,
 372                                     };
 373                u8 up = dcb_getapp(netdev, &app);
 374
 375                adapter->fcoe.up = ffs(up) - 1;
 376                ixgbe_dcbnl_devreset(netdev);
 377                ret = DCB_HW_CHG_RST;
 378        }
 379#endif
 380
 381        adapter->dcb_set_bitmap = 0x00;
 382        return ret;
 383}
 384
 385static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
 386{
 387        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 388
 389        switch (capid) {
 390        case DCB_CAP_ATTR_PG:
 391                *cap = true;
 392                break;
 393        case DCB_CAP_ATTR_PFC:
 394                *cap = true;
 395                break;
 396        case DCB_CAP_ATTR_UP2TC:
 397                *cap = false;
 398                break;
 399        case DCB_CAP_ATTR_PG_TCS:
 400                *cap = 0x80;
 401                break;
 402        case DCB_CAP_ATTR_PFC_TCS:
 403                *cap = 0x80;
 404                break;
 405        case DCB_CAP_ATTR_GSP:
 406                *cap = true;
 407                break;
 408        case DCB_CAP_ATTR_BCN:
 409                *cap = false;
 410                break;
 411        case DCB_CAP_ATTR_DCBX:
 412                *cap = adapter->dcbx_cap;
 413                break;
 414        default:
 415                *cap = false;
 416                break;
 417        }
 418
 419        return 0;
 420}
 421
 422static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
 423{
 424        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 425
 426        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 427                switch (tcid) {
 428                case DCB_NUMTCS_ATTR_PG:
 429                        *num = adapter->dcb_cfg.num_tcs.pg_tcs;
 430                        break;
 431                case DCB_NUMTCS_ATTR_PFC:
 432                        *num = adapter->dcb_cfg.num_tcs.pfc_tcs;
 433                        break;
 434                default:
 435                        return -EINVAL;
 436                }
 437        } else {
 438                return -EINVAL;
 439        }
 440
 441        return 0;
 442}
 443
 444static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
 445{
 446        return -EINVAL;
 447}
 448
 449static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
 450{
 451        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 452
 453        return adapter->dcb_cfg.pfc_mode_enable;
 454}
 455
 456static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
 457{
 458        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 459
 460        adapter->temp_dcb_cfg.pfc_mode_enable = state;
 461}
 462
 463/**
 464 * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority
 465 * @netdev : the corresponding netdev
 466 * @idtype : identifies the id as ether type or TCP/UDP port number
 467 * @id: id is either ether type or TCP/UDP port number
 468 *
 469 * Returns : on success, returns a non-zero 802.1p user priority bitmap
 470 * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an
 471 * error.
 472 */
 473static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
 474{
 475        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 476        struct dcb_app app = {
 477                                .selector = idtype,
 478                                .protocol = id,
 479                             };
 480
 481        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
 482                return -EINVAL;
 483
 484        return dcb_getapp(netdev, &app);
 485}
 486
 487static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
 488                                   struct ieee_ets *ets)
 489{
 490        struct ixgbe_adapter *adapter = netdev_priv(dev);
 491        struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets;
 492
 493        ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs;
 494
 495        /* No IEEE PFC settings available */
 496        if (!my_ets)
 497                return 0;
 498
 499        ets->cbs = my_ets->cbs;
 500        memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
 501        memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
 502        memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
 503        memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
 504        return 0;
 505}
 506
 507static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
 508                                   struct ieee_ets *ets)
 509{
 510        struct ixgbe_adapter *adapter = netdev_priv(dev);
 511        int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
 512        int i, err;
 513        __u8 max_tc = 0;
 514        __u8 map_chg = 0;
 515
 516        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 517                return -EINVAL;
 518
 519        if (!adapter->ixgbe_ieee_ets) {
 520                adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
 521                                                  GFP_KERNEL);
 522                if (!adapter->ixgbe_ieee_ets)
 523                        return -ENOMEM;
 524
 525                /* initialize UP2TC mappings to invalid value */
 526                for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 527                        adapter->ixgbe_ieee_ets->prio_tc[i] =
 528                                IEEE_8021QAZ_MAX_TCS;
 529                /* if possible update UP2TC mappings from HW */
 530                ixgbe_dcb_read_rtrup2tc(&adapter->hw,
 531                                        adapter->ixgbe_ieee_ets->prio_tc);
 532        }
 533
 534        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 535                if (ets->prio_tc[i] > max_tc)
 536                        max_tc = ets->prio_tc[i];
 537                if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i])
 538                        map_chg = 1;
 539        }
 540
 541        memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
 542
 543        if (max_tc)
 544                max_tc++;
 545
 546        if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs)
 547                return -EINVAL;
 548
 549        if (max_tc != adapter->hw_tcs) {
 550                err = ixgbe_setup_tc(dev, max_tc);
 551                if (err)
 552                        return err;
 553        } else if (map_chg) {
 554                ixgbe_dcbnl_devreset(dev);
 555        }
 556
 557        return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
 558}
 559
 560static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev,
 561                                   struct ieee_pfc *pfc)
 562{
 563        struct ixgbe_adapter *adapter = netdev_priv(dev);
 564        struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc;
 565        int i;
 566
 567        pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs;
 568
 569        /* No IEEE PFC settings available */
 570        if (!my_pfc)
 571                return 0;
 572
 573        pfc->pfc_en = my_pfc->pfc_en;
 574        pfc->mbc = my_pfc->mbc;
 575        pfc->delay = my_pfc->delay;
 576
 577        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
 578                pfc->requests[i] = adapter->stats.pxoffrxc[i];
 579                pfc->indications[i] = adapter->stats.pxofftxc[i];
 580        }
 581
 582        return 0;
 583}
 584
 585static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
 586                                   struct ieee_pfc *pfc)
 587{
 588        struct ixgbe_adapter *adapter = netdev_priv(dev);
 589        struct ixgbe_hw *hw = &adapter->hw;
 590        u8 *prio_tc;
 591        int err;
 592
 593        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 594                return -EINVAL;
 595
 596        if (!adapter->ixgbe_ieee_pfc) {
 597                adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
 598                                                  GFP_KERNEL);
 599                if (!adapter->ixgbe_ieee_pfc)
 600                        return -ENOMEM;
 601        }
 602
 603        prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
 604        memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc));
 605
 606        /* Enable link flow control parameters if PFC is disabled */
 607        if (pfc->pfc_en)
 608                err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc);
 609        else
 610                err = hw->mac.ops.fc_enable(hw);
 611
 612        ixgbe_set_rx_drop_en(adapter);
 613
 614        return err;
 615}
 616
 617static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
 618                                   struct dcb_app *app)
 619{
 620        struct ixgbe_adapter *adapter = netdev_priv(dev);
 621        int err;
 622
 623        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 624                return -EINVAL;
 625
 626        err = dcb_ieee_setapp(dev, app);
 627        if (err)
 628                return err;
 629
 630#ifdef IXGBE_FCOE
 631        if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
 632            app->protocol == ETH_P_FCOE) {
 633                u8 app_mask = dcb_ieee_getapp_mask(dev, app);
 634
 635                if (app_mask & BIT(adapter->fcoe.up))
 636                        return 0;
 637
 638                adapter->fcoe.up = app->priority;
 639                ixgbe_dcbnl_devreset(dev);
 640        }
 641#endif
 642
 643        /* VF devices should use default UP when available */
 644        if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
 645            app->protocol == 0) {
 646                int vf;
 647
 648                adapter->default_up = app->priority;
 649
 650                for (vf = 0; vf < adapter->num_vfs; vf++) {
 651                        struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
 652
 653                        if (!vfinfo->pf_qos)
 654                                ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
 655                                                app->priority, vf);
 656                }
 657        }
 658
 659        return 0;
 660}
 661
 662static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,
 663                                   struct dcb_app *app)
 664{
 665        struct ixgbe_adapter *adapter = netdev_priv(dev);
 666        int err;
 667
 668        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 669                return -EINVAL;
 670
 671        err = dcb_ieee_delapp(dev, app);
 672
 673#ifdef IXGBE_FCOE
 674        if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
 675            app->protocol == ETH_P_FCOE) {
 676                u8 app_mask = dcb_ieee_getapp_mask(dev, app);
 677
 678                if (app_mask & BIT(adapter->fcoe.up))
 679                        return 0;
 680
 681                adapter->fcoe.up = app_mask ?
 682                                   ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC;
 683                ixgbe_dcbnl_devreset(dev);
 684        }
 685#endif
 686        /* IF default priority is being removed clear VF default UP */
 687        if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
 688            app->protocol == 0 && adapter->default_up == app->priority) {
 689                int vf;
 690                long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app);
 691                int qos = app_mask ? find_first_bit(&app_mask, 8) : 0;
 692
 693                adapter->default_up = qos;
 694
 695                for (vf = 0; vf < adapter->num_vfs; vf++) {
 696                        struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
 697
 698                        if (!vfinfo->pf_qos)
 699                                ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
 700                                                qos, vf);
 701                }
 702        }
 703
 704        return err;
 705}
 706
 707static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
 708{
 709        struct ixgbe_adapter *adapter = netdev_priv(dev);
 710        return adapter->dcbx_cap;
 711}
 712
 713static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
 714{
 715        struct ixgbe_adapter *adapter = netdev_priv(dev);
 716        struct ieee_ets ets = {0};
 717        struct ieee_pfc pfc = {0};
 718        int err = 0;
 719
 720        /* no support for LLD_MANAGED modes or CEE+IEEE */
 721        if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
 722            ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
 723            !(mode & DCB_CAP_DCBX_HOST))
 724                return 1;
 725
 726        if (mode == adapter->dcbx_cap)
 727                return 0;
 728
 729        adapter->dcbx_cap = mode;
 730
 731        /* ETS and PFC defaults */
 732        ets.ets_cap = 8;
 733        pfc.pfc_cap = 8;
 734
 735        if (mode & DCB_CAP_DCBX_VER_IEEE) {
 736                ixgbe_dcbnl_ieee_setets(dev, &ets);
 737                ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
 738        } else if (mode & DCB_CAP_DCBX_VER_CEE) {
 739                u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG;
 740
 741                adapter->dcb_set_bitmap |= mask;
 742                ixgbe_dcbnl_set_all(dev);
 743        } else {
 744                /* Drop into single TC mode strict priority as this
 745                 * indicates CEE and IEEE versions are disabled
 746                 */
 747                ixgbe_dcbnl_ieee_setets(dev, &ets);
 748                ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
 749                err = ixgbe_setup_tc(dev, 0);
 750        }
 751
 752        return err ? 1 : 0;
 753}
 754
 755const struct dcbnl_rtnl_ops ixgbe_dcbnl_ops = {
 756        .ieee_getets    = ixgbe_dcbnl_ieee_getets,
 757        .ieee_setets    = ixgbe_dcbnl_ieee_setets,
 758        .ieee_getpfc    = ixgbe_dcbnl_ieee_getpfc,
 759        .ieee_setpfc    = ixgbe_dcbnl_ieee_setpfc,
 760        .ieee_setapp    = ixgbe_dcbnl_ieee_setapp,
 761        .ieee_delapp    = ixgbe_dcbnl_ieee_delapp,
 762        .getstate       = ixgbe_dcbnl_get_state,
 763        .setstate       = ixgbe_dcbnl_set_state,
 764        .getpermhwaddr  = ixgbe_dcbnl_get_perm_hw_addr,
 765        .setpgtccfgtx   = ixgbe_dcbnl_set_pg_tc_cfg_tx,
 766        .setpgbwgcfgtx  = ixgbe_dcbnl_set_pg_bwg_cfg_tx,
 767        .setpgtccfgrx   = ixgbe_dcbnl_set_pg_tc_cfg_rx,
 768        .setpgbwgcfgrx  = ixgbe_dcbnl_set_pg_bwg_cfg_rx,
 769        .getpgtccfgtx   = ixgbe_dcbnl_get_pg_tc_cfg_tx,
 770        .getpgbwgcfgtx  = ixgbe_dcbnl_get_pg_bwg_cfg_tx,
 771        .getpgtccfgrx   = ixgbe_dcbnl_get_pg_tc_cfg_rx,
 772        .getpgbwgcfgrx  = ixgbe_dcbnl_get_pg_bwg_cfg_rx,
 773        .setpfccfg      = ixgbe_dcbnl_set_pfc_cfg,
 774        .getpfccfg      = ixgbe_dcbnl_get_pfc_cfg,
 775        .setall         = ixgbe_dcbnl_set_all,
 776        .getcap         = ixgbe_dcbnl_getcap,
 777        .getnumtcs      = ixgbe_dcbnl_getnumtcs,
 778        .setnumtcs      = ixgbe_dcbnl_setnumtcs,
 779        .getpfcstate    = ixgbe_dcbnl_getpfcstate,
 780        .setpfcstate    = ixgbe_dcbnl_setpfcstate,
 781        .getapp         = ixgbe_dcbnl_getapp,
 782        .getdcbx        = ixgbe_dcbnl_getdcbx,
 783        .setdcbx        = ixgbe_dcbnl_setdcbx,
 784};
 785