0001
0002
0003
0004 #ifdef CONFIG_I40E_DCB
0005 #include "i40e.h"
0006 #include <net/dcbnl.h>
0007
0008 #define I40E_DCBNL_STATUS_SUCCESS 0
0009 #define I40E_DCBNL_STATUS_ERROR 1
0010 static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg,
0011 struct i40e_dcb_app_priority_table *app);
0012
0013
0014
0015
0016
0017
0018
0019 static void i40e_get_pfc_delay(struct i40e_hw *hw, u16 *delay)
0020 {
0021 u32 val;
0022
0023 val = rd32(hw, I40E_PRTDCB_GENC);
0024 *delay = (u16)((val & I40E_PRTDCB_GENC_PFCLDA_MASK) >>
0025 I40E_PRTDCB_GENC_PFCLDA_SHIFT);
0026 }
0027
0028
0029
0030
0031
0032
0033
0034
0035 static int i40e_dcbnl_ieee_getets(struct net_device *dev,
0036 struct ieee_ets *ets)
0037 {
0038 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
0039 struct i40e_dcbx_config *dcbxcfg;
0040
0041 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0042 return -EINVAL;
0043
0044 dcbxcfg = &pf->hw.local_dcbx_config;
0045 ets->willing = dcbxcfg->etscfg.willing;
0046 ets->ets_cap = I40E_MAX_TRAFFIC_CLASS;
0047 ets->cbs = dcbxcfg->etscfg.cbs;
0048 memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable,
0049 sizeof(ets->tc_tx_bw));
0050 memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable,
0051 sizeof(ets->tc_rx_bw));
0052 memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable,
0053 sizeof(ets->tc_tsa));
0054 memcpy(ets->prio_tc, dcbxcfg->etscfg.prioritytable,
0055 sizeof(ets->prio_tc));
0056 memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
0057 sizeof(ets->tc_reco_bw));
0058 memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
0059 sizeof(ets->tc_reco_tsa));
0060 memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prioritytable,
0061 sizeof(ets->reco_prio_tc));
0062
0063 return 0;
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073 static int i40e_dcbnl_ieee_getpfc(struct net_device *dev,
0074 struct ieee_pfc *pfc)
0075 {
0076 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
0077 struct i40e_dcbx_config *dcbxcfg;
0078 struct i40e_hw *hw = &pf->hw;
0079 int i;
0080
0081 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
0082 return -EINVAL;
0083
0084 dcbxcfg = &hw->local_dcbx_config;
0085 pfc->pfc_cap = dcbxcfg->pfc.pfccap;
0086 pfc->pfc_en = dcbxcfg->pfc.pfcenable;
0087 pfc->mbc = dcbxcfg->pfc.mbc;
0088 i40e_get_pfc_delay(hw, &pfc->delay);
0089
0090
0091 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
0092 pfc->requests[i] = pf->stats.priority_xoff_tx[i];
0093 pfc->indications[i] = pf->stats.priority_xoff_rx[i];
0094 }
0095
0096 return 0;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106 static int i40e_dcbnl_ieee_setets(struct net_device *netdev,
0107 struct ieee_ets *ets)
0108 {
0109 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0110 struct i40e_dcbx_config *old_cfg;
0111 int i, ret;
0112
0113 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
0114 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0115 return -EINVAL;
0116
0117 old_cfg = &pf->hw.local_dcbx_config;
0118
0119 pf->tmp_cfg = *old_cfg;
0120
0121
0122 pf->tmp_cfg.etscfg.willing = ets->willing;
0123 pf->tmp_cfg.etscfg.maxtcs = I40E_MAX_TRAFFIC_CLASS;
0124 pf->tmp_cfg.etscfg.cbs = ets->cbs;
0125 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
0126 pf->tmp_cfg.etscfg.tcbwtable[i] = ets->tc_tx_bw[i];
0127 pf->tmp_cfg.etscfg.tsatable[i] = ets->tc_tsa[i];
0128 pf->tmp_cfg.etscfg.prioritytable[i] = ets->prio_tc[i];
0129 pf->tmp_cfg.etsrec.tcbwtable[i] = ets->tc_reco_bw[i];
0130 pf->tmp_cfg.etsrec.tsatable[i] = ets->tc_reco_tsa[i];
0131 pf->tmp_cfg.etsrec.prioritytable[i] = ets->reco_prio_tc[i];
0132 }
0133
0134
0135 ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
0136 if (ret) {
0137 dev_info(&pf->pdev->dev,
0138 "Failed setting DCB ETS configuration err %s aq_err %s\n",
0139 i40e_stat_str(&pf->hw, ret),
0140 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
0141 return -EINVAL;
0142 }
0143
0144 return 0;
0145 }
0146
0147
0148
0149
0150
0151
0152
0153
0154 static int i40e_dcbnl_ieee_setpfc(struct net_device *netdev,
0155 struct ieee_pfc *pfc)
0156 {
0157 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0158 struct i40e_dcbx_config *old_cfg;
0159 int ret;
0160
0161 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
0162 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0163 return -EINVAL;
0164
0165 old_cfg = &pf->hw.local_dcbx_config;
0166
0167 pf->tmp_cfg = *old_cfg;
0168 if (pfc->pfc_cap)
0169 pf->tmp_cfg.pfc.pfccap = pfc->pfc_cap;
0170 else
0171 pf->tmp_cfg.pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
0172 pf->tmp_cfg.pfc.pfcenable = pfc->pfc_en;
0173
0174 ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
0175 if (ret) {
0176 dev_info(&pf->pdev->dev,
0177 "Failed setting DCB PFC configuration err %s aq_err %s\n",
0178 i40e_stat_str(&pf->hw, ret),
0179 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
0180 return -EINVAL;
0181 }
0182
0183 return 0;
0184 }
0185
0186
0187
0188
0189
0190
0191
0192
0193 static int i40e_dcbnl_ieee_setapp(struct net_device *netdev,
0194 struct dcb_app *app)
0195 {
0196 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0197 struct i40e_dcb_app_priority_table new_app;
0198 struct i40e_dcbx_config *old_cfg;
0199 int ret;
0200
0201 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
0202 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0203 return -EINVAL;
0204
0205 old_cfg = &pf->hw.local_dcbx_config;
0206 if (old_cfg->numapps == I40E_DCBX_MAX_APPS)
0207 return -EINVAL;
0208
0209 ret = dcb_ieee_setapp(netdev, app);
0210 if (ret)
0211 return ret;
0212
0213 new_app.selector = app->selector;
0214 new_app.protocolid = app->protocol;
0215 new_app.priority = app->priority;
0216
0217 if (i40e_dcbnl_find_app(old_cfg, &new_app))
0218 return 0;
0219
0220
0221 pf->tmp_cfg = *old_cfg;
0222
0223 pf->tmp_cfg.app[pf->tmp_cfg.numapps++] = new_app;
0224
0225 ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
0226 if (ret) {
0227 dev_info(&pf->pdev->dev,
0228 "Failed setting DCB configuration err %s aq_err %s\n",
0229 i40e_stat_str(&pf->hw, ret),
0230 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
0231 return -EINVAL;
0232 }
0233
0234 return 0;
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 static int i40e_dcbnl_ieee_delapp(struct net_device *netdev,
0246 struct dcb_app *app)
0247 {
0248 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0249 struct i40e_dcbx_config *old_cfg;
0250 int i, j, ret;
0251
0252 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
0253 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0254 return -EINVAL;
0255
0256 ret = dcb_ieee_delapp(netdev, app);
0257 if (ret)
0258 return ret;
0259
0260 old_cfg = &pf->hw.local_dcbx_config;
0261
0262 if (old_cfg->numapps == 1)
0263 return 0;
0264
0265
0266 pf->tmp_cfg = *old_cfg;
0267
0268
0269 for (i = 1; i < pf->tmp_cfg.numapps; i++) {
0270 if (app->selector == pf->tmp_cfg.app[i].selector &&
0271 app->protocol == pf->tmp_cfg.app[i].protocolid &&
0272 app->priority == pf->tmp_cfg.app[i].priority) {
0273
0274 pf->tmp_cfg.app[i].selector = 0;
0275 pf->tmp_cfg.app[i].protocolid = 0;
0276 pf->tmp_cfg.app[i].priority = 0;
0277 break;
0278 }
0279 }
0280
0281
0282 if (i == pf->tmp_cfg.numapps)
0283 return -EINVAL;
0284
0285 pf->tmp_cfg.numapps--;
0286
0287 for (j = i; j < pf->tmp_cfg.numapps; j++)
0288 pf->tmp_cfg.app[j] = old_cfg->app[j + 1];
0289
0290 ret = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
0291 if (ret) {
0292 dev_info(&pf->pdev->dev,
0293 "Failed setting DCB configuration err %s aq_err %s\n",
0294 i40e_stat_str(&pf->hw, ret),
0295 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
0296 return -EINVAL;
0297 }
0298
0299 return 0;
0300 }
0301
0302
0303
0304
0305
0306
0307
0308 static u8 i40e_dcbnl_getstate(struct net_device *netdev)
0309 {
0310 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0311
0312 dev_dbg(&pf->pdev->dev, "DCB state=%d\n",
0313 !!(pf->flags & I40E_FLAG_DCB_ENABLED));
0314 return !!(pf->flags & I40E_FLAG_DCB_ENABLED);
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324 static u8 i40e_dcbnl_setstate(struct net_device *netdev, u8 state)
0325 {
0326 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0327 int ret = I40E_DCBNL_STATUS_SUCCESS;
0328
0329 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0330 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0331 return ret;
0332
0333 dev_dbg(&pf->pdev->dev, "new state=%d current state=%d\n",
0334 state, (pf->flags & I40E_FLAG_DCB_ENABLED) ? 1 : 0);
0335
0336 if (!state == !(pf->flags & I40E_FLAG_DCB_ENABLED))
0337 return ret;
0338
0339 if (i40e_is_sw_dcb(pf)) {
0340 if (state) {
0341 pf->flags |= I40E_FLAG_DCB_ENABLED;
0342 memcpy(&pf->hw.desired_dcbx_config,
0343 &pf->hw.local_dcbx_config,
0344 sizeof(struct i40e_dcbx_config));
0345 } else {
0346 pf->flags &= ~I40E_FLAG_DCB_ENABLED;
0347 }
0348 } else {
0349
0350 ret = I40E_DCBNL_STATUS_ERROR;
0351 }
0352 return ret;
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 static void i40e_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
0367 u8 prio_type, u8 bwg_id, u8 bw_pct,
0368 u8 up_map)
0369 {
0370 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0371 int i;
0372
0373 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0374 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0375 return;
0376
0377
0378 if (tc >= I40E_MAX_TRAFFIC_CLASS)
0379 return;
0380
0381
0382
0383
0384 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
0385 if (up_map & BIT(i))
0386 pf->tmp_cfg.etscfg.prioritytable[i] = tc;
0387 }
0388 pf->tmp_cfg.etscfg.tsatable[tc] = I40E_IEEE_TSA_ETS;
0389 dev_dbg(&pf->pdev->dev,
0390 "Set PG config tc=%d bwg_id=%d prio_type=%d bw_pct=%d up_map=%d\n",
0391 tc, bwg_id, prio_type, bw_pct, up_map);
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402 static void i40e_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
0403 u8 bw_pct)
0404 {
0405 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0406
0407 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0408 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0409 return;
0410
0411
0412 if (pgid >= I40E_MAX_TRAFFIC_CLASS)
0413 return;
0414
0415 pf->tmp_cfg.etscfg.tcbwtable[pgid] = bw_pct;
0416 dev_dbg(&pf->pdev->dev, "Set PG BW config tc=%d bw_pct=%d\n",
0417 pgid, bw_pct);
0418 }
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 static void i40e_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev,
0433 int __always_unused prio,
0434 u8 __always_unused prio_type,
0435 u8 __always_unused pgid,
0436 u8 __always_unused bw_pct,
0437 u8 __always_unused up_map)
0438 {
0439 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0440
0441 dev_dbg(&pf->pdev->dev, "Rx TC PG Config Not Supported.\n");
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453 static void i40e_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int pgid,
0454 u8 bw_pct)
0455 {
0456 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0457
0458 dev_dbg(&pf->pdev->dev, "Rx BWG PG Config Not Supported.\n");
0459 }
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 static void i40e_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio,
0473 u8 __always_unused *prio_type,
0474 u8 *pgid,
0475 u8 __always_unused *bw_pct,
0476 u8 __always_unused *up_map)
0477 {
0478 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0479
0480 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0481 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0482 return;
0483
0484 if (prio >= I40E_MAX_USER_PRIORITY)
0485 return;
0486
0487 *pgid = pf->hw.local_dcbx_config.etscfg.prioritytable[prio];
0488 dev_dbg(&pf->pdev->dev, "Get PG config prio=%d tc=%d\n",
0489 prio, *pgid);
0490 }
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500 static void i40e_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
0501 u8 *bw_pct)
0502 {
0503 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0504
0505 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0506 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0507 return;
0508
0509 if (pgid >= I40E_MAX_TRAFFIC_CLASS)
0510 return;
0511
0512 *bw_pct = pf->hw.local_dcbx_config.etscfg.tcbwtable[pgid];
0513 dev_dbg(&pf->pdev->dev, "Get PG BW config tc=%d bw_pct=%d\n",
0514 pgid, *bw_pct);
0515 }
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530 static void i40e_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio,
0531 u8 *prio_type, u8 *pgid, u8 *bw_pct,
0532 u8 *up_map)
0533 {
0534 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0535
0536 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0537 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0538 return;
0539
0540 if (prio >= I40E_MAX_USER_PRIORITY)
0541 return;
0542
0543 *pgid = pf->hw.local_dcbx_config.etscfg.prioritytable[prio];
0544 }
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 static void i40e_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int pgid,
0557 u8 *bw_pct)
0558 {
0559 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0560
0561 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0562 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0563 return;
0564 *bw_pct = 0;
0565 }
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575 static void i40e_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio,
0576 u8 setting)
0577 {
0578 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0579
0580 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0581 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0582 return;
0583
0584 if (prio >= I40E_MAX_USER_PRIORITY)
0585 return;
0586
0587 pf->tmp_cfg.pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
0588 if (setting)
0589 pf->tmp_cfg.pfc.pfcenable |= BIT(prio);
0590 else
0591 pf->tmp_cfg.pfc.pfcenable &= ~BIT(prio);
0592 dev_dbg(&pf->pdev->dev,
0593 "Set PFC Config up=%d setting=%d pfcenable=0x%x\n",
0594 prio, setting, pf->tmp_cfg.pfc.pfcenable);
0595 }
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 static void i40e_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
0606 u8 *setting)
0607 {
0608 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0609
0610 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0611 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0612 return;
0613
0614 if (prio >= I40E_MAX_USER_PRIORITY)
0615 return;
0616
0617 *setting = (pf->hw.local_dcbx_config.pfc.pfcenable >> prio) & 0x1;
0618 dev_dbg(&pf->pdev->dev,
0619 "Get PFC Config up=%d setting=%d pfcenable=0x%x\n",
0620 prio, *setting, pf->hw.local_dcbx_config.pfc.pfcenable);
0621 }
0622
0623
0624
0625
0626
0627
0628
0629 static u8 i40e_dcbnl_cee_set_all(struct net_device *netdev)
0630 {
0631 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0632 int err;
0633
0634 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0635 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0636 return I40E_DCBNL_STATUS_ERROR;
0637
0638 dev_dbg(&pf->pdev->dev, "Commit DCB Configuration to the hardware\n");
0639 err = i40e_hw_dcb_config(pf, &pf->tmp_cfg);
0640
0641 return err ? I40E_DCBNL_STATUS_ERROR : I40E_DCBNL_STATUS_SUCCESS;
0642 }
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652 static u8 i40e_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
0653 {
0654 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0655
0656 if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
0657 return I40E_DCBNL_STATUS_ERROR;
0658
0659 switch (capid) {
0660 case DCB_CAP_ATTR_PG:
0661 case DCB_CAP_ATTR_PFC:
0662 *cap = true;
0663 break;
0664 case DCB_CAP_ATTR_PG_TCS:
0665 case DCB_CAP_ATTR_PFC_TCS:
0666 *cap = 0x80;
0667 break;
0668 case DCB_CAP_ATTR_DCBX:
0669 *cap = pf->dcbx_cap;
0670 break;
0671 case DCB_CAP_ATTR_UP2TC:
0672 case DCB_CAP_ATTR_GSP:
0673 case DCB_CAP_ATTR_BCN:
0674 default:
0675 *cap = false;
0676 break;
0677 }
0678
0679 dev_dbg(&pf->pdev->dev, "Get Capability cap=%d capval=0x%x\n",
0680 capid, *cap);
0681 return I40E_DCBNL_STATUS_SUCCESS;
0682 }
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 static int i40e_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
0693 {
0694 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0695
0696 if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
0697 return -EINVAL;
0698
0699 *num = I40E_MAX_TRAFFIC_CLASS;
0700 return 0;
0701 }
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711 static int i40e_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
0712 {
0713 return -EINVAL;
0714 }
0715
0716
0717
0718
0719
0720
0721
0722 static u8 i40e_dcbnl_getpfcstate(struct net_device *netdev)
0723 {
0724 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0725
0726
0727 if (pf->hw.local_dcbx_config.pfc.pfcenable)
0728 return 1;
0729 else
0730 return 0;
0731 }
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741 static void i40e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
0742 {
0743 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0744
0745 dev_dbg(&pf->pdev->dev, "PFC State is modified via PFC config.\n");
0746 }
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756 static int i40e_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
0757 {
0758 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0759 struct dcb_app app = {
0760 .selector = idtype,
0761 .protocol = id,
0762 };
0763
0764 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE) ||
0765 (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED))
0766 return -EINVAL;
0767
0768 return dcb_getapp(netdev, &app);
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778 static u8 i40e_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
0779 {
0780 struct i40e_pf *pf = i40e_netdev_to_pf(netdev);
0781
0782
0783 if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED)
0784 return I40E_DCBNL_STATUS_ERROR;
0785
0786
0787 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
0788 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
0789 !(mode & DCB_CAP_DCBX_HOST))
0790 return I40E_DCBNL_STATUS_ERROR;
0791
0792
0793 if (mode == pf->dcbx_cap)
0794 return I40E_DCBNL_STATUS_SUCCESS;
0795
0796 pf->dcbx_cap = mode;
0797 if (mode & DCB_CAP_DCBX_VER_CEE)
0798 pf->hw.local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
0799 else
0800 pf->hw.local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
0801
0802 dev_dbg(&pf->pdev->dev, "mode=%d\n", mode);
0803 return I40E_DCBNL_STATUS_SUCCESS;
0804 }
0805
0806
0807
0808
0809
0810
0811
0812 static u8 i40e_dcbnl_getdcbx(struct net_device *dev)
0813 {
0814 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
0815
0816 return pf->dcbx_cap;
0817 }
0818
0819
0820
0821
0822
0823
0824
0825
0826 static void i40e_dcbnl_get_perm_hw_addr(struct net_device *dev,
0827 u8 *perm_addr)
0828 {
0829 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
0830 int i, j;
0831
0832 memset(perm_addr, 0xff, MAX_ADDR_LEN);
0833
0834 for (i = 0; i < dev->addr_len; i++)
0835 perm_addr[i] = pf->hw.mac.perm_addr[i];
0836
0837 for (j = 0; j < dev->addr_len; j++, i++)
0838 perm_addr[i] = pf->hw.mac.san_addr[j];
0839 }
0840
0841 static const struct dcbnl_rtnl_ops dcbnl_ops = {
0842 .ieee_getets = i40e_dcbnl_ieee_getets,
0843 .ieee_getpfc = i40e_dcbnl_ieee_getpfc,
0844 .getdcbx = i40e_dcbnl_getdcbx,
0845 .getpermhwaddr = i40e_dcbnl_get_perm_hw_addr,
0846 .ieee_setets = i40e_dcbnl_ieee_setets,
0847 .ieee_setpfc = i40e_dcbnl_ieee_setpfc,
0848 .ieee_setapp = i40e_dcbnl_ieee_setapp,
0849 .ieee_delapp = i40e_dcbnl_ieee_delapp,
0850 .getstate = i40e_dcbnl_getstate,
0851 .setstate = i40e_dcbnl_setstate,
0852 .setpgtccfgtx = i40e_dcbnl_set_pg_tc_cfg_tx,
0853 .setpgbwgcfgtx = i40e_dcbnl_set_pg_bwg_cfg_tx,
0854 .setpgtccfgrx = i40e_dcbnl_set_pg_tc_cfg_rx,
0855 .setpgbwgcfgrx = i40e_dcbnl_set_pg_bwg_cfg_rx,
0856 .getpgtccfgtx = i40e_dcbnl_get_pg_tc_cfg_tx,
0857 .getpgbwgcfgtx = i40e_dcbnl_get_pg_bwg_cfg_tx,
0858 .getpgtccfgrx = i40e_dcbnl_get_pg_tc_cfg_rx,
0859 .getpgbwgcfgrx = i40e_dcbnl_get_pg_bwg_cfg_rx,
0860 .setpfccfg = i40e_dcbnl_set_pfc_cfg,
0861 .getpfccfg = i40e_dcbnl_get_pfc_cfg,
0862 .setall = i40e_dcbnl_cee_set_all,
0863 .getcap = i40e_dcbnl_get_cap,
0864 .getnumtcs = i40e_dcbnl_getnumtcs,
0865 .setnumtcs = i40e_dcbnl_setnumtcs,
0866 .getpfcstate = i40e_dcbnl_getpfcstate,
0867 .setpfcstate = i40e_dcbnl_setpfcstate,
0868 .getapp = i40e_dcbnl_getapp,
0869 .setdcbx = i40e_dcbnl_setdcbx,
0870 };
0871
0872
0873
0874
0875
0876
0877
0878
0879 void i40e_dcbnl_set_all(struct i40e_vsi *vsi)
0880 {
0881 struct net_device *dev = vsi->netdev;
0882 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
0883 struct i40e_dcbx_config *dcbxcfg;
0884 struct i40e_hw *hw = &pf->hw;
0885 struct dcb_app sapp;
0886 u8 prio, tc_map;
0887 int i;
0888
0889
0890 if (pf->dcbx_cap & DCB_CAP_DCBX_HOST)
0891 return;
0892
0893
0894 if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
0895 return;
0896
0897
0898 if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(hw->func_caps.iscsi))
0899 return;
0900
0901 dcbxcfg = &hw->local_dcbx_config;
0902
0903
0904 for (i = 0; i < dcbxcfg->numapps; i++) {
0905 prio = dcbxcfg->app[i].priority;
0906 tc_map = BIT(dcbxcfg->etscfg.prioritytable[prio]);
0907
0908
0909 if (tc_map & vsi->tc_config.enabled_tc) {
0910 sapp.selector = dcbxcfg->app[i].selector;
0911 sapp.protocol = dcbxcfg->app[i].protocolid;
0912 sapp.priority = prio;
0913 dcb_ieee_setapp(dev, &sapp);
0914 }
0915 }
0916
0917
0918 dcbnl_ieee_notify(dev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
0919 }
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929 static int i40e_dcbnl_vsi_del_app(struct i40e_vsi *vsi,
0930 struct i40e_dcb_app_priority_table *app)
0931 {
0932 struct net_device *dev = vsi->netdev;
0933 struct dcb_app sapp;
0934
0935 if (!dev)
0936 return -EINVAL;
0937
0938 sapp.selector = app->selector;
0939 sapp.protocol = app->protocolid;
0940 sapp.priority = app->priority;
0941 return dcb_ieee_delapp(dev, &sapp);
0942 }
0943
0944
0945
0946
0947
0948
0949
0950
0951 static void i40e_dcbnl_del_app(struct i40e_pf *pf,
0952 struct i40e_dcb_app_priority_table *app)
0953 {
0954 int v, err;
0955
0956 for (v = 0; v < pf->num_alloc_vsi; v++) {
0957 if (pf->vsi[v] && pf->vsi[v]->netdev) {
0958 err = i40e_dcbnl_vsi_del_app(pf->vsi[v], app);
0959 dev_dbg(&pf->pdev->dev, "Deleting app for VSI seid=%d err=%d sel=%d proto=0x%x prio=%d\n",
0960 pf->vsi[v]->seid, err, app->selector,
0961 app->protocolid, app->priority);
0962 }
0963 }
0964 }
0965
0966
0967
0968
0969
0970
0971
0972
0973 static bool i40e_dcbnl_find_app(struct i40e_dcbx_config *cfg,
0974 struct i40e_dcb_app_priority_table *app)
0975 {
0976 int i;
0977
0978 for (i = 0; i < cfg->numapps; i++) {
0979 if (app->selector == cfg->app[i].selector &&
0980 app->protocolid == cfg->app[i].protocolid &&
0981 app->priority == cfg->app[i].priority)
0982 return true;
0983 }
0984
0985 return false;
0986 }
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997 void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
0998 struct i40e_dcbx_config *old_cfg,
0999 struct i40e_dcbx_config *new_cfg)
1000 {
1001 struct i40e_dcb_app_priority_table app;
1002 int i;
1003
1004
1005 if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
1006 return;
1007
1008 for (i = 0; i < old_cfg->numapps; i++) {
1009 app = old_cfg->app[i];
1010
1011 if (!i40e_dcbnl_find_app(new_cfg, &app))
1012 i40e_dcbnl_del_app(pf, &app);
1013 }
1014 }
1015
1016
1017
1018
1019
1020
1021
1022 void i40e_dcbnl_setup(struct i40e_vsi *vsi)
1023 {
1024 struct net_device *dev = vsi->netdev;
1025 struct i40e_pf *pf = i40e_netdev_to_pf(dev);
1026
1027
1028 if (!(pf->flags & I40E_FLAG_DCB_CAPABLE))
1029 return;
1030
1031 dev->dcbnl_ops = &dcbnl_ops;
1032
1033
1034 i40e_dcbnl_set_all(vsi);
1035 }
1036 #endif