Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 1999 - 2018 Intel Corporation. */
0003 
0004 #include "ixgbe.h"
0005 #include <linux/dcbnl.h>
0006 #include "ixgbe_dcb_82598.h"
0007 #include "ixgbe_dcb_82599.h"
0008 #include "ixgbe_sriov.h"
0009 
0010 /* Callbacks for DCB netlink in the kernel */
0011 #define BIT_PFC     0x02
0012 #define BIT_PG_RX   0x04
0013 #define BIT_PG_TX   0x08
0014 #define BIT_APP_UPCHG   0x10
0015 
0016 /* Responses for the DCB_C_SET_ALL command */
0017 #define DCB_HW_CHG_RST  0  /* DCB configuration changed with reset */
0018 #define DCB_NO_HW_CHG   1  /* DCB configuration did not change */
0019 #define DCB_HW_CHG      2  /* DCB configuration changed, no reset */
0020 
0021 static int ixgbe_copy_dcb_cfg(struct ixgbe_adapter *adapter, int tc_max)
0022 {
0023     struct ixgbe_dcb_config *scfg = &adapter->temp_dcb_cfg;
0024     struct ixgbe_dcb_config *dcfg = &adapter->dcb_cfg;
0025     struct tc_configuration *src = NULL;
0026     struct tc_configuration *dst = NULL;
0027     int i, j;
0028     int tx = DCB_TX_CONFIG;
0029     int rx = DCB_RX_CONFIG;
0030     int changes = 0;
0031 #ifdef IXGBE_FCOE
0032     struct dcb_app app = {
0033                   .selector = DCB_APP_IDTYPE_ETHTYPE,
0034                   .protocol = ETH_P_FCOE,
0035                  };
0036     u8 up = dcb_getapp(adapter->netdev, &app);
0037 
0038     if (up && !(up & BIT(adapter->fcoe.up)))
0039         changes |= BIT_APP_UPCHG;
0040 #endif
0041 
0042     for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) {
0043         src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0];
0044         dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0];
0045 
0046         if (dst->path[tx].prio_type != src->path[tx].prio_type) {
0047             dst->path[tx].prio_type = src->path[tx].prio_type;
0048             changes |= BIT_PG_TX;
0049         }
0050 
0051         if (dst->path[tx].bwg_id != src->path[tx].bwg_id) {
0052             dst->path[tx].bwg_id = src->path[tx].bwg_id;
0053             changes |= BIT_PG_TX;
0054         }
0055 
0056         if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) {
0057             dst->path[tx].bwg_percent = src->path[tx].bwg_percent;
0058             changes |= BIT_PG_TX;
0059         }
0060 
0061         if (dst->path[tx].up_to_tc_bitmap !=
0062                 src->path[tx].up_to_tc_bitmap) {
0063             dst->path[tx].up_to_tc_bitmap =
0064                 src->path[tx].up_to_tc_bitmap;
0065             changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG);
0066         }
0067 
0068         if (dst->path[rx].prio_type != src->path[rx].prio_type) {
0069             dst->path[rx].prio_type = src->path[rx].prio_type;
0070             changes |= BIT_PG_RX;
0071         }
0072 
0073         if (dst->path[rx].bwg_id != src->path[rx].bwg_id) {
0074             dst->path[rx].bwg_id = src->path[rx].bwg_id;
0075             changes |= BIT_PG_RX;
0076         }
0077 
0078         if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) {
0079             dst->path[rx].bwg_percent = src->path[rx].bwg_percent;
0080             changes |= BIT_PG_RX;
0081         }
0082 
0083         if (dst->path[rx].up_to_tc_bitmap !=
0084                 src->path[rx].up_to_tc_bitmap) {
0085             dst->path[rx].up_to_tc_bitmap =
0086                 src->path[rx].up_to_tc_bitmap;
0087             changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG);
0088         }
0089     }
0090 
0091     for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) {
0092         j = i - DCB_PG_ATTR_BW_ID_0;
0093         if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) {
0094             dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j];
0095             changes |= BIT_PG_TX;
0096         }
0097         if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) {
0098             dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j];
0099             changes |= BIT_PG_RX;
0100         }
0101     }
0102 
0103     for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) {
0104         j = i - DCB_PFC_UP_ATTR_0;
0105         if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) {
0106             dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc;
0107             changes |= BIT_PFC;
0108         }
0109     }
0110 
0111     if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) {
0112         dcfg->pfc_mode_enable = scfg->pfc_mode_enable;
0113         changes |= BIT_PFC;
0114     }
0115 
0116     return changes;
0117 }
0118 
0119 static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
0120 {
0121     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0122 
0123     return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
0124 }
0125 
0126 static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
0127 {
0128     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0129 
0130     /* Fail command if not in CEE mode */
0131     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
0132         return 1;
0133 
0134     /* verify there is something to do, if not then exit */
0135     if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
0136         return 0;
0137 
0138     return !!ixgbe_setup_tc(netdev,
0139                 state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0);
0140 }
0141 
0142 static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
0143                      u8 *perm_addr)
0144 {
0145     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0146     int i, j;
0147 
0148     memset(perm_addr, 0xff, MAX_ADDR_LEN);
0149 
0150     for (i = 0; i < netdev->addr_len; i++)
0151         perm_addr[i] = adapter->hw.mac.perm_addr[i];
0152 
0153     switch (adapter->hw.mac.type) {
0154     case ixgbe_mac_82599EB:
0155     case ixgbe_mac_X540:
0156     case ixgbe_mac_X550:
0157         for (j = 0; j < netdev->addr_len; j++, i++)
0158             perm_addr[i] = adapter->hw.mac.san_addr[j];
0159         break;
0160     default:
0161         break;
0162     }
0163 }
0164 
0165 static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
0166                      u8 prio, u8 bwg_id, u8 bw_pct,
0167                      u8 up_map)
0168 {
0169     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0170 
0171     if (prio != DCB_ATTR_VALUE_UNDEFINED)
0172         adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio;
0173     if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
0174         adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id = bwg_id;
0175     if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
0176         adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent =
0177             bw_pct;
0178     if (up_map != DCB_ATTR_VALUE_UNDEFINED)
0179         adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap =
0180             up_map;
0181 }
0182 
0183 static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
0184                       u8 bw_pct)
0185 {
0186     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0187 
0188     adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
0189 }
0190 
0191 static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
0192                      u8 prio, u8 bwg_id, u8 bw_pct,
0193                      u8 up_map)
0194 {
0195     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0196 
0197     if (prio != DCB_ATTR_VALUE_UNDEFINED)
0198         adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio;
0199     if (bwg_id != DCB_ATTR_VALUE_UNDEFINED)
0200         adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id = bwg_id;
0201     if (bw_pct != DCB_ATTR_VALUE_UNDEFINED)
0202         adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent =
0203             bw_pct;
0204     if (up_map != DCB_ATTR_VALUE_UNDEFINED)
0205         adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap =
0206             up_map;
0207 }
0208 
0209 static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
0210                       u8 bw_pct)
0211 {
0212     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0213 
0214     adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
0215 }
0216 
0217 static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
0218                      u8 *prio, u8 *bwg_id, u8 *bw_pct,
0219                      u8 *up_map)
0220 {
0221     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0222 
0223     *prio = adapter->dcb_cfg.tc_config[tc].path[0].prio_type;
0224     *bwg_id = adapter->dcb_cfg.tc_config[tc].path[0].bwg_id;
0225     *bw_pct = adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent;
0226     *up_map = adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap;
0227 }
0228 
0229 static void ixgbe_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
0230                       u8 *bw_pct)
0231 {
0232     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0233 
0234     *bw_pct = adapter->dcb_cfg.bw_percentage[0][bwg_id];
0235 }
0236 
0237 static void ixgbe_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int tc,
0238                      u8 *prio, u8 *bwg_id, u8 *bw_pct,
0239                      u8 *up_map)
0240 {
0241     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0242 
0243     *prio = adapter->dcb_cfg.tc_config[tc].path[1].prio_type;
0244     *bwg_id = adapter->dcb_cfg.tc_config[tc].path[1].bwg_id;
0245     *bw_pct = adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent;
0246     *up_map = adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap;
0247 }
0248 
0249 static void ixgbe_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
0250                       u8 *bw_pct)
0251 {
0252     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0253 
0254     *bw_pct = adapter->dcb_cfg.bw_percentage[1][bwg_id];
0255 }
0256 
0257 static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority,
0258                     u8 setting)
0259 {
0260     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0261 
0262     adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
0263     if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
0264         adapter->dcb_cfg.tc_config[priority].dcb_pfc)
0265         adapter->temp_dcb_cfg.pfc_mode_enable = true;
0266 }
0267 
0268 static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
0269                     u8 *setting)
0270 {
0271     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0272 
0273     *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc;
0274 }
0275 
0276 static void ixgbe_dcbnl_devreset(struct net_device *dev)
0277 {
0278     struct ixgbe_adapter *adapter = netdev_priv(dev);
0279 
0280     while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
0281         usleep_range(1000, 2000);
0282 
0283     if (netif_running(dev))
0284         dev->netdev_ops->ndo_stop(dev);
0285 
0286     ixgbe_clear_interrupt_scheme(adapter);
0287     ixgbe_init_interrupt_scheme(adapter);
0288 
0289     if (netif_running(dev))
0290         dev->netdev_ops->ndo_open(dev);
0291 
0292     clear_bit(__IXGBE_RESETTING, &adapter->state);
0293 }
0294 
0295 static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
0296 {
0297     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0298     struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg;
0299     struct ixgbe_hw *hw = &adapter->hw;
0300     int ret = DCB_NO_HW_CHG;
0301     int i;
0302 
0303     /* Fail command if not in CEE mode */
0304     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
0305         return DCB_NO_HW_CHG;
0306 
0307     adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter,
0308                               MAX_TRAFFIC_CLASS);
0309     if (!adapter->dcb_set_bitmap)
0310         return DCB_NO_HW_CHG;
0311 
0312     if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
0313         u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
0314         u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
0315         /* Priority to TC mapping in CEE case default to 1:1 */
0316         u8 prio_tc[MAX_USER_PRIORITY];
0317         int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
0318 
0319 #ifdef IXGBE_FCOE
0320         if (adapter->netdev->features & NETIF_F_FCOE_MTU)
0321             max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
0322 #endif
0323 
0324         ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
0325                            DCB_TX_CONFIG);
0326         ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
0327                            DCB_RX_CONFIG);
0328 
0329         ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill);
0330         ixgbe_dcb_unpack_max(dcb_cfg, max);
0331         ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id);
0332         ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type);
0333         ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
0334 
0335         ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id,
0336                     prio_type, prio_tc);
0337 
0338         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
0339             netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
0340 
0341         ret = DCB_HW_CHG_RST;
0342     }
0343 
0344     if (adapter->dcb_set_bitmap & BIT_PFC) {
0345         if (dcb_cfg->pfc_mode_enable) {
0346             u8 pfc_en;
0347             u8 prio_tc[MAX_USER_PRIORITY];
0348 
0349             ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
0350             ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en);
0351             ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc);
0352         } else {
0353             hw->mac.ops.fc_enable(hw);
0354         }
0355 
0356         ixgbe_set_rx_drop_en(adapter);
0357 
0358         ret = DCB_HW_CHG;
0359     }
0360 
0361 #ifdef IXGBE_FCOE
0362     /* Reprogram FCoE hardware offloads when the traffic class
0363      * FCoE is using changes. This happens if the APP info
0364      * changes or the up2tc mapping is updated.
0365      */
0366     if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
0367         struct dcb_app app = {
0368                       .selector = DCB_APP_IDTYPE_ETHTYPE,
0369                       .protocol = ETH_P_FCOE,
0370                      };
0371         u8 up = dcb_getapp(netdev, &app);
0372 
0373         adapter->fcoe.up = ffs(up) - 1;
0374         ixgbe_dcbnl_devreset(netdev);
0375         ret = DCB_HW_CHG_RST;
0376     }
0377 #endif
0378 
0379     adapter->dcb_set_bitmap = 0x00;
0380     return ret;
0381 }
0382 
0383 static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
0384 {
0385     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0386 
0387     switch (capid) {
0388     case DCB_CAP_ATTR_PG:
0389         *cap = true;
0390         break;
0391     case DCB_CAP_ATTR_PFC:
0392         *cap = true;
0393         break;
0394     case DCB_CAP_ATTR_UP2TC:
0395         *cap = false;
0396         break;
0397     case DCB_CAP_ATTR_PG_TCS:
0398         *cap = 0x80;
0399         break;
0400     case DCB_CAP_ATTR_PFC_TCS:
0401         *cap = 0x80;
0402         break;
0403     case DCB_CAP_ATTR_GSP:
0404         *cap = true;
0405         break;
0406     case DCB_CAP_ATTR_BCN:
0407         *cap = false;
0408         break;
0409     case DCB_CAP_ATTR_DCBX:
0410         *cap = adapter->dcbx_cap;
0411         break;
0412     default:
0413         *cap = false;
0414         break;
0415     }
0416 
0417     return 0;
0418 }
0419 
0420 static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
0421 {
0422     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0423 
0424     if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
0425         switch (tcid) {
0426         case DCB_NUMTCS_ATTR_PG:
0427             *num = adapter->dcb_cfg.num_tcs.pg_tcs;
0428             break;
0429         case DCB_NUMTCS_ATTR_PFC:
0430             *num = adapter->dcb_cfg.num_tcs.pfc_tcs;
0431             break;
0432         default:
0433             return -EINVAL;
0434         }
0435     } else {
0436         return -EINVAL;
0437     }
0438 
0439     return 0;
0440 }
0441 
0442 static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
0443 {
0444     return -EINVAL;
0445 }
0446 
0447 static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
0448 {
0449     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0450 
0451     return adapter->dcb_cfg.pfc_mode_enable;
0452 }
0453 
0454 static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
0455 {
0456     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0457 
0458     adapter->temp_dcb_cfg.pfc_mode_enable = state;
0459 }
0460 
0461 /**
0462  * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority
0463  * @netdev : the corresponding netdev
0464  * @idtype : identifies the id as ether type or TCP/UDP port number
0465  * @id: id is either ether type or TCP/UDP port number
0466  *
0467  * Returns : on success, returns a non-zero 802.1p user priority bitmap
0468  * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an
0469  * error.
0470  */
0471 static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
0472 {
0473     struct ixgbe_adapter *adapter = netdev_priv(netdev);
0474     struct dcb_app app = {
0475                 .selector = idtype,
0476                 .protocol = id,
0477                  };
0478 
0479     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
0480         return -EINVAL;
0481 
0482     return dcb_getapp(netdev, &app);
0483 }
0484 
0485 static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
0486                    struct ieee_ets *ets)
0487 {
0488     struct ixgbe_adapter *adapter = netdev_priv(dev);
0489     struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets;
0490 
0491     ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs;
0492 
0493     /* No IEEE PFC settings available */
0494     if (!my_ets)
0495         return 0;
0496 
0497     ets->cbs = my_ets->cbs;
0498     memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
0499     memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
0500     memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
0501     memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
0502     return 0;
0503 }
0504 
0505 static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
0506                    struct ieee_ets *ets)
0507 {
0508     struct ixgbe_adapter *adapter = netdev_priv(dev);
0509     int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
0510     int i, err;
0511     __u8 max_tc = 0;
0512     __u8 map_chg = 0;
0513 
0514     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0515         return -EINVAL;
0516 
0517     if (!adapter->ixgbe_ieee_ets) {
0518         adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
0519                           GFP_KERNEL);
0520         if (!adapter->ixgbe_ieee_ets)
0521             return -ENOMEM;
0522 
0523         /* initialize UP2TC mappings to invalid value */
0524         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
0525             adapter->ixgbe_ieee_ets->prio_tc[i] =
0526                 IEEE_8021QAZ_MAX_TCS;
0527         /* if possible update UP2TC mappings from HW */
0528         ixgbe_dcb_read_rtrup2tc(&adapter->hw,
0529                     adapter->ixgbe_ieee_ets->prio_tc);
0530     }
0531 
0532     for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
0533         if (ets->prio_tc[i] > max_tc)
0534             max_tc = ets->prio_tc[i];
0535         if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i])
0536             map_chg = 1;
0537     }
0538 
0539     memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
0540 
0541     if (max_tc)
0542         max_tc++;
0543 
0544     if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs)
0545         return -EINVAL;
0546 
0547     if (max_tc != adapter->hw_tcs) {
0548         err = ixgbe_setup_tc(dev, max_tc);
0549         if (err)
0550             return err;
0551     } else if (map_chg) {
0552         ixgbe_dcbnl_devreset(dev);
0553     }
0554 
0555     return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
0556 }
0557 
0558 static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev,
0559                    struct ieee_pfc *pfc)
0560 {
0561     struct ixgbe_adapter *adapter = netdev_priv(dev);
0562     struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc;
0563     int i;
0564 
0565     pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs;
0566 
0567     /* No IEEE PFC settings available */
0568     if (!my_pfc)
0569         return 0;
0570 
0571     pfc->pfc_en = my_pfc->pfc_en;
0572     pfc->mbc = my_pfc->mbc;
0573     pfc->delay = my_pfc->delay;
0574 
0575     for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
0576         pfc->requests[i] = adapter->stats.pxoffrxc[i];
0577         pfc->indications[i] = adapter->stats.pxofftxc[i];
0578     }
0579 
0580     return 0;
0581 }
0582 
0583 static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
0584                    struct ieee_pfc *pfc)
0585 {
0586     struct ixgbe_adapter *adapter = netdev_priv(dev);
0587     struct ixgbe_hw *hw = &adapter->hw;
0588     u8 *prio_tc;
0589     int err;
0590 
0591     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0592         return -EINVAL;
0593 
0594     if (!adapter->ixgbe_ieee_pfc) {
0595         adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
0596                           GFP_KERNEL);
0597         if (!adapter->ixgbe_ieee_pfc)
0598             return -ENOMEM;
0599     }
0600 
0601     prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
0602     memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc));
0603 
0604     /* Enable link flow control parameters if PFC is disabled */
0605     if (pfc->pfc_en)
0606         err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc);
0607     else
0608         err = hw->mac.ops.fc_enable(hw);
0609 
0610     ixgbe_set_rx_drop_en(adapter);
0611 
0612     return err;
0613 }
0614 
0615 static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
0616                    struct dcb_app *app)
0617 {
0618     struct ixgbe_adapter *adapter = netdev_priv(dev);
0619     int err;
0620 
0621     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0622         return -EINVAL;
0623 
0624     err = dcb_ieee_setapp(dev, app);
0625     if (err)
0626         return err;
0627 
0628 #ifdef IXGBE_FCOE
0629     if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
0630         app->protocol == ETH_P_FCOE) {
0631         u8 app_mask = dcb_ieee_getapp_mask(dev, app);
0632 
0633         if (app_mask & BIT(adapter->fcoe.up))
0634             return 0;
0635 
0636         adapter->fcoe.up = app->priority;
0637         ixgbe_dcbnl_devreset(dev);
0638     }
0639 #endif
0640 
0641     /* VF devices should use default UP when available */
0642     if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
0643         app->protocol == 0) {
0644         int vf;
0645 
0646         adapter->default_up = app->priority;
0647 
0648         for (vf = 0; vf < adapter->num_vfs; vf++) {
0649             struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
0650 
0651             if (!vfinfo->pf_qos)
0652                 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
0653                         app->priority, vf);
0654         }
0655     }
0656 
0657     return 0;
0658 }
0659 
0660 static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,
0661                    struct dcb_app *app)
0662 {
0663     struct ixgbe_adapter *adapter = netdev_priv(dev);
0664     int err;
0665 
0666     if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0667         return -EINVAL;
0668 
0669     err = dcb_ieee_delapp(dev, app);
0670 
0671 #ifdef IXGBE_FCOE
0672     if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
0673         app->protocol == ETH_P_FCOE) {
0674         u8 app_mask = dcb_ieee_getapp_mask(dev, app);
0675 
0676         if (app_mask & BIT(adapter->fcoe.up))
0677             return 0;
0678 
0679         adapter->fcoe.up = app_mask ?
0680                    ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC;
0681         ixgbe_dcbnl_devreset(dev);
0682     }
0683 #endif
0684     /* IF default priority is being removed clear VF default UP */
0685     if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
0686         app->protocol == 0 && adapter->default_up == app->priority) {
0687         int vf;
0688         long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app);
0689         int qos = app_mask ? find_first_bit(&app_mask, 8) : 0;
0690 
0691         adapter->default_up = qos;
0692 
0693         for (vf = 0; vf < adapter->num_vfs; vf++) {
0694             struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
0695 
0696             if (!vfinfo->pf_qos)
0697                 ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
0698                         qos, vf);
0699         }
0700     }
0701 
0702     return err;
0703 }
0704 
0705 static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev)
0706 {
0707     struct ixgbe_adapter *adapter = netdev_priv(dev);
0708     return adapter->dcbx_cap;
0709 }
0710 
0711 static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode)
0712 {
0713     struct ixgbe_adapter *adapter = netdev_priv(dev);
0714     struct ieee_ets ets = {0};
0715     struct ieee_pfc pfc = {0};
0716     int err = 0;
0717 
0718     /* no support for LLD_MANAGED modes or CEE+IEEE */
0719     if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
0720         ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
0721         !(mode & DCB_CAP_DCBX_HOST))
0722         return 1;
0723 
0724     if (mode == adapter->dcbx_cap)
0725         return 0;
0726 
0727     adapter->dcbx_cap = mode;
0728 
0729     /* ETS and PFC defaults */
0730     ets.ets_cap = 8;
0731     pfc.pfc_cap = 8;
0732 
0733     if (mode & DCB_CAP_DCBX_VER_IEEE) {
0734         ixgbe_dcbnl_ieee_setets(dev, &ets);
0735         ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
0736     } else if (mode & DCB_CAP_DCBX_VER_CEE) {
0737         u8 mask = BIT_PFC | BIT_PG_TX | BIT_PG_RX | BIT_APP_UPCHG;
0738 
0739         adapter->dcb_set_bitmap |= mask;
0740         ixgbe_dcbnl_set_all(dev);
0741     } else {
0742         /* Drop into single TC mode strict priority as this
0743          * indicates CEE and IEEE versions are disabled
0744          */
0745         ixgbe_dcbnl_ieee_setets(dev, &ets);
0746         ixgbe_dcbnl_ieee_setpfc(dev, &pfc);
0747         err = ixgbe_setup_tc(dev, 0);
0748     }
0749 
0750     return err ? 1 : 0;
0751 }
0752 
0753 const struct dcbnl_rtnl_ops ixgbe_dcbnl_ops = {
0754     .ieee_getets    = ixgbe_dcbnl_ieee_getets,
0755     .ieee_setets    = ixgbe_dcbnl_ieee_setets,
0756     .ieee_getpfc    = ixgbe_dcbnl_ieee_getpfc,
0757     .ieee_setpfc    = ixgbe_dcbnl_ieee_setpfc,
0758     .ieee_setapp    = ixgbe_dcbnl_ieee_setapp,
0759     .ieee_delapp    = ixgbe_dcbnl_ieee_delapp,
0760     .getstate   = ixgbe_dcbnl_get_state,
0761     .setstate   = ixgbe_dcbnl_set_state,
0762     .getpermhwaddr  = ixgbe_dcbnl_get_perm_hw_addr,
0763     .setpgtccfgtx   = ixgbe_dcbnl_set_pg_tc_cfg_tx,
0764     .setpgbwgcfgtx  = ixgbe_dcbnl_set_pg_bwg_cfg_tx,
0765     .setpgtccfgrx   = ixgbe_dcbnl_set_pg_tc_cfg_rx,
0766     .setpgbwgcfgrx  = ixgbe_dcbnl_set_pg_bwg_cfg_rx,
0767     .getpgtccfgtx   = ixgbe_dcbnl_get_pg_tc_cfg_tx,
0768     .getpgbwgcfgtx  = ixgbe_dcbnl_get_pg_bwg_cfg_tx,
0769     .getpgtccfgrx   = ixgbe_dcbnl_get_pg_tc_cfg_rx,
0770     .getpgbwgcfgrx  = ixgbe_dcbnl_get_pg_bwg_cfg_rx,
0771     .setpfccfg  = ixgbe_dcbnl_set_pfc_cfg,
0772     .getpfccfg  = ixgbe_dcbnl_get_pfc_cfg,
0773     .setall     = ixgbe_dcbnl_set_all,
0774     .getcap     = ixgbe_dcbnl_getcap,
0775     .getnumtcs  = ixgbe_dcbnl_getnumtcs,
0776     .setnumtcs  = ixgbe_dcbnl_setnumtcs,
0777     .getpfcstate    = ixgbe_dcbnl_getpfcstate,
0778     .setpfcstate    = ixgbe_dcbnl_setpfcstate,
0779     .getapp     = ixgbe_dcbnl_getapp,
0780     .getdcbx    = ixgbe_dcbnl_getdcbx,
0781     .setdcbx    = ixgbe_dcbnl_setdcbx,
0782 };