root/drivers/net/ethernet/intel/ice/ice_dcb_lib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ice_vsi_cfg_netdev_tc
  2. ice_dcb_get_ena_tc
  3. ice_dcb_get_num_tc
  4. ice_vsi_cfg_dcb_rings
  5. ice_pf_dcb_recfg
  6. ice_pf_dcb_cfg
  7. ice_cfg_etsrec_defaults
  8. ice_dcb_need_recfg
  9. ice_dcb_rebuild
  10. ice_dcb_init_cfg
  11. ice_dcb_sw_dflt_cfg
  12. ice_init_pf_dcb
  13. ice_update_dcb_stats
  14. ice_tx_prepare_vlan_flags_dcb
  15. ice_dcb_process_lldp_set_mib_change

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (c) 2019, Intel Corporation. */
   3 
   4 #include "ice_dcb_lib.h"
   5 
   6 /**
   7  * ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
   8  * @vsi: the VSI being configured
   9  * @ena_tc: TC map to be enabled
  10  */
  11 void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc)
  12 {
  13         struct net_device *netdev = vsi->netdev;
  14         struct ice_pf *pf = vsi->back;
  15         struct ice_dcbx_cfg *dcbcfg;
  16         u8 netdev_tc;
  17         int i;
  18 
  19         if (!netdev)
  20                 return;
  21 
  22         if (!ena_tc) {
  23                 netdev_reset_tc(netdev);
  24                 return;
  25         }
  26 
  27         if (netdev_set_num_tc(netdev, vsi->tc_cfg.numtc))
  28                 return;
  29 
  30         dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
  31 
  32         ice_for_each_traffic_class(i)
  33                 if (vsi->tc_cfg.ena_tc & BIT(i))
  34                         netdev_set_tc_queue(netdev,
  35                                             vsi->tc_cfg.tc_info[i].netdev_tc,
  36                                             vsi->tc_cfg.tc_info[i].qcount_tx,
  37                                             vsi->tc_cfg.tc_info[i].qoffset);
  38 
  39         for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
  40                 u8 ets_tc = dcbcfg->etscfg.prio_table[i];
  41 
  42                 /* Get the mapped netdev TC# for the UP */
  43                 netdev_tc = vsi->tc_cfg.tc_info[ets_tc].netdev_tc;
  44                 netdev_set_prio_tc_map(netdev, i, netdev_tc);
  45         }
  46 }
  47 
  48 /**
  49  * ice_dcb_get_ena_tc - return bitmap of enabled TCs
  50  * @dcbcfg: DCB config to evaluate for enabled TCs
  51  */
  52 u8 ice_dcb_get_ena_tc(struct ice_dcbx_cfg *dcbcfg)
  53 {
  54         u8 i, num_tc, ena_tc = 1;
  55 
  56         num_tc = ice_dcb_get_num_tc(dcbcfg);
  57 
  58         for (i = 0; i < num_tc; i++)
  59                 ena_tc |= BIT(i);
  60 
  61         return ena_tc;
  62 }
  63 
  64 /**
  65  * ice_dcb_get_num_tc - Get the number of TCs from DCBX config
  66  * @dcbcfg: config to retrieve number of TCs from
  67  */
  68 u8 ice_dcb_get_num_tc(struct ice_dcbx_cfg *dcbcfg)
  69 {
  70         bool tc_unused = false;
  71         u8 num_tc = 0;
  72         u8 ret = 0;
  73         int i;
  74 
  75         /* Scan the ETS Config Priority Table to find traffic classes
  76          * enabled and create a bitmask of enabled TCs
  77          */
  78         for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
  79                 num_tc |= BIT(dcbcfg->etscfg.prio_table[i]);
  80 
  81         /* Scan bitmask for contiguous TCs starting with TC0 */
  82         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
  83                 if (num_tc & BIT(i)) {
  84                         if (!tc_unused) {
  85                                 ret++;
  86                         } else {
  87                                 pr_err("Non-contiguous TCs - Disabling DCB\n");
  88                                 return 1;
  89                         }
  90                 } else {
  91                         tc_unused = true;
  92                 }
  93         }
  94 
  95         /* There is always at least 1 TC */
  96         if (!ret)
  97                 ret = 1;
  98 
  99         return ret;
 100 }
 101 
 102 /**
 103  * ice_vsi_cfg_dcb_rings - Update rings to reflect DCB TC
 104  * @vsi: VSI owner of rings being updated
 105  */
 106 void ice_vsi_cfg_dcb_rings(struct ice_vsi *vsi)
 107 {
 108         struct ice_ring *tx_ring, *rx_ring;
 109         u16 qoffset, qcount;
 110         int i, n;
 111 
 112         if (!test_bit(ICE_FLAG_DCB_ENA, vsi->back->flags)) {
 113                 /* Reset the TC information */
 114                 for (i = 0; i < vsi->num_txq; i++) {
 115                         tx_ring = vsi->tx_rings[i];
 116                         tx_ring->dcb_tc = 0;
 117                 }
 118                 for (i = 0; i < vsi->num_rxq; i++) {
 119                         rx_ring = vsi->rx_rings[i];
 120                         rx_ring->dcb_tc = 0;
 121                 }
 122                 return;
 123         }
 124 
 125         ice_for_each_traffic_class(n) {
 126                 if (!(vsi->tc_cfg.ena_tc & BIT(n)))
 127                         break;
 128 
 129                 qoffset = vsi->tc_cfg.tc_info[n].qoffset;
 130                 qcount = vsi->tc_cfg.tc_info[n].qcount_tx;
 131                 for (i = qoffset; i < (qoffset + qcount); i++) {
 132                         tx_ring = vsi->tx_rings[i];
 133                         rx_ring = vsi->rx_rings[i];
 134                         tx_ring->dcb_tc = n;
 135                         rx_ring->dcb_tc = n;
 136                 }
 137         }
 138 }
 139 
 140 /**
 141  * ice_pf_dcb_recfg - Reconfigure all VEBs and VSIs
 142  * @pf: pointer to the PF struct
 143  *
 144  * Assumed caller has already disabled all VSIs before
 145  * calling this function. Reconfiguring DCB based on
 146  * local_dcbx_cfg.
 147  */
 148 static void ice_pf_dcb_recfg(struct ice_pf *pf)
 149 {
 150         struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
 151         u8 tc_map = 0;
 152         int v, ret;
 153 
 154         /* Update each VSI */
 155         ice_for_each_vsi(pf, v) {
 156                 if (!pf->vsi[v])
 157                         continue;
 158 
 159                 if (pf->vsi[v]->type == ICE_VSI_PF)
 160                         tc_map = ice_dcb_get_ena_tc(dcbcfg);
 161                 else
 162                         tc_map = ICE_DFLT_TRAFFIC_CLASS;
 163 
 164                 ret = ice_vsi_cfg_tc(pf->vsi[v], tc_map);
 165                 if (ret) {
 166                         dev_err(&pf->pdev->dev,
 167                                 "Failed to config TC for VSI index: %d\n",
 168                                 pf->vsi[v]->idx);
 169                         continue;
 170                 }
 171 
 172                 ice_vsi_map_rings_to_vectors(pf->vsi[v]);
 173         }
 174 }
 175 
 176 /**
 177  * ice_pf_dcb_cfg - Apply new DCB configuration
 178  * @pf: pointer to the PF struct
 179  * @new_cfg: DCBX config to apply
 180  * @locked: is the RTNL held
 181  */
 182 static
 183 int ice_pf_dcb_cfg(struct ice_pf *pf, struct ice_dcbx_cfg *new_cfg, bool locked)
 184 {
 185         struct ice_dcbx_cfg *old_cfg, *curr_cfg;
 186         struct ice_aqc_port_ets_elem buf = { 0 };
 187         int ret = 0;
 188 
 189         curr_cfg = &pf->hw.port_info->local_dcbx_cfg;
 190 
 191         /* Enable DCB tagging only when more than one TC */
 192         if (ice_dcb_get_num_tc(new_cfg) > 1) {
 193                 dev_dbg(&pf->pdev->dev, "DCB tagging enabled (num TC > 1)\n");
 194                 set_bit(ICE_FLAG_DCB_ENA, pf->flags);
 195         } else {
 196                 dev_dbg(&pf->pdev->dev, "DCB tagging disabled (num TC = 1)\n");
 197                 clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
 198         }
 199 
 200         if (!memcmp(new_cfg, curr_cfg, sizeof(*new_cfg))) {
 201                 dev_dbg(&pf->pdev->dev, "No change in DCB config required\n");
 202                 return ret;
 203         }
 204 
 205         /* Store old config in case FW config fails */
 206         old_cfg = devm_kzalloc(&pf->pdev->dev, sizeof(*old_cfg), GFP_KERNEL);
 207         memcpy(old_cfg, curr_cfg, sizeof(*old_cfg));
 208 
 209         /* avoid race conditions by holding the lock while disabling and
 210          * re-enabling the VSI
 211          */
 212         if (!locked)
 213                 rtnl_lock();
 214         ice_pf_dis_all_vsi(pf, true);
 215 
 216         memcpy(curr_cfg, new_cfg, sizeof(*curr_cfg));
 217         memcpy(&curr_cfg->etsrec, &curr_cfg->etscfg, sizeof(curr_cfg->etsrec));
 218 
 219         /* Only send new config to HW if we are in SW LLDP mode. Otherwise,
 220          * the new config came from the HW in the first place.
 221          */
 222         if (pf->hw.port_info->is_sw_lldp) {
 223                 ret = ice_set_dcb_cfg(pf->hw.port_info);
 224                 if (ret) {
 225                         dev_err(&pf->pdev->dev, "Set DCB Config failed\n");
 226                         /* Restore previous settings to local config */
 227                         memcpy(curr_cfg, old_cfg, sizeof(*curr_cfg));
 228                         goto out;
 229                 }
 230         }
 231 
 232         ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
 233         if (ret) {
 234                 dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
 235                 goto out;
 236         }
 237 
 238         ice_pf_dcb_recfg(pf);
 239 
 240 out:
 241         ice_pf_ena_all_vsi(pf, true);
 242         if (!locked)
 243                 rtnl_unlock();
 244         devm_kfree(&pf->pdev->dev, old_cfg);
 245         return ret;
 246 }
 247 
 248 /**
 249  * ice_cfg_etsrec_defaults - Set default ETS recommended DCB config
 250  * @pi: port information structure
 251  */
 252 static void ice_cfg_etsrec_defaults(struct ice_port_info *pi)
 253 {
 254         struct ice_dcbx_cfg *dcbcfg = &pi->local_dcbx_cfg;
 255         u8 i;
 256 
 257         /* Ensure ETS recommended DCB configuration is not already set */
 258         if (dcbcfg->etsrec.maxtcs)
 259                 return;
 260 
 261         /* In CEE mode, set the default to 1 TC */
 262         dcbcfg->etsrec.maxtcs = 1;
 263         for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
 264                 dcbcfg->etsrec.tcbwtable[i] = i ? 0 : 100;
 265                 dcbcfg->etsrec.tsatable[i] = i ? ICE_IEEE_TSA_STRICT :
 266                                                  ICE_IEEE_TSA_ETS;
 267         }
 268 }
 269 
 270 /**
 271  * ice_dcb_need_recfg - Check if DCB needs reconfig
 272  * @pf: board private structure
 273  * @old_cfg: current DCB config
 274  * @new_cfg: new DCB config
 275  */
 276 static bool
 277 ice_dcb_need_recfg(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
 278                    struct ice_dcbx_cfg *new_cfg)
 279 {
 280         bool need_reconfig = false;
 281 
 282         /* Check if ETS configuration has changed */
 283         if (memcmp(&new_cfg->etscfg, &old_cfg->etscfg,
 284                    sizeof(new_cfg->etscfg))) {
 285                 /* If Priority Table has changed reconfig is needed */
 286                 if (memcmp(&new_cfg->etscfg.prio_table,
 287                            &old_cfg->etscfg.prio_table,
 288                            sizeof(new_cfg->etscfg.prio_table))) {
 289                         need_reconfig = true;
 290                         dev_dbg(&pf->pdev->dev, "ETS UP2TC changed.\n");
 291                 }
 292 
 293                 if (memcmp(&new_cfg->etscfg.tcbwtable,
 294                            &old_cfg->etscfg.tcbwtable,
 295                            sizeof(new_cfg->etscfg.tcbwtable)))
 296                         dev_dbg(&pf->pdev->dev, "ETS TC BW Table changed.\n");
 297 
 298                 if (memcmp(&new_cfg->etscfg.tsatable,
 299                            &old_cfg->etscfg.tsatable,
 300                            sizeof(new_cfg->etscfg.tsatable)))
 301                         dev_dbg(&pf->pdev->dev, "ETS TSA Table changed.\n");
 302         }
 303 
 304         /* Check if PFC configuration has changed */
 305         if (memcmp(&new_cfg->pfc, &old_cfg->pfc, sizeof(new_cfg->pfc))) {
 306                 need_reconfig = true;
 307                 dev_dbg(&pf->pdev->dev, "PFC config change detected.\n");
 308         }
 309 
 310         /* Check if APP Table has changed */
 311         if (memcmp(&new_cfg->app, &old_cfg->app, sizeof(new_cfg->app))) {
 312                 need_reconfig = true;
 313                 dev_dbg(&pf->pdev->dev, "APP Table change detected.\n");
 314         }
 315 
 316         dev_dbg(&pf->pdev->dev, "dcb need_reconfig=%d\n", need_reconfig);
 317         return need_reconfig;
 318 }
 319 
 320 /**
 321  * ice_dcb_rebuild - rebuild DCB post reset
 322  * @pf: physical function instance
 323  */
 324 void ice_dcb_rebuild(struct ice_pf *pf)
 325 {
 326         struct ice_dcbx_cfg *local_dcbx_cfg, *desired_dcbx_cfg, *prev_cfg;
 327         struct ice_aqc_port_ets_elem buf = { 0 };
 328         enum ice_status ret;
 329 
 330         ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
 331         if (ret) {
 332                 dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
 333                 goto dcb_error;
 334         }
 335 
 336         /* If DCB was not enabled previously, we are done */
 337         if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
 338                 return;
 339 
 340         local_dcbx_cfg = &pf->hw.port_info->local_dcbx_cfg;
 341         desired_dcbx_cfg = &pf->hw.port_info->desired_dcbx_cfg;
 342 
 343         /* Save current willing state and force FW to unwilling */
 344         local_dcbx_cfg->etscfg.willing = 0x0;
 345         local_dcbx_cfg->pfc.willing = 0x0;
 346         local_dcbx_cfg->app_mode = ICE_DCBX_APPS_NON_WILLING;
 347 
 348         ice_cfg_etsrec_defaults(pf->hw.port_info);
 349         ret = ice_set_dcb_cfg(pf->hw.port_info);
 350         if (ret) {
 351                 dev_err(&pf->pdev->dev, "Failed to set DCB to unwilling\n");
 352                 goto dcb_error;
 353         }
 354 
 355         /* Retrieve DCB config and ensure same as current in SW */
 356         prev_cfg = devm_kmemdup(&pf->pdev->dev, local_dcbx_cfg,
 357                                 sizeof(*prev_cfg), GFP_KERNEL);
 358         if (!prev_cfg) {
 359                 dev_err(&pf->pdev->dev, "Failed to alloc space for DCB cfg\n");
 360                 goto dcb_error;
 361         }
 362 
 363         ice_init_dcb(&pf->hw, true);
 364         if (pf->hw.port_info->dcbx_status == ICE_DCBX_STATUS_DIS)
 365                 pf->hw.port_info->is_sw_lldp = true;
 366         else
 367                 pf->hw.port_info->is_sw_lldp = false;
 368 
 369         if (ice_dcb_need_recfg(pf, prev_cfg, local_dcbx_cfg)) {
 370                 /* difference in cfg detected - disable DCB till next MIB */
 371                 dev_err(&pf->pdev->dev, "Set local MIB not accurate\n");
 372                 goto dcb_error;
 373         }
 374 
 375         /* fetched config congruent to previous configuration */
 376         devm_kfree(&pf->pdev->dev, prev_cfg);
 377 
 378         /* Set the local desired config */
 379         if (local_dcbx_cfg->dcbx_mode == ICE_DCBX_MODE_CEE)
 380                 memcpy(local_dcbx_cfg, desired_dcbx_cfg,
 381                        sizeof(*local_dcbx_cfg));
 382 
 383         ice_cfg_etsrec_defaults(pf->hw.port_info);
 384         ret = ice_set_dcb_cfg(pf->hw.port_info);
 385         if (ret) {
 386                 dev_err(&pf->pdev->dev, "Failed to set desired config\n");
 387                 goto dcb_error;
 388         }
 389         dev_info(&pf->pdev->dev, "DCB restored after reset\n");
 390         ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
 391         if (ret) {
 392                 dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
 393                 goto dcb_error;
 394         }
 395 
 396         return;
 397 
 398 dcb_error:
 399         dev_err(&pf->pdev->dev, "Disabling DCB until new settings occur\n");
 400         prev_cfg = devm_kzalloc(&pf->pdev->dev, sizeof(*prev_cfg), GFP_KERNEL);
 401         prev_cfg->etscfg.willing = true;
 402         prev_cfg->etscfg.tcbwtable[0] = ICE_TC_MAX_BW;
 403         prev_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
 404         memcpy(&prev_cfg->etsrec, &prev_cfg->etscfg, sizeof(prev_cfg->etsrec));
 405         ice_pf_dcb_cfg(pf, prev_cfg, false);
 406         devm_kfree(&pf->pdev->dev, prev_cfg);
 407 }
 408 
 409 /**
 410  * ice_dcb_init_cfg - set the initial DCB config in SW
 411  * @pf: PF to apply config to
 412  * @locked: Is the RTNL held
 413  */
 414 static int ice_dcb_init_cfg(struct ice_pf *pf, bool locked)
 415 {
 416         struct ice_dcbx_cfg *newcfg;
 417         struct ice_port_info *pi;
 418         int ret = 0;
 419 
 420         pi = pf->hw.port_info;
 421         newcfg = devm_kzalloc(&pf->pdev->dev, sizeof(*newcfg), GFP_KERNEL);
 422         if (!newcfg)
 423                 return -ENOMEM;
 424 
 425         memcpy(newcfg, &pi->local_dcbx_cfg, sizeof(*newcfg));
 426         memset(&pi->local_dcbx_cfg, 0, sizeof(*newcfg));
 427 
 428         dev_info(&pf->pdev->dev, "Configuring initial DCB values\n");
 429         if (ice_pf_dcb_cfg(pf, newcfg, locked))
 430                 ret = -EINVAL;
 431 
 432         devm_kfree(&pf->pdev->dev, newcfg);
 433 
 434         return ret;
 435 }
 436 
 437 /**
 438  * ice_dcb_sw_default_config - Apply a default DCB config
 439  * @pf: PF to apply config to
 440  * @locked: was this function called with RTNL held
 441  */
 442 static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool locked)
 443 {
 444         struct ice_aqc_port_ets_elem buf = { 0 };
 445         struct ice_dcbx_cfg *dcbcfg;
 446         struct ice_port_info *pi;
 447         struct ice_hw *hw;
 448         int ret;
 449 
 450         hw = &pf->hw;
 451         pi = hw->port_info;
 452         dcbcfg = devm_kzalloc(&pf->pdev->dev, sizeof(*dcbcfg), GFP_KERNEL);
 453 
 454         memset(dcbcfg, 0, sizeof(*dcbcfg));
 455         memset(&pi->local_dcbx_cfg, 0, sizeof(*dcbcfg));
 456 
 457         dcbcfg->etscfg.willing = 1;
 458         dcbcfg->etscfg.maxtcs = hw->func_caps.common_cap.maxtc;
 459         dcbcfg->etscfg.tcbwtable[0] = 100;
 460         dcbcfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
 461 
 462         memcpy(&dcbcfg->etsrec, &dcbcfg->etscfg,
 463                sizeof(dcbcfg->etsrec));
 464         dcbcfg->etsrec.willing = 0;
 465 
 466         dcbcfg->pfc.willing = 1;
 467         dcbcfg->pfc.pfccap = hw->func_caps.common_cap.maxtc;
 468 
 469         dcbcfg->numapps = 1;
 470         dcbcfg->app[0].selector = ICE_APP_SEL_ETHTYPE;
 471         dcbcfg->app[0].priority = 3;
 472         dcbcfg->app[0].prot_id = ICE_APP_PROT_ID_FCOE;
 473 
 474         ret = ice_pf_dcb_cfg(pf, dcbcfg, locked);
 475         devm_kfree(&pf->pdev->dev, dcbcfg);
 476         if (ret)
 477                 return ret;
 478 
 479         return ice_query_port_ets(pi, &buf, sizeof(buf), NULL);
 480 }
 481 
 482 /**
 483  * ice_init_pf_dcb - initialize DCB for a PF
 484  * @pf: PF to initialize DCB for
 485  * @locked: Was function called with RTNL held
 486  */
 487 int ice_init_pf_dcb(struct ice_pf *pf, bool locked)
 488 {
 489         struct device *dev = &pf->pdev->dev;
 490         struct ice_port_info *port_info;
 491         struct ice_hw *hw = &pf->hw;
 492         int err;
 493 
 494         port_info = hw->port_info;
 495 
 496         err = ice_init_dcb(hw, false);
 497         if (err && !port_info->is_sw_lldp) {
 498                 dev_err(&pf->pdev->dev, "Error initializing DCB %d\n", err);
 499                 goto dcb_init_err;
 500         }
 501 
 502         dev_info(&pf->pdev->dev,
 503                  "DCB is enabled in the hardware, max number of TCs supported on this port are %d\n",
 504                  pf->hw.func_caps.common_cap.maxtc);
 505         if (err) {
 506                 /* FW LLDP is disabled, activate SW DCBX/LLDP mode */
 507                 dev_info(&pf->pdev->dev,
 508                          "FW LLDP is disabled, DCBx/LLDP in SW mode.\n");
 509                 clear_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
 510                 err = ice_dcb_sw_dflt_cfg(pf, locked);
 511                 if (err) {
 512                         dev_err(&pf->pdev->dev,
 513                                 "Failed to set local DCB config %d\n", err);
 514                         err = -EIO;
 515                         goto dcb_init_err;
 516                 }
 517 
 518                 pf->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
 519                 return 0;
 520         }
 521 
 522         set_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
 523 
 524         /* DCBX in FW and LLDP enabled in FW */
 525         pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE;
 526 
 527         err = ice_dcb_init_cfg(pf, locked);
 528         if (err)
 529                 goto dcb_init_err;
 530 
 531         return err;
 532 
 533 dcb_init_err:
 534         dev_err(dev, "DCB init failed\n");
 535         return err;
 536 }
 537 
 538 /**
 539  * ice_update_dcb_stats - Update DCB stats counters
 540  * @pf: PF whose stats needs to be updated
 541  */
 542 void ice_update_dcb_stats(struct ice_pf *pf)
 543 {
 544         struct ice_hw_port_stats *prev_ps, *cur_ps;
 545         struct ice_hw *hw = &pf->hw;
 546         u8 port;
 547         int i;
 548 
 549         port = hw->port_info->lport;
 550         prev_ps = &pf->stats_prev;
 551         cur_ps = &pf->stats;
 552 
 553         for (i = 0; i < 8; i++) {
 554                 ice_stat_update32(hw, GLPRT_PXOFFRXC(port, i),
 555                                   pf->stat_prev_loaded,
 556                                   &prev_ps->priority_xoff_rx[i],
 557                                   &cur_ps->priority_xoff_rx[i]);
 558                 ice_stat_update32(hw, GLPRT_PXONRXC(port, i),
 559                                   pf->stat_prev_loaded,
 560                                   &prev_ps->priority_xon_rx[i],
 561                                   &cur_ps->priority_xon_rx[i]);
 562                 ice_stat_update32(hw, GLPRT_PXONTXC(port, i),
 563                                   pf->stat_prev_loaded,
 564                                   &prev_ps->priority_xon_tx[i],
 565                                   &cur_ps->priority_xon_tx[i]);
 566                 ice_stat_update32(hw, GLPRT_PXOFFTXC(port, i),
 567                                   pf->stat_prev_loaded,
 568                                   &prev_ps->priority_xoff_tx[i],
 569                                   &cur_ps->priority_xoff_tx[i]);
 570                 ice_stat_update32(hw, GLPRT_RXON2OFFCNT(port, i),
 571                                   pf->stat_prev_loaded,
 572                                   &prev_ps->priority_xon_2_xoff[i],
 573                                   &cur_ps->priority_xon_2_xoff[i]);
 574         }
 575 }
 576 
 577 /**
 578  * ice_tx_prepare_vlan_flags_dcb - prepare VLAN tagging for DCB
 579  * @tx_ring: ring to send buffer on
 580  * @first: pointer to struct ice_tx_buf
 581  */
 582 int
 583 ice_tx_prepare_vlan_flags_dcb(struct ice_ring *tx_ring,
 584                               struct ice_tx_buf *first)
 585 {
 586         struct sk_buff *skb = first->skb;
 587 
 588         if (!test_bit(ICE_FLAG_DCB_ENA, tx_ring->vsi->back->flags))
 589                 return 0;
 590 
 591         /* Insert 802.1p priority into VLAN header */
 592         if ((first->tx_flags & (ICE_TX_FLAGS_HW_VLAN | ICE_TX_FLAGS_SW_VLAN)) ||
 593             skb->priority != TC_PRIO_CONTROL) {
 594                 first->tx_flags &= ~ICE_TX_FLAGS_VLAN_PR_M;
 595                 /* Mask the lower 3 bits to set the 802.1p priority */
 596                 first->tx_flags |= (skb->priority & 0x7) <<
 597                                    ICE_TX_FLAGS_VLAN_PR_S;
 598                 if (first->tx_flags & ICE_TX_FLAGS_SW_VLAN) {
 599                         struct vlan_ethhdr *vhdr;
 600                         int rc;
 601 
 602                         rc = skb_cow_head(skb, 0);
 603                         if (rc < 0)
 604                                 return rc;
 605                         vhdr = (struct vlan_ethhdr *)skb->data;
 606                         vhdr->h_vlan_TCI = htons(first->tx_flags >>
 607                                                  ICE_TX_FLAGS_VLAN_S);
 608                 } else {
 609                         first->tx_flags |= ICE_TX_FLAGS_HW_VLAN;
 610                 }
 611         }
 612 
 613         return 0;
 614 }
 615 
 616 /**
 617  * ice_dcb_process_lldp_set_mib_change - Process MIB change
 618  * @pf: ptr to ice_pf
 619  * @event: pointer to the admin queue receive event
 620  */
 621 void
 622 ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf,
 623                                     struct ice_rq_event_info *event)
 624 {
 625         struct ice_aqc_port_ets_elem buf = { 0 };
 626         struct ice_aqc_lldp_get_mib *mib;
 627         struct ice_dcbx_cfg tmp_dcbx_cfg;
 628         bool need_reconfig = false;
 629         struct ice_port_info *pi;
 630         u8 type;
 631         int ret;
 632 
 633         /* Not DCB capable or capability disabled */
 634         if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
 635                 return;
 636 
 637         if (pf->dcbx_cap & DCB_CAP_DCBX_HOST) {
 638                 dev_dbg(&pf->pdev->dev,
 639                         "MIB Change Event in HOST mode\n");
 640                 return;
 641         }
 642 
 643         pi = pf->hw.port_info;
 644         mib = (struct ice_aqc_lldp_get_mib *)&event->desc.params.raw;
 645         /* Ignore if event is not for Nearest Bridge */
 646         type = ((mib->type >> ICE_AQ_LLDP_BRID_TYPE_S) &
 647                 ICE_AQ_LLDP_BRID_TYPE_M);
 648         dev_dbg(&pf->pdev->dev, "LLDP event MIB bridge type 0x%x\n", type);
 649         if (type != ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID)
 650                 return;
 651 
 652         /* Check MIB Type and return if event for Remote MIB update */
 653         type = mib->type & ICE_AQ_LLDP_MIB_TYPE_M;
 654         dev_dbg(&pf->pdev->dev,
 655                 "LLDP event mib type %s\n", type ? "remote" : "local");
 656         if (type == ICE_AQ_LLDP_MIB_REMOTE) {
 657                 /* Update the remote cached instance and return */
 658                 ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
 659                                          ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID,
 660                                          &pi->remote_dcbx_cfg);
 661                 if (ret) {
 662                         dev_err(&pf->pdev->dev, "Failed to get remote DCB config\n");
 663                         return;
 664                 }
 665         }
 666 
 667         /* store the old configuration */
 668         tmp_dcbx_cfg = pf->hw.port_info->local_dcbx_cfg;
 669 
 670         /* Reset the old DCBX configuration data */
 671         memset(&pi->local_dcbx_cfg, 0, sizeof(pi->local_dcbx_cfg));
 672 
 673         /* Get updated DCBX data from firmware */
 674         ret = ice_get_dcb_cfg(pf->hw.port_info);
 675         if (ret) {
 676                 dev_err(&pf->pdev->dev, "Failed to get DCB config\n");
 677                 return;
 678         }
 679 
 680         /* No change detected in DCBX configs */
 681         if (!memcmp(&tmp_dcbx_cfg, &pi->local_dcbx_cfg, sizeof(tmp_dcbx_cfg))) {
 682                 dev_dbg(&pf->pdev->dev,
 683                         "No change detected in DCBX configuration.\n");
 684                 return;
 685         }
 686 
 687         need_reconfig = ice_dcb_need_recfg(pf, &tmp_dcbx_cfg,
 688                                            &pi->local_dcbx_cfg);
 689         if (!need_reconfig)
 690                 return;
 691 
 692         /* Enable DCB tagging only when more than one TC */
 693         if (ice_dcb_get_num_tc(&pi->local_dcbx_cfg) > 1) {
 694                 dev_dbg(&pf->pdev->dev, "DCB tagging enabled (num TC > 1)\n");
 695                 set_bit(ICE_FLAG_DCB_ENA, pf->flags);
 696         } else {
 697                 dev_dbg(&pf->pdev->dev, "DCB tagging disabled (num TC = 1)\n");
 698                 clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
 699         }
 700 
 701         rtnl_lock();
 702         ice_pf_dis_all_vsi(pf, true);
 703 
 704         ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
 705         if (ret) {
 706                 dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
 707                 rtnl_unlock();
 708                 return;
 709         }
 710 
 711         /* changes in configuration update VSI */
 712         ice_pf_dcb_recfg(pf);
 713 
 714         ice_pf_ena_all_vsi(pf, true);
 715         rtnl_unlock();
 716 }

/* [<][>][^][v][top][bottom][index][help] */