1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 /* Copyright (C) 2023 Corigine, Inc. */ 3 4 #include <linux/device.h> 5 #include <linux/netdevice.h> 6 #include <net/dcbnl.h> 7 8 #include "../nfp_app.h" 9 #include "../nfp_net.h" 10 #include "../nfp_main.h" 11 #include "../nfpcore/nfp_cpp.h" 12 #include "../nfpcore/nfp_nffw.h" 13 #include "../nfp_net_sriov.h" 14 15 #include "main.h" 16 17 #define NFP_DCB_TRUST_PCP 1 18 #define NFP_DCB_TRUST_DSCP 2 19 #define NFP_DCB_TRUST_INVALID 0xff 20 21 #define NFP_DCB_TSA_VENDOR 1 22 #define NFP_DCB_TSA_STRICT 2 23 #define NFP_DCB_TSA_ETS 3 24 25 #define NFP_DCB_GBL_ENABLE BIT(0) 26 #define NFP_DCB_QOS_ENABLE BIT(1) 27 #define NFP_DCB_DISABLE 0 28 #define NFP_DCB_ALL_QOS_ENABLE (NFP_DCB_GBL_ENABLE | NFP_DCB_QOS_ENABLE) 29 30 #define NFP_DCB_UPDATE_MSK_SZ 4 31 #define NFP_DCB_TC_RATE_MAX 0xffff 32 33 #define NFP_DCB_DATA_OFF_DSCP2IDX 0 34 #define NFP_DCB_DATA_OFF_PCP2IDX 64 35 #define NFP_DCB_DATA_OFF_TSA 80 36 #define NFP_DCB_DATA_OFF_IDX_BW_PCT 88 37 #define NFP_DCB_DATA_OFF_RATE 96 38 #define NFP_DCB_DATA_OFF_CAP 112 39 #define NFP_DCB_DATA_OFF_ENABLE 116 40 #define NFP_DCB_DATA_OFF_TRUST 120 41 42 #define NFP_DCB_MSG_MSK_ENABLE BIT(31) 43 #define NFP_DCB_MSG_MSK_TRUST BIT(30) 44 #define NFP_DCB_MSG_MSK_TSA BIT(29) 45 #define NFP_DCB_MSG_MSK_DSCP BIT(28) 46 #define NFP_DCB_MSG_MSK_PCP BIT(27) 47 #define NFP_DCB_MSG_MSK_RATE BIT(26) 48 #define NFP_DCB_MSG_MSK_PCT BIT(25) 49 50 static struct nfp_dcb *get_dcb_priv(struct nfp_net *nn) 51 { 52 struct nfp_dcb *dcb = &((struct nfp_app_nic_private *)nn->app_priv)->dcb; 53 54 return dcb; 55 } 56 57 static u8 nfp_tsa_ieee2nfp(u8 tsa) 58 { 59 switch (tsa) { 60 case IEEE_8021QAZ_TSA_STRICT: 61 return NFP_DCB_TSA_STRICT; 62 case IEEE_8021QAZ_TSA_ETS: 63 return NFP_DCB_TSA_ETS; 64 default: 65 return NFP_DCB_TSA_VENDOR; 66 } 67 } 68 69 static int nfp_nic_dcbnl_ieee_getets(struct net_device *dev, 70 struct ieee_ets *ets) 71 { 72 struct nfp_net *nn = netdev_priv(dev); 73 struct nfp_dcb *dcb; 74 75 dcb = get_dcb_priv(nn); 76 77 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 78 ets->prio_tc[i] = dcb->prio2tc[i]; 79 ets->tc_tx_bw[i] = dcb->tc_tx_pct[i]; 80 ets->tc_tsa[i] = dcb->tc_tsa[i]; 81 } 82 83 return 0; 84 } 85 86 static bool nfp_refresh_tc2idx(struct nfp_net *nn) 87 { 88 u8 tc2idx[IEEE_8021QAZ_MAX_TCS]; 89 bool change = false; 90 struct nfp_dcb *dcb; 91 int maxstrict = 0; 92 93 dcb = get_dcb_priv(nn); 94 95 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 96 tc2idx[i] = i; 97 if (dcb->tc_tsa[i] == IEEE_8021QAZ_TSA_STRICT) 98 maxstrict = i; 99 } 100 101 if (maxstrict > 0 && dcb->tc_tsa[0] != IEEE_8021QAZ_TSA_STRICT) { 102 tc2idx[0] = maxstrict; 103 tc2idx[maxstrict] = 0; 104 } 105 106 for (unsigned int j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) { 107 if (dcb->tc2idx[j] != tc2idx[j]) { 108 change = true; 109 dcb->tc2idx[j] = tc2idx[j]; 110 } 111 } 112 113 return change; 114 } 115 116 static int nfp_fill_maxrate(struct nfp_net *nn, u64 *max_rate_array) 117 { 118 struct nfp_app *app = nn->app; 119 struct nfp_dcb *dcb; 120 u32 ratembps; 121 122 dcb = get_dcb_priv(nn); 123 124 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 125 /* Convert bandwidth from kbps to mbps. */ 126 ratembps = max_rate_array[i] / 1024; 127 128 /* Reject input values >= NFP_DCB_TC_RATE_MAX */ 129 if (ratembps >= NFP_DCB_TC_RATE_MAX) { 130 nfp_warn(app->cpp, "ratembps(%d) must less than %d.", 131 ratembps, NFP_DCB_TC_RATE_MAX); 132 return -EINVAL; 133 } 134 /* Input value 0 mapped to NFP_DCB_TC_RATE_MAX for firmware. */ 135 if (ratembps == 0) 136 ratembps = NFP_DCB_TC_RATE_MAX; 137 138 writew((u16)ratembps, dcb->dcbcfg_tbl + 139 dcb->cfg_offset + NFP_DCB_DATA_OFF_RATE + dcb->tc2idx[i] * 2); 140 /* for rate value from user space, need to sync to dcb structure */ 141 if (dcb->tc_maxrate != max_rate_array) 142 dcb->tc_maxrate[i] = max_rate_array[i]; 143 } 144 145 return 0; 146 } 147 148 static int update_dscp_maxrate(struct net_device *dev, u32 *update) 149 { 150 struct nfp_net *nn = netdev_priv(dev); 151 struct nfp_dcb *dcb; 152 int err; 153 154 dcb = get_dcb_priv(nn); 155 156 err = nfp_fill_maxrate(nn, dcb->tc_maxrate); 157 if (err) 158 return err; 159 160 *update |= NFP_DCB_MSG_MSK_RATE; 161 162 /* We only refresh dscp in dscp trust mode. */ 163 if (dcb->dscp_cnt > 0) { 164 for (unsigned int i = 0; i < NFP_NET_MAX_DSCP; i++) { 165 writeb(dcb->tc2idx[dcb->prio2tc[dcb->dscp2prio[i]]], 166 dcb->dcbcfg_tbl + dcb->cfg_offset + 167 NFP_DCB_DATA_OFF_DSCP2IDX + i); 168 } 169 *update |= NFP_DCB_MSG_MSK_DSCP; 170 } 171 172 return 0; 173 } 174 175 static void nfp_nic_set_trust(struct nfp_net *nn, u32 *update) 176 { 177 struct nfp_dcb *dcb; 178 u8 trust; 179 180 dcb = get_dcb_priv(nn); 181 182 if (dcb->trust_status != NFP_DCB_TRUST_INVALID) 183 return; 184 185 trust = dcb->dscp_cnt > 0 ? NFP_DCB_TRUST_DSCP : NFP_DCB_TRUST_PCP; 186 writeb(trust, dcb->dcbcfg_tbl + dcb->cfg_offset + 187 NFP_DCB_DATA_OFF_TRUST); 188 189 dcb->trust_status = trust; 190 *update |= NFP_DCB_MSG_MSK_TRUST; 191 } 192 193 static void nfp_nic_set_enable(struct nfp_net *nn, u32 enable, u32 *update) 194 { 195 struct nfp_dcb *dcb; 196 u32 value = 0; 197 198 dcb = get_dcb_priv(nn); 199 200 value = readl(dcb->dcbcfg_tbl + dcb->cfg_offset + 201 NFP_DCB_DATA_OFF_ENABLE); 202 if (value != enable) { 203 writel(enable, dcb->dcbcfg_tbl + dcb->cfg_offset + 204 NFP_DCB_DATA_OFF_ENABLE); 205 *update |= NFP_DCB_MSG_MSK_ENABLE; 206 } 207 } 208 209 static int dcb_ets_check(struct net_device *dev, struct ieee_ets *ets) 210 { 211 struct nfp_net *nn = netdev_priv(dev); 212 struct nfp_app *app = nn->app; 213 bool ets_exists = false; 214 int sum = 0; 215 216 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 217 /* For ets mode, check bw percentage sum. */ 218 if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) { 219 ets_exists = true; 220 sum += ets->tc_tx_bw[i]; 221 } else if (ets->tc_tx_bw[i]) { 222 nfp_warn(app->cpp, "ETS BW for strict/vendor TC must be 0."); 223 return -EINVAL; 224 } 225 } 226 227 if (ets_exists && sum != 100) { 228 nfp_warn(app->cpp, "Failed to validate ETS BW: sum must be 100."); 229 return -EINVAL; 230 } 231 232 return 0; 233 } 234 235 static void nfp_nic_fill_ets(struct nfp_net *nn) 236 { 237 struct nfp_dcb *dcb; 238 239 dcb = get_dcb_priv(nn); 240 241 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 242 writeb(dcb->tc2idx[dcb->prio2tc[i]], 243 dcb->dcbcfg_tbl + dcb->cfg_offset + NFP_DCB_DATA_OFF_PCP2IDX + i); 244 writeb(dcb->tc_tx_pct[i], dcb->dcbcfg_tbl + 245 dcb->cfg_offset + NFP_DCB_DATA_OFF_IDX_BW_PCT + dcb->tc2idx[i]); 246 writeb(nfp_tsa_ieee2nfp(dcb->tc_tsa[i]), dcb->dcbcfg_tbl + 247 dcb->cfg_offset + NFP_DCB_DATA_OFF_TSA + dcb->tc2idx[i]); 248 } 249 } 250 251 static void nfp_nic_ets_init(struct nfp_net *nn, u32 *update) 252 { 253 struct nfp_dcb *dcb = get_dcb_priv(nn); 254 255 if (dcb->ets_init) 256 return; 257 258 nfp_nic_fill_ets(nn); 259 dcb->ets_init = true; 260 *update |= NFP_DCB_MSG_MSK_TSA | NFP_DCB_MSG_MSK_PCT | NFP_DCB_MSG_MSK_PCP; 261 } 262 263 static int nfp_nic_dcbnl_ieee_setets(struct net_device *dev, 264 struct ieee_ets *ets) 265 { 266 const u32 cmd = NFP_NET_CFG_MBOX_CMD_DCB_UPDATE; 267 struct nfp_net *nn = netdev_priv(dev); 268 struct nfp_app *app = nn->app; 269 struct nfp_dcb *dcb; 270 u32 update = 0; 271 bool change; 272 int err; 273 274 err = dcb_ets_check(dev, ets); 275 if (err) 276 return err; 277 278 dcb = get_dcb_priv(nn); 279 280 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 281 dcb->prio2tc[i] = ets->prio_tc[i]; 282 dcb->tc_tx_pct[i] = ets->tc_tx_bw[i]; 283 dcb->tc_tsa[i] = ets->tc_tsa[i]; 284 } 285 286 change = nfp_refresh_tc2idx(nn); 287 nfp_nic_fill_ets(nn); 288 dcb->ets_init = true; 289 if (change || !dcb->rate_init) { 290 err = update_dscp_maxrate(dev, &update); 291 if (err) { 292 nfp_warn(app->cpp, 293 "nfp dcbnl ieee setets ERROR:%d.", 294 err); 295 return err; 296 } 297 298 dcb->rate_init = true; 299 } 300 nfp_nic_set_enable(nn, NFP_DCB_ALL_QOS_ENABLE, &update); 301 nfp_nic_set_trust(nn, &update); 302 err = nfp_net_mbox_lock(nn, NFP_DCB_UPDATE_MSK_SZ); 303 if (err) 304 return err; 305 306 nn_writel(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL, 307 update | NFP_DCB_MSG_MSK_TSA | NFP_DCB_MSG_MSK_PCT | 308 NFP_DCB_MSG_MSK_PCP); 309 310 return nfp_net_mbox_reconfig_and_unlock(nn, cmd); 311 } 312 313 static int nfp_nic_dcbnl_ieee_getmaxrate(struct net_device *dev, 314 struct ieee_maxrate *maxrate) 315 { 316 struct nfp_net *nn = netdev_priv(dev); 317 struct nfp_dcb *dcb; 318 319 dcb = get_dcb_priv(nn); 320 321 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 322 maxrate->tc_maxrate[i] = dcb->tc_maxrate[i]; 323 324 return 0; 325 } 326 327 static int nfp_nic_dcbnl_ieee_setmaxrate(struct net_device *dev, 328 struct ieee_maxrate *maxrate) 329 { 330 const u32 cmd = NFP_NET_CFG_MBOX_CMD_DCB_UPDATE; 331 struct nfp_net *nn = netdev_priv(dev); 332 struct nfp_app *app = nn->app; 333 struct nfp_dcb *dcb; 334 u32 update = 0; 335 int err; 336 337 err = nfp_fill_maxrate(nn, maxrate->tc_maxrate); 338 if (err) { 339 nfp_warn(app->cpp, 340 "nfp dcbnl ieee setmaxrate ERROR:%d.", 341 err); 342 return err; 343 } 344 345 dcb = get_dcb_priv(nn); 346 347 dcb->rate_init = true; 348 nfp_nic_set_enable(nn, NFP_DCB_ALL_QOS_ENABLE, &update); 349 nfp_nic_set_trust(nn, &update); 350 nfp_nic_ets_init(nn, &update); 351 352 err = nfp_net_mbox_lock(nn, NFP_DCB_UPDATE_MSK_SZ); 353 if (err) 354 return err; 355 356 nn_writel(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL, 357 update | NFP_DCB_MSG_MSK_RATE); 358 359 return nfp_net_mbox_reconfig_and_unlock(nn, cmd); 360 } 361 362 static int nfp_nic_set_trust_status(struct nfp_net *nn, u8 status) 363 { 364 const u32 cmd = NFP_NET_CFG_MBOX_CMD_DCB_UPDATE; 365 struct nfp_dcb *dcb; 366 u32 update = 0; 367 int err; 368 369 dcb = get_dcb_priv(nn); 370 if (!dcb->rate_init) { 371 err = nfp_fill_maxrate(nn, dcb->tc_maxrate); 372 if (err) 373 return err; 374 375 update |= NFP_DCB_MSG_MSK_RATE; 376 dcb->rate_init = true; 377 } 378 379 err = nfp_net_mbox_lock(nn, NFP_DCB_UPDATE_MSK_SZ); 380 if (err) 381 return err; 382 383 nfp_nic_ets_init(nn, &update); 384 writeb(status, dcb->dcbcfg_tbl + dcb->cfg_offset + 385 NFP_DCB_DATA_OFF_TRUST); 386 nfp_nic_set_enable(nn, NFP_DCB_ALL_QOS_ENABLE, &update); 387 nn_writel(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL, 388 update | NFP_DCB_MSG_MSK_TRUST); 389 390 err = nfp_net_mbox_reconfig_and_unlock(nn, cmd); 391 if (err) 392 return err; 393 394 dcb->trust_status = status; 395 396 return 0; 397 } 398 399 static int nfp_nic_set_dscp2prio(struct nfp_net *nn, u8 dscp, u8 prio) 400 { 401 const u32 cmd = NFP_NET_CFG_MBOX_CMD_DCB_UPDATE; 402 struct nfp_dcb *dcb; 403 u8 idx, tc; 404 int err; 405 406 err = nfp_net_mbox_lock(nn, NFP_DCB_UPDATE_MSK_SZ); 407 if (err) 408 return err; 409 410 dcb = get_dcb_priv(nn); 411 412 tc = dcb->prio2tc[prio]; 413 idx = dcb->tc2idx[tc]; 414 415 writeb(idx, dcb->dcbcfg_tbl + dcb->cfg_offset + 416 NFP_DCB_DATA_OFF_DSCP2IDX + dscp); 417 418 nn_writel(nn, nn->tlv_caps.mbox_off + 419 NFP_NET_CFG_MBOX_SIMPLE_VAL, NFP_DCB_MSG_MSK_DSCP); 420 421 err = nfp_net_mbox_reconfig_and_unlock(nn, cmd); 422 if (err) 423 return err; 424 425 dcb->dscp2prio[dscp] = prio; 426 427 return 0; 428 } 429 430 static int nfp_nic_dcbnl_ieee_setapp(struct net_device *dev, 431 struct dcb_app *app) 432 { 433 struct nfp_net *nn = netdev_priv(dev); 434 struct dcb_app old_app; 435 struct nfp_dcb *dcb; 436 bool is_new; 437 int err; 438 439 if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP) 440 return -EINVAL; 441 442 dcb = get_dcb_priv(nn); 443 444 /* Save the old entry info */ 445 old_app.selector = IEEE_8021QAZ_APP_SEL_DSCP; 446 old_app.protocol = app->protocol; 447 old_app.priority = dcb->dscp2prio[app->protocol]; 448 449 /* Check trust status */ 450 if (!dcb->dscp_cnt) { 451 err = nfp_nic_set_trust_status(nn, NFP_DCB_TRUST_DSCP); 452 if (err) 453 return err; 454 } 455 456 /* Check if the new mapping is same as old or in init stage */ 457 if (app->priority != old_app.priority || app->priority == 0) { 458 err = nfp_nic_set_dscp2prio(nn, app->protocol, app->priority); 459 if (err) 460 return err; 461 } 462 463 /* Delete the old entry if exists */ 464 is_new = !!dcb_ieee_delapp(dev, &old_app); 465 466 /* Add new entry and update counter */ 467 err = dcb_ieee_setapp(dev, app); 468 if (err) 469 return err; 470 471 if (is_new) 472 dcb->dscp_cnt++; 473 474 return 0; 475 } 476 477 static int nfp_nic_dcbnl_ieee_delapp(struct net_device *dev, 478 struct dcb_app *app) 479 { 480 struct nfp_net *nn = netdev_priv(dev); 481 struct nfp_dcb *dcb; 482 int err; 483 484 if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP) 485 return -EINVAL; 486 487 dcb = get_dcb_priv(nn); 488 489 /* Check if the dcb_app param match fw */ 490 if (app->priority != dcb->dscp2prio[app->protocol]) 491 return -ENOENT; 492 493 /* Set fw dscp mapping to 0 */ 494 err = nfp_nic_set_dscp2prio(nn, app->protocol, 0); 495 if (err) 496 return err; 497 498 /* Delete app from dcb list */ 499 err = dcb_ieee_delapp(dev, app); 500 if (err) 501 return err; 502 503 /* Decrease dscp counter */ 504 dcb->dscp_cnt--; 505 506 /* If no dscp mapping is configured, trust pcp */ 507 if (dcb->dscp_cnt == 0) 508 return nfp_nic_set_trust_status(nn, NFP_DCB_TRUST_PCP); 509 510 return 0; 511 } 512 513 static const struct dcbnl_rtnl_ops nfp_nic_dcbnl_ops = { 514 /* ieee 802.1Qaz std */ 515 .ieee_getets = nfp_nic_dcbnl_ieee_getets, 516 .ieee_setets = nfp_nic_dcbnl_ieee_setets, 517 .ieee_getmaxrate = nfp_nic_dcbnl_ieee_getmaxrate, 518 .ieee_setmaxrate = nfp_nic_dcbnl_ieee_setmaxrate, 519 .ieee_setapp = nfp_nic_dcbnl_ieee_setapp, 520 .ieee_delapp = nfp_nic_dcbnl_ieee_delapp, 521 }; 522 523 int nfp_nic_dcb_init(struct nfp_net *nn) 524 { 525 struct nfp_app *app = nn->app; 526 struct nfp_dcb *dcb; 527 int err; 528 529 dcb = get_dcb_priv(nn); 530 dcb->cfg_offset = NFP_DCB_CFG_STRIDE * nn->id; 531 dcb->dcbcfg_tbl = nfp_pf_map_rtsym(app->pf, "net.dcbcfg_tbl", 532 "_abi_dcb_cfg", 533 dcb->cfg_offset, &dcb->dcbcfg_tbl_area); 534 if (IS_ERR(dcb->dcbcfg_tbl)) { 535 if (PTR_ERR(dcb->dcbcfg_tbl) != -ENOENT) { 536 err = PTR_ERR(dcb->dcbcfg_tbl); 537 dcb->dcbcfg_tbl = NULL; 538 nfp_err(app->cpp, 539 "Failed to map dcbcfg_tbl area, min_size %u.\n", 540 dcb->cfg_offset); 541 return err; 542 } 543 dcb->dcbcfg_tbl = NULL; 544 } 545 546 if (dcb->dcbcfg_tbl) { 547 for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 548 dcb->prio2tc[i] = i; 549 dcb->tc2idx[i] = i; 550 dcb->tc_tx_pct[i] = 0; 551 dcb->tc_maxrate[i] = 0; 552 dcb->tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR; 553 } 554 dcb->trust_status = NFP_DCB_TRUST_INVALID; 555 dcb->rate_init = false; 556 dcb->ets_init = false; 557 558 nn->dp.netdev->dcbnl_ops = &nfp_nic_dcbnl_ops; 559 } 560 561 return 0; 562 } 563 564 void nfp_nic_dcb_clean(struct nfp_net *nn) 565 { 566 struct nfp_dcb *dcb; 567 568 dcb = get_dcb_priv(nn); 569 if (dcb->dcbcfg_tbl_area) 570 nfp_cpp_area_release_free(dcb->dcbcfg_tbl_area); 571 } 572