1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2019, Intel Corporation. */ 3 4 #include "ice.h" 5 #include "ice_dcb.h" 6 #include "ice_dcb_lib.h" 7 #include "ice_dcb_nl.h" 8 #include <net/dcbnl.h> 9 10 /** 11 * ice_dcbnl_devreset - perform enough of a ifdown/ifup to sync DCBNL info 12 * @netdev: device associated with interface that needs reset 13 */ 14 static void ice_dcbnl_devreset(struct net_device *netdev) 15 { 16 struct ice_pf *pf = ice_netdev_to_pf(netdev); 17 18 while (ice_is_reset_in_progress(pf->state)) 19 usleep_range(1000, 2000); 20 21 dev_close(netdev); 22 netdev_state_change(netdev); 23 dev_open(netdev, NULL); 24 netdev_state_change(netdev); 25 } 26 27 /** 28 * ice_dcbnl_getets - retrieve local ETS configuration 29 * @netdev: the relevant netdev 30 * @ets: struct to hold ETS configuration 31 */ 32 static int ice_dcbnl_getets(struct net_device *netdev, struct ieee_ets *ets) 33 { 34 struct ice_dcbx_cfg *dcbxcfg; 35 struct ice_pf *pf; 36 37 pf = ice_netdev_to_pf(netdev); 38 dcbxcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 39 40 ets->willing = dcbxcfg->etscfg.willing; 41 ets->ets_cap = dcbxcfg->etscfg.maxtcs; 42 ets->cbs = dcbxcfg->etscfg.cbs; 43 memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_tx_bw)); 44 memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_rx_bw)); 45 memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable, sizeof(ets->tc_tsa)); 46 memcpy(ets->prio_tc, dcbxcfg->etscfg.prio_table, sizeof(ets->prio_tc)); 47 memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable, 48 sizeof(ets->tc_reco_bw)); 49 memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable, 50 sizeof(ets->tc_reco_tsa)); 51 memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prio_table, 52 sizeof(ets->reco_prio_tc)); 53 54 return 0; 55 } 56 57 /** 58 * ice_dcbnl_setets - set IEEE ETS configuration 59 * @netdev: pointer to relevant netdev 60 * @ets: struct to hold ETS configuration 61 */ 62 static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets) 63 { 64 struct ice_pf *pf = ice_netdev_to_pf(netdev); 65 struct ice_dcbx_cfg *new_cfg; 66 int bwcfg = 0, bwrec = 0; 67 int err, i; 68 69 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 70 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 71 return -EINVAL; 72 73 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 74 75 mutex_lock(&pf->tc_mutex); 76 77 new_cfg->etscfg.willing = ets->willing; 78 new_cfg->etscfg.cbs = ets->cbs; 79 ice_for_each_traffic_class(i) { 80 new_cfg->etscfg.tcbwtable[i] = ets->tc_tx_bw[i]; 81 bwcfg += ets->tc_tx_bw[i]; 82 new_cfg->etscfg.tsatable[i] = ets->tc_tsa[i]; 83 if (new_cfg->pfc_mode == ICE_QOS_MODE_VLAN) { 84 /* in DSCP mode up->tc mapping cannot change */ 85 new_cfg->etscfg.prio_table[i] = ets->prio_tc[i]; 86 new_cfg->etsrec.prio_table[i] = ets->reco_prio_tc[i]; 87 } 88 new_cfg->etsrec.tcbwtable[i] = ets->tc_reco_bw[i]; 89 bwrec += ets->tc_reco_bw[i]; 90 new_cfg->etsrec.tsatable[i] = ets->tc_reco_tsa[i]; 91 } 92 93 if (ice_dcb_bwchk(pf, new_cfg)) { 94 err = -EINVAL; 95 goto ets_out; 96 } 97 98 new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc; 99 100 if (!bwrec) 101 new_cfg->etsrec.tcbwtable[0] = 100; 102 103 err = ice_pf_dcb_cfg(pf, new_cfg, true); 104 /* return of zero indicates new cfg applied */ 105 if (err == ICE_DCB_HW_CHG_RST) 106 ice_dcbnl_devreset(netdev); 107 if (err == ICE_DCB_NO_HW_CHG) 108 err = ICE_DCB_HW_CHG_RST; 109 110 ets_out: 111 mutex_unlock(&pf->tc_mutex); 112 return err; 113 } 114 115 /** 116 * ice_dcbnl_getnumtcs - Get max number of traffic classes supported 117 * @dev: pointer to netdev struct 118 * @tcid: TC ID 119 * @num: total number of TCs supported by the adapter 120 * 121 * Return the total number of TCs supported 122 */ 123 static int 124 ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num) 125 { 126 struct ice_pf *pf = ice_netdev_to_pf(dev); 127 128 if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) 129 return -EINVAL; 130 131 *num = pf->hw.func_caps.common_cap.maxtc; 132 return 0; 133 } 134 135 /** 136 * ice_dcbnl_getdcbx - retrieve current DCBX capability 137 * @netdev: pointer to the netdev struct 138 */ 139 static u8 ice_dcbnl_getdcbx(struct net_device *netdev) 140 { 141 struct ice_pf *pf = ice_netdev_to_pf(netdev); 142 143 return pf->dcbx_cap; 144 } 145 146 /** 147 * ice_dcbnl_setdcbx - set required DCBX capability 148 * @netdev: the corresponding netdev 149 * @mode: required mode 150 */ 151 static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode) 152 { 153 struct ice_pf *pf = ice_netdev_to_pf(netdev); 154 struct ice_qos_cfg *qos_cfg; 155 156 /* if FW LLDP agent is running, DCBNL not allowed to change mode */ 157 if (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags)) 158 return ICE_DCB_NO_HW_CHG; 159 160 /* No support for LLD_MANAGED modes or CEE+IEEE */ 161 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || 162 ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || 163 !(mode & DCB_CAP_DCBX_HOST)) 164 return ICE_DCB_NO_HW_CHG; 165 166 /* Already set to the given mode no change */ 167 if (mode == pf->dcbx_cap) 168 return ICE_DCB_NO_HW_CHG; 169 170 pf->dcbx_cap = mode; 171 qos_cfg = &pf->hw.port_info->qos_cfg; 172 if (mode & DCB_CAP_DCBX_VER_CEE) { 173 if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP) 174 return ICE_DCB_NO_HW_CHG; 175 qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE; 176 } else { 177 qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE; 178 } 179 180 dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode); 181 return ICE_DCB_HW_CHG_RST; 182 } 183 184 /** 185 * ice_dcbnl_get_perm_hw_addr - MAC address used by DCBX 186 * @netdev: pointer to netdev struct 187 * @perm_addr: buffer to return permanent MAC address 188 */ 189 static void ice_dcbnl_get_perm_hw_addr(struct net_device *netdev, u8 *perm_addr) 190 { 191 struct ice_pf *pf = ice_netdev_to_pf(netdev); 192 struct ice_port_info *pi = pf->hw.port_info; 193 int i, j; 194 195 memset(perm_addr, 0xff, MAX_ADDR_LEN); 196 197 for (i = 0; i < netdev->addr_len; i++) 198 perm_addr[i] = pi->mac.perm_addr[i]; 199 200 for (j = 0; j < netdev->addr_len; j++, i++) 201 perm_addr[i] = pi->mac.perm_addr[j]; 202 } 203 204 /** 205 * ice_get_pfc_delay - Retrieve PFC Link Delay 206 * @hw: pointer to HW struct 207 * @delay: holds the PFC Link Delay value 208 */ 209 static void ice_get_pfc_delay(struct ice_hw *hw, u16 *delay) 210 { 211 u32 val; 212 213 val = rd32(hw, PRTDCB_GENC); 214 *delay = (u16)((val & PRTDCB_GENC_PFCLDA_M) >> PRTDCB_GENC_PFCLDA_S); 215 } 216 217 /** 218 * ice_dcbnl_getpfc - retrieve local IEEE PFC config 219 * @netdev: pointer to netdev struct 220 * @pfc: struct to hold PFC info 221 */ 222 static int ice_dcbnl_getpfc(struct net_device *netdev, struct ieee_pfc *pfc) 223 { 224 struct ice_pf *pf = ice_netdev_to_pf(netdev); 225 struct ice_port_info *pi = pf->hw.port_info; 226 struct ice_dcbx_cfg *dcbxcfg; 227 int i; 228 229 dcbxcfg = &pi->qos_cfg.local_dcbx_cfg; 230 pfc->pfc_cap = dcbxcfg->pfc.pfccap; 231 pfc->pfc_en = dcbxcfg->pfc.pfcena; 232 pfc->mbc = dcbxcfg->pfc.mbc; 233 ice_get_pfc_delay(&pf->hw, &pfc->delay); 234 235 ice_for_each_traffic_class(i) { 236 pfc->requests[i] = pf->stats.priority_xoff_tx[i]; 237 pfc->indications[i] = pf->stats.priority_xoff_rx[i]; 238 } 239 240 return 0; 241 } 242 243 /** 244 * ice_dcbnl_setpfc - set local IEEE PFC config 245 * @netdev: pointer to relevant netdev 246 * @pfc: pointer to struct holding PFC config 247 */ 248 static int ice_dcbnl_setpfc(struct net_device *netdev, struct ieee_pfc *pfc) 249 { 250 struct ice_pf *pf = ice_netdev_to_pf(netdev); 251 struct ice_dcbx_cfg *new_cfg; 252 int err; 253 254 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 255 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 256 return -EINVAL; 257 258 mutex_lock(&pf->tc_mutex); 259 260 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 261 262 if (pfc->pfc_cap) 263 new_cfg->pfc.pfccap = pfc->pfc_cap; 264 else 265 new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc; 266 267 new_cfg->pfc.pfcena = pfc->pfc_en; 268 269 err = ice_pf_dcb_cfg(pf, new_cfg, true); 270 if (err == ICE_DCB_HW_CHG_RST) 271 ice_dcbnl_devreset(netdev); 272 if (err == ICE_DCB_NO_HW_CHG) 273 err = ICE_DCB_HW_CHG_RST; 274 mutex_unlock(&pf->tc_mutex); 275 return err; 276 } 277 278 /** 279 * ice_dcbnl_get_pfc_cfg - Get CEE PFC config 280 * @netdev: pointer to netdev struct 281 * @prio: corresponding user priority 282 * @setting: the PFC setting for given priority 283 */ 284 static void 285 ice_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting) 286 { 287 struct ice_pf *pf = ice_netdev_to_pf(netdev); 288 struct ice_port_info *pi = pf->hw.port_info; 289 290 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 291 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 292 return; 293 294 if (prio >= ICE_MAX_USER_PRIORITY) 295 return; 296 297 *setting = (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena >> prio) & 0x1; 298 dev_dbg(ice_pf_to_dev(pf), "Get PFC Config up=%d, setting=%d, pfcenable=0x%x\n", 299 prio, *setting, pi->qos_cfg.local_dcbx_cfg.pfc.pfcena); 300 } 301 302 /** 303 * ice_dcbnl_set_pfc_cfg - Set CEE PFC config 304 * @netdev: the corresponding netdev 305 * @prio: User Priority 306 * @set: PFC setting to apply 307 */ 308 static void ice_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 set) 309 { 310 struct ice_pf *pf = ice_netdev_to_pf(netdev); 311 struct ice_dcbx_cfg *new_cfg; 312 313 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 314 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 315 return; 316 317 if (prio >= ICE_MAX_USER_PRIORITY) 318 return; 319 320 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 321 322 new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc; 323 if (set) 324 new_cfg->pfc.pfcena |= BIT(prio); 325 else 326 new_cfg->pfc.pfcena &= ~BIT(prio); 327 328 dev_dbg(ice_pf_to_dev(pf), "Set PFC config UP:%d set:%d pfcena:0x%x\n", 329 prio, set, new_cfg->pfc.pfcena); 330 } 331 332 /** 333 * ice_dcbnl_getpfcstate - get CEE PFC mode 334 * @netdev: pointer to netdev struct 335 */ 336 static u8 ice_dcbnl_getpfcstate(struct net_device *netdev) 337 { 338 struct ice_pf *pf = ice_netdev_to_pf(netdev); 339 struct ice_port_info *pi = pf->hw.port_info; 340 341 /* Return enabled if any UP enabled for PFC */ 342 if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena) 343 return 1; 344 345 return 0; 346 } 347 348 /** 349 * ice_dcbnl_getstate - get DCB enabled state 350 * @netdev: pointer to netdev struct 351 */ 352 static u8 ice_dcbnl_getstate(struct net_device *netdev) 353 { 354 struct ice_pf *pf = ice_netdev_to_pf(netdev); 355 u8 state = 0; 356 357 state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags); 358 359 dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state); 360 return state; 361 } 362 363 /** 364 * ice_dcbnl_setstate - Set CEE DCB state 365 * @netdev: pointer to relevant netdev 366 * @state: state value to set 367 */ 368 static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state) 369 { 370 struct ice_pf *pf = ice_netdev_to_pf(netdev); 371 372 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 373 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 374 return ICE_DCB_NO_HW_CHG; 375 376 /* Nothing to do */ 377 if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags)) 378 return ICE_DCB_NO_HW_CHG; 379 380 if (state) { 381 set_bit(ICE_FLAG_DCB_ENA, pf->flags); 382 memcpy(&pf->hw.port_info->qos_cfg.desired_dcbx_cfg, 383 &pf->hw.port_info->qos_cfg.local_dcbx_cfg, 384 sizeof(struct ice_dcbx_cfg)); 385 } else { 386 clear_bit(ICE_FLAG_DCB_ENA, pf->flags); 387 } 388 389 return ICE_DCB_HW_CHG; 390 } 391 392 /** 393 * ice_dcbnl_get_pg_tc_cfg_tx - get CEE PG Tx config 394 * @netdev: pointer to netdev struct 395 * @prio: the corresponding user priority 396 * @prio_type: traffic priority type 397 * @pgid: the BW group ID the traffic class belongs to 398 * @bw_pct: BW percentage for the corresponding BWG 399 * @up_map: prio mapped to corresponding TC 400 */ 401 static void 402 ice_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio, 403 u8 __always_unused *prio_type, u8 *pgid, 404 u8 __always_unused *bw_pct, 405 u8 __always_unused *up_map) 406 { 407 struct ice_pf *pf = ice_netdev_to_pf(netdev); 408 struct ice_port_info *pi = pf->hw.port_info; 409 410 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 411 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 412 return; 413 414 if (prio >= ICE_MAX_USER_PRIORITY) 415 return; 416 417 *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio]; 418 dev_dbg(ice_pf_to_dev(pf), "Get PG config prio=%d tc=%d\n", prio, 419 *pgid); 420 } 421 422 /** 423 * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config 424 * @netdev: pointer to relevant netdev 425 * @tc: the corresponding traffic class 426 * @prio_type: the traffic priority type 427 * @bwg_id: the BW group ID the TC belongs to 428 * @bw_pct: the BW perventage for the BWG 429 * @up_map: prio mapped to corresponding TC 430 */ 431 static void 432 ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, 433 u8 __always_unused prio_type, 434 u8 __always_unused bwg_id, 435 u8 __always_unused bw_pct, u8 up_map) 436 { 437 struct ice_pf *pf = ice_netdev_to_pf(netdev); 438 struct ice_dcbx_cfg *new_cfg; 439 int i; 440 441 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 442 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 443 return; 444 445 if (tc >= ICE_MAX_TRAFFIC_CLASS) 446 return; 447 448 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 449 450 /* prio_type, bwg_id and bw_pct per UP are not supported */ 451 452 ice_for_each_traffic_class(i) { 453 if (up_map & BIT(i)) 454 new_cfg->etscfg.prio_table[i] = tc; 455 } 456 new_cfg->etscfg.tsatable[tc] = ICE_IEEE_TSA_ETS; 457 } 458 459 /** 460 * ice_dcbnl_get_pg_bwg_cfg_tx - Get CEE PGBW config 461 * @netdev: pointer to the netdev struct 462 * @pgid: corresponding traffic class 463 * @bw_pct: the BW percentage for the corresponding TC 464 */ 465 static void 466 ice_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 *bw_pct) 467 { 468 struct ice_pf *pf = ice_netdev_to_pf(netdev); 469 struct ice_port_info *pi = pf->hw.port_info; 470 471 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 472 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 473 return; 474 475 if (pgid >= ICE_MAX_TRAFFIC_CLASS) 476 return; 477 478 *bw_pct = pi->qos_cfg.local_dcbx_cfg.etscfg.tcbwtable[pgid]; 479 dev_dbg(ice_pf_to_dev(pf), "Get PG BW config tc=%d bw_pct=%d\n", 480 pgid, *bw_pct); 481 } 482 483 /** 484 * ice_dcbnl_set_pg_bwg_cfg_tx - set CEE PG Tx BW config 485 * @netdev: the corresponding netdev 486 * @pgid: Correspongind traffic class 487 * @bw_pct: the BW percentage for the specified TC 488 */ 489 static void 490 ice_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 bw_pct) 491 { 492 struct ice_pf *pf = ice_netdev_to_pf(netdev); 493 struct ice_dcbx_cfg *new_cfg; 494 495 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 496 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 497 return; 498 499 if (pgid >= ICE_MAX_TRAFFIC_CLASS) 500 return; 501 502 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 503 504 new_cfg->etscfg.tcbwtable[pgid] = bw_pct; 505 } 506 507 /** 508 * ice_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config 509 * @netdev: pointer to netdev struct 510 * @prio: the corresponding user priority 511 * @prio_type: the traffic priority type 512 * @pgid: the PG ID 513 * @bw_pct: the BW percentage for the corresponding BWG 514 * @up_map: prio mapped to corresponding TC 515 */ 516 static void 517 ice_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio, 518 u8 __always_unused *prio_type, u8 *pgid, 519 u8 __always_unused *bw_pct, 520 u8 __always_unused *up_map) 521 { 522 struct ice_pf *pf = ice_netdev_to_pf(netdev); 523 struct ice_port_info *pi = pf->hw.port_info; 524 525 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 526 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 527 return; 528 529 if (prio >= ICE_MAX_USER_PRIORITY) 530 return; 531 532 *pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio]; 533 } 534 535 /** 536 * ice_dcbnl_set_pg_tc_cfg_rx 537 * @netdev: relevant netdev struct 538 * @prio: corresponding user priority 539 * @prio_type: the traffic priority type 540 * @pgid: the PG ID 541 * @bw_pct: BW percentage for corresponding BWG 542 * @up_map: prio mapped to corresponding TC 543 * 544 * lldpad requires this function pointer to be non-NULL to complete CEE config. 545 */ 546 static void 547 ice_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, 548 int __always_unused prio, 549 u8 __always_unused prio_type, 550 u8 __always_unused pgid, 551 u8 __always_unused bw_pct, 552 u8 __always_unused up_map) 553 { 554 struct ice_pf *pf = ice_netdev_to_pf(netdev); 555 556 dev_dbg(ice_pf_to_dev(pf), "Rx TC PG Config Not Supported.\n"); 557 } 558 559 /** 560 * ice_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config 561 * @netdev: pointer to netdev struct 562 * @pgid: the corresponding traffic class 563 * @bw_pct: the BW percentage for the corresponding TC 564 */ 565 static void 566 ice_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid, 567 u8 *bw_pct) 568 { 569 struct ice_pf *pf = ice_netdev_to_pf(netdev); 570 571 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 572 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 573 return; 574 575 *bw_pct = 0; 576 } 577 578 /** 579 * ice_dcbnl_set_pg_bwg_cfg_rx 580 * @netdev: the corresponding netdev 581 * @pgid: corresponding TC 582 * @bw_pct: BW percentage for given TC 583 * 584 * lldpad requires this function pointer to be non-NULL to complete CEE config. 585 */ 586 static void 587 ice_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid, 588 u8 __always_unused bw_pct) 589 { 590 struct ice_pf *pf = ice_netdev_to_pf(netdev); 591 592 dev_dbg(ice_pf_to_dev(pf), "Rx BWG PG Config Not Supported.\n"); 593 } 594 595 /** 596 * ice_dcbnl_get_cap - Get DCBX capabilities of adapter 597 * @netdev: pointer to netdev struct 598 * @capid: the capability type 599 * @cap: the capability value 600 */ 601 static u8 ice_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) 602 { 603 struct ice_pf *pf = ice_netdev_to_pf(netdev); 604 605 if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))) 606 return ICE_DCB_NO_HW_CHG; 607 608 switch (capid) { 609 case DCB_CAP_ATTR_PG: 610 *cap = true; 611 break; 612 case DCB_CAP_ATTR_PFC: 613 *cap = true; 614 break; 615 case DCB_CAP_ATTR_UP2TC: 616 *cap = false; 617 break; 618 case DCB_CAP_ATTR_PG_TCS: 619 *cap = 0x80; 620 break; 621 case DCB_CAP_ATTR_PFC_TCS: 622 *cap = 0x80; 623 break; 624 case DCB_CAP_ATTR_GSP: 625 *cap = false; 626 break; 627 case DCB_CAP_ATTR_BCN: 628 *cap = false; 629 break; 630 case DCB_CAP_ATTR_DCBX: 631 *cap = pf->dcbx_cap; 632 break; 633 default: 634 *cap = false; 635 break; 636 } 637 638 dev_dbg(ice_pf_to_dev(pf), "DCBX Get Capability cap=%d capval=0x%x\n", 639 capid, *cap); 640 return 0; 641 } 642 643 /** 644 * ice_dcbnl_getapp - get CEE APP 645 * @netdev: pointer to netdev struct 646 * @idtype: the App selector 647 * @id: the App ethtype or port number 648 */ 649 static int ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) 650 { 651 struct ice_pf *pf = ice_netdev_to_pf(netdev); 652 struct dcb_app app = { 653 .selector = idtype, 654 .protocol = id, 655 }; 656 657 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 658 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 659 return -EINVAL; 660 661 return dcb_getapp(netdev, &app); 662 } 663 664 /** 665 * ice_dcbnl_find_app - Search for APP in given DCB config 666 * @cfg: struct to hold DCBX config 667 * @app: struct to hold app data to look for 668 */ 669 static bool 670 ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg, 671 struct ice_dcb_app_priority_table *app) 672 { 673 unsigned int i; 674 675 for (i = 0; i < cfg->numapps; i++) { 676 if (app->selector == cfg->app[i].selector && 677 app->prot_id == cfg->app[i].prot_id && 678 app->priority == cfg->app[i].priority) 679 return true; 680 } 681 682 return false; 683 } 684 685 #define ICE_BYTES_PER_DSCP_VAL 8 686 687 /** 688 * ice_dcbnl_setapp - set local IEEE App config 689 * @netdev: relevant netdev struct 690 * @app: struct to hold app config info 691 */ 692 static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app) 693 { 694 struct ice_pf *pf = ice_netdev_to_pf(netdev); 695 struct ice_dcb_app_priority_table new_app; 696 struct ice_dcbx_cfg *old_cfg, *new_cfg; 697 u8 max_tc; 698 int ret; 699 700 /* ONLY DSCP APP TLVs have operational significance */ 701 if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP) 702 return -EINVAL; 703 704 /* only allow APP TLVs in SW Mode */ 705 if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) { 706 netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n"); 707 return -EINVAL; 708 } 709 710 if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) 711 return -EINVAL; 712 713 if (!ice_is_feature_supported(pf, ICE_F_DSCP)) 714 return -EOPNOTSUPP; 715 716 if (app->protocol >= ICE_DSCP_NUM_VAL) { 717 netdev_err(netdev, "DSCP value 0x%04X out of range\n", 718 app->protocol); 719 return -EINVAL; 720 } 721 722 max_tc = pf->hw.func_caps.common_cap.maxtc; 723 if (app->priority >= max_tc) { 724 netdev_err(netdev, "TC %d out of range, max TC %d\n", 725 app->priority, max_tc); 726 return -EINVAL; 727 } 728 729 /* grab TC mutex */ 730 mutex_lock(&pf->tc_mutex); 731 732 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 733 old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 734 735 ret = dcb_ieee_setapp(netdev, app); 736 if (ret) 737 goto setapp_out; 738 739 if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) { 740 netdev_err(netdev, "DSCP value 0x%04X already user mapped\n", 741 app->protocol); 742 ret = dcb_ieee_delapp(netdev, app); 743 if (ret) 744 netdev_err(netdev, "Failed to delete re-mapping TLV\n"); 745 ret = -EINVAL; 746 goto setapp_out; 747 } 748 749 new_app.selector = app->selector; 750 new_app.prot_id = app->protocol; 751 new_app.priority = app->priority; 752 753 /* If port is not in DSCP mode, need to set */ 754 if (old_cfg->pfc_mode == ICE_QOS_MODE_VLAN) { 755 int i, j; 756 757 /* set DSCP mode */ 758 ret = ice_aq_set_pfc_mode(&pf->hw, ICE_AQC_PFC_DSCP_BASED_PFC, 759 NULL); 760 if (ret) { 761 netdev_err(netdev, "Failed to set DSCP PFC mode %d\n", 762 ret); 763 goto setapp_out; 764 } 765 netdev_info(netdev, "Switched QoS to L3 DSCP mode\n"); 766 767 new_cfg->pfc_mode = ICE_QOS_MODE_DSCP; 768 769 /* set default DSCP QoS values */ 770 new_cfg->etscfg.willing = 0; 771 new_cfg->pfc.pfccap = max_tc; 772 new_cfg->pfc.willing = 0; 773 774 for (i = 0; i < max_tc; i++) 775 for (j = 0; j < ICE_BYTES_PER_DSCP_VAL; j++) { 776 int dscp, offset; 777 778 dscp = (i * max_tc) + j; 779 offset = max_tc * ICE_BYTES_PER_DSCP_VAL; 780 781 new_cfg->dscp_map[dscp] = i; 782 /* if less that 8 TCs supported */ 783 if (max_tc < ICE_MAX_TRAFFIC_CLASS) 784 new_cfg->dscp_map[dscp + offset] = i; 785 } 786 787 new_cfg->etscfg.tcbwtable[0] = 100; 788 new_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS; 789 new_cfg->etscfg.prio_table[0] = 0; 790 791 for (i = 1; i < max_tc; i++) { 792 new_cfg->etscfg.tcbwtable[i] = 0; 793 new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS; 794 new_cfg->etscfg.prio_table[i] = i; 795 } 796 } /* end of switching to DSCP mode */ 797 798 /* apply new mapping for this DSCP value */ 799 new_cfg->dscp_map[app->protocol] = app->priority; 800 new_cfg->app[new_cfg->numapps++] = new_app; 801 802 ret = ice_pf_dcb_cfg(pf, new_cfg, true); 803 /* return of zero indicates new cfg applied */ 804 if (ret == ICE_DCB_HW_CHG_RST) 805 ice_dcbnl_devreset(netdev); 806 else 807 ret = ICE_DCB_NO_HW_CHG; 808 809 setapp_out: 810 mutex_unlock(&pf->tc_mutex); 811 return ret; 812 } 813 814 /** 815 * ice_dcbnl_delapp - Delete local IEEE App config 816 * @netdev: relevant netdev 817 * @app: struct to hold app too delete 818 * 819 * Will not delete first application required by the FW 820 */ 821 static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app) 822 { 823 struct ice_pf *pf = ice_netdev_to_pf(netdev); 824 struct ice_dcbx_cfg *old_cfg, *new_cfg; 825 unsigned int i, j; 826 int ret = 0; 827 828 if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) { 829 netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n"); 830 return -EINVAL; 831 } 832 833 mutex_lock(&pf->tc_mutex); 834 old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 835 836 ret = dcb_ieee_delapp(netdev, app); 837 if (ret) 838 goto delapp_out; 839 840 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 841 842 for (i = 0; i < new_cfg->numapps; i++) { 843 if (app->selector == new_cfg->app[i].selector && 844 app->protocol == new_cfg->app[i].prot_id && 845 app->priority == new_cfg->app[i].priority) { 846 new_cfg->app[i].selector = 0; 847 new_cfg->app[i].prot_id = 0; 848 new_cfg->app[i].priority = 0; 849 break; 850 } 851 } 852 853 /* Did not find DCB App */ 854 if (i == new_cfg->numapps) { 855 ret = -EINVAL; 856 goto delapp_out; 857 } 858 859 new_cfg->numapps--; 860 861 for (j = i; j < new_cfg->numapps; j++) { 862 new_cfg->app[j].selector = old_cfg->app[j + 1].selector; 863 new_cfg->app[j].prot_id = old_cfg->app[j + 1].prot_id; 864 new_cfg->app[j].priority = old_cfg->app[j + 1].priority; 865 } 866 867 /* if not a DSCP APP TLV or DSCP is not supported, we are done */ 868 if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP || 869 !ice_is_feature_supported(pf, ICE_F_DSCP)) { 870 ret = ICE_DCB_HW_CHG; 871 goto delapp_out; 872 } 873 874 /* if DSCP TLV, then need to address change in mapping */ 875 clear_bit(app->protocol, new_cfg->dscp_mapped); 876 /* remap this DSCP value to default value */ 877 new_cfg->dscp_map[app->protocol] = app->protocol % 878 ICE_BYTES_PER_DSCP_VAL; 879 880 /* if the last DSCP mapping just got deleted, need to switch 881 * to L2 VLAN QoS mode 882 */ 883 if (bitmap_empty(new_cfg->dscp_mapped, ICE_DSCP_NUM_VAL) && 884 new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) { 885 ret = ice_aq_set_pfc_mode(&pf->hw, 886 ICE_AQC_PFC_VLAN_BASED_PFC, 887 NULL); 888 if (ret) { 889 netdev_info(netdev, "Failed to set VLAN PFC mode %d\n", 890 ret); 891 goto delapp_out; 892 } 893 netdev_info(netdev, "Switched QoS to L2 VLAN mode\n"); 894 895 new_cfg->pfc_mode = ICE_QOS_MODE_VLAN; 896 897 ret = ice_dcb_sw_dflt_cfg(pf, true, true); 898 } else { 899 ret = ice_pf_dcb_cfg(pf, new_cfg, true); 900 } 901 902 /* return of ICE_DCB_HW_CHG_RST indicates new cfg applied 903 * and reset needs to be performed 904 */ 905 if (ret == ICE_DCB_HW_CHG_RST) 906 ice_dcbnl_devreset(netdev); 907 908 /* if the change was not siginificant enough to actually call 909 * the reconfiguration flow, we still need to tell caller that 910 * their request was successfully handled 911 */ 912 if (ret == ICE_DCB_NO_HW_CHG) 913 ret = ICE_DCB_HW_CHG; 914 915 delapp_out: 916 mutex_unlock(&pf->tc_mutex); 917 return ret; 918 } 919 920 /** 921 * ice_dcbnl_cee_set_all - Commit CEE DCB settings to HW 922 * @netdev: the corresponding netdev 923 */ 924 static u8 ice_dcbnl_cee_set_all(struct net_device *netdev) 925 { 926 struct ice_pf *pf = ice_netdev_to_pf(netdev); 927 struct ice_dcbx_cfg *new_cfg; 928 int err; 929 930 if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) || 931 !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) 932 return ICE_DCB_NO_HW_CHG; 933 934 new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg; 935 936 mutex_lock(&pf->tc_mutex); 937 938 err = ice_pf_dcb_cfg(pf, new_cfg, true); 939 940 mutex_unlock(&pf->tc_mutex); 941 return (err != ICE_DCB_HW_CHG_RST) ? ICE_DCB_NO_HW_CHG : err; 942 } 943 944 static const struct dcbnl_rtnl_ops dcbnl_ops = { 945 /* IEEE 802.1Qaz std */ 946 .ieee_getets = ice_dcbnl_getets, 947 .ieee_setets = ice_dcbnl_setets, 948 .ieee_getpfc = ice_dcbnl_getpfc, 949 .ieee_setpfc = ice_dcbnl_setpfc, 950 .ieee_setapp = ice_dcbnl_setapp, 951 .ieee_delapp = ice_dcbnl_delapp, 952 953 /* CEE std */ 954 .getstate = ice_dcbnl_getstate, 955 .setstate = ice_dcbnl_setstate, 956 .getpermhwaddr = ice_dcbnl_get_perm_hw_addr, 957 .setpgtccfgtx = ice_dcbnl_set_pg_tc_cfg_tx, 958 .setpgbwgcfgtx = ice_dcbnl_set_pg_bwg_cfg_tx, 959 .setpgtccfgrx = ice_dcbnl_set_pg_tc_cfg_rx, 960 .setpgbwgcfgrx = ice_dcbnl_set_pg_bwg_cfg_rx, 961 .getpgtccfgtx = ice_dcbnl_get_pg_tc_cfg_tx, 962 .getpgbwgcfgtx = ice_dcbnl_get_pg_bwg_cfg_tx, 963 .getpgtccfgrx = ice_dcbnl_get_pg_tc_cfg_rx, 964 .getpgbwgcfgrx = ice_dcbnl_get_pg_bwg_cfg_rx, 965 .setpfccfg = ice_dcbnl_set_pfc_cfg, 966 .getpfccfg = ice_dcbnl_get_pfc_cfg, 967 .setall = ice_dcbnl_cee_set_all, 968 .getcap = ice_dcbnl_get_cap, 969 .getnumtcs = ice_dcbnl_getnumtcs, 970 .getpfcstate = ice_dcbnl_getpfcstate, 971 .getapp = ice_dcbnl_getapp, 972 973 /* DCBX configuration */ 974 .getdcbx = ice_dcbnl_getdcbx, 975 .setdcbx = ice_dcbnl_setdcbx, 976 }; 977 978 /** 979 * ice_dcbnl_set_all - set all the apps and ieee data from DCBX config 980 * @vsi: pointer to VSI struct 981 */ 982 void ice_dcbnl_set_all(struct ice_vsi *vsi) 983 { 984 struct net_device *netdev = vsi->netdev; 985 struct ice_dcbx_cfg *dcbxcfg; 986 struct ice_port_info *pi; 987 struct dcb_app sapp; 988 struct ice_pf *pf; 989 unsigned int i; 990 991 if (!netdev) 992 return; 993 994 pf = ice_netdev_to_pf(netdev); 995 pi = pf->hw.port_info; 996 997 /* SW DCB taken care of by SW Default Config */ 998 if (pf->dcbx_cap & DCB_CAP_DCBX_HOST) 999 return; 1000 1001 /* DCB not enabled */ 1002 if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags)) 1003 return; 1004 1005 dcbxcfg = &pi->qos_cfg.local_dcbx_cfg; 1006 1007 for (i = 0; i < dcbxcfg->numapps; i++) { 1008 u8 prio, tc_map; 1009 1010 prio = dcbxcfg->app[i].priority; 1011 tc_map = BIT(dcbxcfg->etscfg.prio_table[prio]); 1012 1013 /* Add APP only if the TC is enabled for this VSI */ 1014 if (tc_map & vsi->tc_cfg.ena_tc) { 1015 sapp.selector = dcbxcfg->app[i].selector; 1016 sapp.protocol = dcbxcfg->app[i].prot_id; 1017 sapp.priority = prio; 1018 dcb_ieee_setapp(netdev, &sapp); 1019 } 1020 } 1021 /* Notify user-space of the changes */ 1022 dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0); 1023 } 1024 1025 /** 1026 * ice_dcbnl_vsi_del_app - Delete APP on all VSIs 1027 * @vsi: pointer to the main VSI 1028 * @app: APP to delete 1029 * 1030 * Delete given APP from all the VSIs for given PF 1031 */ 1032 static void 1033 ice_dcbnl_vsi_del_app(struct ice_vsi *vsi, 1034 struct ice_dcb_app_priority_table *app) 1035 { 1036 struct dcb_app sapp; 1037 int err; 1038 1039 sapp.selector = app->selector; 1040 sapp.protocol = app->prot_id; 1041 sapp.priority = app->priority; 1042 err = ice_dcbnl_delapp(vsi->netdev, &sapp); 1043 dev_dbg(ice_pf_to_dev(vsi->back), "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n", 1044 vsi->idx, err, app->selector, app->prot_id, app->priority); 1045 } 1046 1047 /** 1048 * ice_dcbnl_flush_apps - Delete all removed APPs 1049 * @pf: the corresponding PF 1050 * @old_cfg: old DCBX configuration data 1051 * @new_cfg: new DCBX configuration data 1052 * 1053 * Find and delete all APPS that are not present in the passed 1054 * DCB configuration 1055 */ 1056 void 1057 ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg, 1058 struct ice_dcbx_cfg *new_cfg) 1059 { 1060 struct ice_vsi *main_vsi = ice_get_main_vsi(pf); 1061 unsigned int i; 1062 1063 if (!main_vsi) 1064 return; 1065 1066 for (i = 0; i < old_cfg->numapps; i++) { 1067 struct ice_dcb_app_priority_table app = old_cfg->app[i]; 1068 1069 /* The APP is not available anymore delete it */ 1070 if (!ice_dcbnl_find_app(new_cfg, &app)) 1071 ice_dcbnl_vsi_del_app(main_vsi, &app); 1072 } 1073 } 1074 1075 /** 1076 * ice_dcbnl_setup - setup DCBNL 1077 * @vsi: VSI to get associated netdev from 1078 */ 1079 void ice_dcbnl_setup(struct ice_vsi *vsi) 1080 { 1081 struct net_device *netdev = vsi->netdev; 1082 struct ice_pf *pf; 1083 1084 pf = ice_netdev_to_pf(netdev); 1085 if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)) 1086 return; 1087 1088 netdev->dcbnl_ops = &dcbnl_ops; 1089 ice_dcbnl_set_all(vsi); 1090 } 1091