1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017-2018 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <inttypes.h> 7 #include <stdbool.h> 8 #include <unistd.h> 9 10 #include <rte_dev.h> 11 #include <rte_ethdev_driver.h> 12 #include <rte_malloc.h> 13 #include <rte_cycles.h> 14 #include <rte_byteorder.h> 15 16 #include "bnxt.h" 17 #include "bnxt_filter.h" 18 #include "bnxt_hwrm.h" 19 #include "bnxt_vnic.h" 20 #include "rte_pmd_bnxt.h" 21 #include "hsi_struct_def_dpdk.h" 22 23 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg) 24 { 25 struct rte_pmd_bnxt_mb_event_param ret_param; 26 27 ret_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED; 28 ret_param.vf_id = vf_id; 29 ret_param.msg = msg; 30 31 _rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX, 32 &ret_param); 33 34 /* Default to approve */ 35 if (ret_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED) 36 ret_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK; 37 38 return ret_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? 39 true : false; 40 } 41 42 int rte_pmd_bnxt_set_tx_loopback(uint16_t port, uint8_t on) 43 { 44 struct rte_eth_dev *eth_dev; 45 struct bnxt *bp; 46 int rc; 47 48 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 49 50 if (on > 1) 51 return -EINVAL; 52 53 eth_dev = &rte_eth_devices[port]; 54 if (!is_bnxt_supported(eth_dev)) 55 return -ENOTSUP; 56 57 bp = eth_dev->data->dev_private; 58 59 if (!BNXT_PF(bp)) { 60 PMD_DRV_LOG(ERR, 61 "Attempt to set Tx loopback on non-PF port %d!\n", 62 port); 63 return -ENOTSUP; 64 } 65 66 if (on) 67 bp->pf.evb_mode = BNXT_EVB_MODE_VEB; 68 else 69 bp->pf.evb_mode = BNXT_EVB_MODE_VEPA; 70 71 rc = bnxt_hwrm_pf_evb_mode(bp); 72 73 return rc; 74 } 75 76 static void 77 rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr) 78 { 79 uint8_t *on = onptr; 80 vnic->bd_stall = !(*on); 81 } 82 83 int rte_pmd_bnxt_set_all_queues_drop_en(uint16_t port, uint8_t on) 84 { 85 struct rte_eth_dev *eth_dev; 86 struct bnxt *bp; 87 uint32_t i; 88 int rc = -EINVAL; 89 90 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 91 92 if (on > 1) 93 return -EINVAL; 94 95 eth_dev = &rte_eth_devices[port]; 96 if (!is_bnxt_supported(eth_dev)) 97 return -ENOTSUP; 98 99 bp = eth_dev->data->dev_private; 100 101 if (!BNXT_PF(bp)) { 102 PMD_DRV_LOG(ERR, 103 "Attempt to set all queues drop on non-PF port!\n"); 104 return -ENOTSUP; 105 } 106 107 if (bp->vnic_info == NULL) 108 return -ENODEV; 109 110 /* Stall PF */ 111 for (i = 0; i < bp->nr_vnics; i++) { 112 bp->vnic_info[i].bd_stall = !on; 113 rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]); 114 if (rc) { 115 PMD_DRV_LOG(ERR, "Failed to update PF VNIC %d.\n", i); 116 return rc; 117 } 118 } 119 120 /* Stall all active VFs */ 121 for (i = 0; i < bp->pf.active_vfs; i++) { 122 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i, 123 rte_pmd_bnxt_set_all_queues_drop_en_cb, &on, 124 bnxt_hwrm_vnic_cfg); 125 if (rc) { 126 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", i); 127 break; 128 } 129 } 130 131 return rc; 132 } 133 134 int rte_pmd_bnxt_set_vf_mac_addr(uint16_t port, uint16_t vf, 135 struct rte_ether_addr *mac_addr) 136 { 137 struct rte_eth_dev *dev; 138 struct rte_eth_dev_info dev_info; 139 struct bnxt *bp; 140 int rc; 141 142 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 143 144 dev = &rte_eth_devices[port]; 145 if (!is_bnxt_supported(dev)) 146 return -ENOTSUP; 147 148 rc = rte_eth_dev_info_get(port, &dev_info); 149 if (rc != 0) { 150 PMD_DRV_LOG(ERR, 151 "Error during getting device (port %u) info: %s\n", 152 port, strerror(-rc)); 153 154 return rc; 155 } 156 157 bp = dev->data->dev_private; 158 159 if (vf >= dev_info.max_vfs || mac_addr == NULL) 160 return -EINVAL; 161 162 if (!BNXT_PF(bp)) { 163 PMD_DRV_LOG(ERR, 164 "Attempt to set VF %d mac address on non-PF port %d!\n", 165 vf, port); 166 return -ENOTSUP; 167 } 168 169 rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr); 170 171 return rc; 172 } 173 174 int rte_pmd_bnxt_set_vf_rate_limit(uint16_t port, uint16_t vf, 175 uint16_t tx_rate, uint64_t q_msk) 176 { 177 struct rte_eth_dev *eth_dev; 178 struct rte_eth_dev_info dev_info; 179 struct bnxt *bp; 180 uint16_t tot_rate = 0; 181 uint64_t idx; 182 int rc; 183 184 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 185 186 eth_dev = &rte_eth_devices[port]; 187 if (!is_bnxt_supported(eth_dev)) 188 return -ENOTSUP; 189 190 rc = rte_eth_dev_info_get(port, &dev_info); 191 if (rc != 0) { 192 PMD_DRV_LOG(ERR, 193 "Error during getting device (port %u) info: %s\n", 194 port, strerror(-rc)); 195 196 return rc; 197 } 198 bp = eth_dev->data->dev_private; 199 200 if (!bp->pf.active_vfs) 201 return -EINVAL; 202 203 if (vf >= bp->pf.max_vfs) 204 return -EINVAL; 205 206 /* Add up the per queue BW and configure MAX BW of the VF */ 207 for (idx = 0; idx < 64; idx++) { 208 if ((1ULL << idx) & q_msk) 209 tot_rate += tx_rate; 210 } 211 212 /* Requested BW can't be greater than link speed */ 213 if (tot_rate > eth_dev->data->dev_link.link_speed) { 214 PMD_DRV_LOG(ERR, "Rate > Link speed. Set to %d\n", tot_rate); 215 return -EINVAL; 216 } 217 218 /* Requested BW already configured */ 219 if (tot_rate == bp->pf.vf_info[vf].max_tx_rate) 220 return 0; 221 222 rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate, 223 HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW); 224 225 if (!rc) 226 bp->pf.vf_info[vf].max_tx_rate = tot_rate; 227 228 return rc; 229 } 230 231 int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf, uint8_t on) 232 { 233 struct rte_eth_dev_info dev_info; 234 struct rte_eth_dev *dev; 235 uint32_t func_flags; 236 struct bnxt *bp; 237 int rc; 238 239 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 240 241 if (on > 1) 242 return -EINVAL; 243 244 dev = &rte_eth_devices[port]; 245 if (!is_bnxt_supported(dev)) 246 return -ENOTSUP; 247 248 rc = rte_eth_dev_info_get(port, &dev_info); 249 if (rc != 0) { 250 PMD_DRV_LOG(ERR, 251 "Error during getting device (port %u) info: %s\n", 252 port, strerror(-rc)); 253 254 return rc; 255 } 256 bp = dev->data->dev_private; 257 258 if (!BNXT_PF(bp)) { 259 PMD_DRV_LOG(ERR, 260 "Attempt to set mac spoof on non-PF port %d!\n", port); 261 return -EINVAL; 262 } 263 264 if (vf >= dev_info.max_vfs) 265 return -EINVAL; 266 267 /* Prev setting same as new setting. */ 268 if (on == bp->pf.vf_info[vf].mac_spoof_en) 269 return 0; 270 271 func_flags = bp->pf.vf_info[vf].func_cfg_flags; 272 func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE | 273 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE); 274 275 if (on) 276 func_flags |= 277 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; 278 else 279 func_flags |= 280 HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; 281 282 rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags); 283 if (!rc) { 284 bp->pf.vf_info[vf].mac_spoof_en = on; 285 bp->pf.vf_info[vf].func_cfg_flags = func_flags; 286 } 287 288 return rc; 289 } 290 291 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf, uint8_t on) 292 { 293 struct rte_eth_dev_info dev_info; 294 struct rte_eth_dev *dev; 295 struct bnxt *bp; 296 int rc; 297 298 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 299 300 if (on > 1) 301 return -EINVAL; 302 303 dev = &rte_eth_devices[port]; 304 if (!is_bnxt_supported(dev)) 305 return -ENOTSUP; 306 307 rc = rte_eth_dev_info_get(port, &dev_info); 308 if (rc != 0) { 309 PMD_DRV_LOG(ERR, 310 "Error during getting device (port %u) info: %s\n", 311 port, strerror(-rc)); 312 313 return rc; 314 } 315 bp = dev->data->dev_private; 316 317 if (!BNXT_PF(bp)) { 318 PMD_DRV_LOG(ERR, 319 "Attempt to set VLAN spoof on non-PF port %d!\n", port); 320 return -EINVAL; 321 } 322 323 if (vf >= dev_info.max_vfs) 324 return -EINVAL; 325 326 rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on); 327 if (!rc) { 328 bp->pf.vf_info[vf].vlan_spoof_en = on; 329 if (on) { 330 if (bnxt_hwrm_cfa_vlan_antispoof_cfg(bp, 331 bp->pf.first_vf_id + vf, 332 bp->pf.vf_info[vf].vlan_count, 333 bp->pf.vf_info[vf].vlan_as_table)) 334 rc = -1; 335 } 336 } else { 337 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf); 338 } 339 340 return rc; 341 } 342 343 static void 344 rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr) 345 { 346 uint8_t *on = onptr; 347 vnic->vlan_strip = *on; 348 } 349 350 int 351 rte_pmd_bnxt_set_vf_vlan_stripq(uint16_t port, uint16_t vf, uint8_t on) 352 { 353 struct rte_eth_dev *dev; 354 struct rte_eth_dev_info dev_info; 355 struct bnxt *bp; 356 int rc; 357 358 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 359 360 dev = &rte_eth_devices[port]; 361 if (!is_bnxt_supported(dev)) 362 return -ENOTSUP; 363 364 rc = rte_eth_dev_info_get(port, &dev_info); 365 if (rc != 0) { 366 PMD_DRV_LOG(ERR, 367 "Error during getting device (port %u) info: %s\n", 368 port, strerror(-rc)); 369 370 return rc; 371 } 372 bp = dev->data->dev_private; 373 374 if (vf >= dev_info.max_vfs) 375 return -EINVAL; 376 377 if (!BNXT_PF(bp)) { 378 PMD_DRV_LOG(ERR, 379 "Attempt to set VF %d stripq on non-PF port %d!\n", 380 vf, port); 381 return -ENOTSUP; 382 } 383 384 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, 385 rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on, 386 bnxt_hwrm_vnic_cfg); 387 if (rc) 388 PMD_DRV_LOG(ERR, "Failed to update VF VNIC %d.\n", vf); 389 390 return rc; 391 } 392 393 int rte_pmd_bnxt_set_vf_rxmode(uint16_t port, uint16_t vf, 394 uint16_t rx_mask, uint8_t on) 395 { 396 struct rte_eth_dev *dev; 397 struct rte_eth_dev_info dev_info; 398 uint16_t flag = 0; 399 struct bnxt *bp; 400 int rc; 401 402 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 403 404 dev = &rte_eth_devices[port]; 405 if (!is_bnxt_supported(dev)) 406 return -ENOTSUP; 407 408 rc = rte_eth_dev_info_get(port, &dev_info); 409 if (rc != 0) { 410 PMD_DRV_LOG(ERR, 411 "Error during getting device (port %u) info: %s\n", 412 port, strerror(-rc)); 413 414 return rc; 415 } 416 bp = dev->data->dev_private; 417 418 if (!bp->pf.vf_info) 419 return -EINVAL; 420 421 if (vf >= bp->pdev->max_vfs) 422 return -EINVAL; 423 424 if (rx_mask & ETH_VMDQ_ACCEPT_UNTAG) { 425 PMD_DRV_LOG(ERR, "Currently cannot toggle this setting\n"); 426 return -ENOTSUP; 427 } 428 429 /* Is this really the correct mapping? VFd seems to think it is. */ 430 if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC) 431 flag |= BNXT_VNIC_INFO_PROMISC; 432 433 if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST) 434 flag |= BNXT_VNIC_INFO_BCAST; 435 if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST) 436 flag |= BNXT_VNIC_INFO_ALLMULTI | BNXT_VNIC_INFO_MCAST; 437 438 if (on) 439 bp->pf.vf_info[vf].l2_rx_mask |= flag; 440 else 441 bp->pf.vf_info[vf].l2_rx_mask &= ~flag; 442 443 rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, 444 vf_vnic_set_rxmask_cb, 445 &bp->pf.vf_info[vf].l2_rx_mask, 446 bnxt_set_rx_mask_no_vlan); 447 if (rc) 448 PMD_DRV_LOG(ERR, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n"); 449 450 return rc; 451 } 452 453 static int bnxt_set_vf_table(struct bnxt *bp, uint16_t vf) 454 { 455 int rc = 0; 456 int dflt_vnic; 457 struct bnxt_vnic_info vnic; 458 459 if (!BNXT_PF(bp)) { 460 PMD_DRV_LOG(ERR, 461 "Attempt to set VLAN table on non-PF port!\n"); 462 return -EINVAL; 463 } 464 465 if (vf >= bp->pdev->max_vfs) 466 return -EINVAL; 467 468 dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf); 469 if (dflt_vnic < 0) { 470 /* This simply indicates there's no driver loaded. 471 * This is not an error. 472 */ 473 PMD_DRV_LOG(ERR, "Unable to get default VNIC for VF %d\n", vf); 474 } else { 475 memset(&vnic, 0, sizeof(vnic)); 476 vnic.fw_vnic_id = dflt_vnic; 477 if (bnxt_hwrm_vnic_qcfg(bp, &vnic, 478 bp->pf.first_vf_id + vf) == 0) { 479 if (bnxt_hwrm_cfa_l2_set_rx_mask(bp, &vnic, 480 bp->pf.vf_info[vf].vlan_count, 481 bp->pf.vf_info[vf].vlan_table)) 482 rc = -1; 483 } else { 484 rc = -1; 485 } 486 } 487 488 return rc; 489 } 490 491 int rte_pmd_bnxt_set_vf_vlan_filter(uint16_t port, uint16_t vlan, 492 uint64_t vf_mask, uint8_t vlan_on) 493 { 494 struct bnxt_vlan_table_entry *ve; 495 struct bnxt_vlan_antispoof_table_entry *vase; 496 struct rte_eth_dev *dev; 497 struct bnxt *bp; 498 uint16_t cnt; 499 int rc = 0; 500 int i, j; 501 502 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 503 504 dev = &rte_eth_devices[port]; 505 if (!is_bnxt_supported(dev)) 506 return -ENOTSUP; 507 508 bp = dev->data->dev_private; 509 if (!bp->pf.vf_info) 510 return -EINVAL; 511 512 for (i = 0; vf_mask; i++, vf_mask >>= 1) { 513 cnt = bp->pf.vf_info[i].vlan_count; 514 if ((vf_mask & 1) == 0) 515 continue; 516 517 if (bp->pf.vf_info[i].vlan_table == NULL) { 518 rc = -1; 519 continue; 520 } 521 if (bp->pf.vf_info[i].vlan_as_table == NULL) { 522 rc = -1; 523 continue; 524 } 525 if (vlan_on) { 526 /* First, search for a duplicate... */ 527 for (j = 0; j < cnt; j++) { 528 if (rte_be_to_cpu_16( 529 bp->pf.vf_info[i].vlan_table[j].vid) == vlan) 530 break; 531 } 532 if (j == cnt) { 533 /* Now check that there's space */ 534 if (cnt == getpagesize() / sizeof(struct 535 bnxt_vlan_antispoof_table_entry)) { 536 PMD_DRV_LOG(ERR, 537 "VLAN anti-spoof table is full\n"); 538 PMD_DRV_LOG(ERR, 539 "VF %d cannot add VLAN %u\n", 540 i, vlan); 541 rc = -1; 542 continue; 543 } 544 545 /* cnt is one less than vlan_count */ 546 cnt = bp->pf.vf_info[i].vlan_count++; 547 /* 548 * And finally, add to the 549 * end of the table 550 */ 551 vase = &bp->pf.vf_info[i].vlan_as_table[cnt]; 552 // TODO: Hardcoded TPID 553 vase->tpid = rte_cpu_to_be_16(0x8100); 554 vase->vid = rte_cpu_to_be_16(vlan); 555 vase->mask = rte_cpu_to_be_16(0xfff); 556 ve = &bp->pf.vf_info[i].vlan_table[cnt]; 557 /* TODO: Hardcoded TPID */ 558 ve->tpid = rte_cpu_to_be_16(0x8100); 559 ve->vid = rte_cpu_to_be_16(vlan); 560 } 561 } else { 562 for (j = 0; j < cnt; j++) { 563 if (rte_be_to_cpu_16( 564 bp->pf.vf_info[i].vlan_table[j].vid) != vlan) 565 continue; 566 memmove(&bp->pf.vf_info[i].vlan_table[j], 567 &bp->pf.vf_info[i].vlan_table[j + 1], 568 getpagesize() - ((j + 1) * 569 sizeof(struct bnxt_vlan_table_entry))); 570 memmove(&bp->pf.vf_info[i].vlan_as_table[j], 571 &bp->pf.vf_info[i].vlan_as_table[j + 1], 572 getpagesize() - ((j + 1) * sizeof(struct 573 bnxt_vlan_antispoof_table_entry))); 574 j--; 575 cnt = --bp->pf.vf_info[i].vlan_count; 576 } 577 } 578 bnxt_set_vf_table(bp, i); 579 } 580 581 return rc; 582 } 583 584 int rte_pmd_bnxt_get_vf_stats(uint16_t port, 585 uint16_t vf_id, 586 struct rte_eth_stats *stats) 587 { 588 struct rte_eth_dev *dev; 589 struct rte_eth_dev_info dev_info; 590 struct bnxt *bp; 591 int rc; 592 593 dev = &rte_eth_devices[port]; 594 if (!is_bnxt_supported(dev)) 595 return -ENOTSUP; 596 597 rc = rte_eth_dev_info_get(port, &dev_info); 598 if (rc != 0) { 599 PMD_DRV_LOG(ERR, 600 "Error during getting device (port %u) info: %s\n", 601 port, strerror(-rc)); 602 603 return rc; 604 } 605 bp = dev->data->dev_private; 606 607 if (vf_id >= dev_info.max_vfs) 608 return -EINVAL; 609 610 if (!BNXT_PF(bp)) { 611 PMD_DRV_LOG(ERR, 612 "Attempt to get VF %d stats on non-PF port %d!\n", 613 vf_id, port); 614 return -ENOTSUP; 615 } 616 617 return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats); 618 } 619 620 int rte_pmd_bnxt_reset_vf_stats(uint16_t port, 621 uint16_t vf_id) 622 { 623 struct rte_eth_dev *dev; 624 struct rte_eth_dev_info dev_info; 625 struct bnxt *bp; 626 int rc; 627 628 dev = &rte_eth_devices[port]; 629 if (!is_bnxt_supported(dev)) 630 return -ENOTSUP; 631 632 rc = rte_eth_dev_info_get(port, &dev_info); 633 if (rc != 0) { 634 PMD_DRV_LOG(ERR, 635 "Error during getting device (port %u) info: %s\n", 636 port, strerror(-rc)); 637 638 return rc; 639 } 640 bp = dev->data->dev_private; 641 642 if (vf_id >= dev_info.max_vfs) 643 return -EINVAL; 644 645 if (!BNXT_PF(bp)) { 646 PMD_DRV_LOG(ERR, 647 "Attempt to reset VF %d stats on non-PF port %d!\n", 648 vf_id, port); 649 return -ENOTSUP; 650 } 651 652 return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id); 653 } 654 655 int rte_pmd_bnxt_get_vf_rx_status(uint16_t port, uint16_t vf_id) 656 { 657 struct rte_eth_dev *dev; 658 struct rte_eth_dev_info dev_info; 659 struct bnxt *bp; 660 int rc; 661 662 dev = &rte_eth_devices[port]; 663 if (!is_bnxt_supported(dev)) 664 return -ENOTSUP; 665 666 rc = rte_eth_dev_info_get(port, &dev_info); 667 if (rc != 0) { 668 PMD_DRV_LOG(ERR, 669 "Error during getting device (port %u) info: %s\n", 670 port, strerror(-rc)); 671 672 return rc; 673 } 674 bp = dev->data->dev_private; 675 676 if (vf_id >= dev_info.max_vfs) 677 return -EINVAL; 678 679 if (!BNXT_PF(bp)) { 680 PMD_DRV_LOG(ERR, 681 "Attempt to query VF %d RX stats on non-PF port %d!\n", 682 vf_id, port); 683 return -ENOTSUP; 684 } 685 686 return bnxt_vf_vnic_count(bp, vf_id); 687 } 688 689 int rte_pmd_bnxt_get_vf_tx_drop_count(uint16_t port, uint16_t vf_id, 690 uint64_t *count) 691 { 692 struct rte_eth_dev *dev; 693 struct rte_eth_dev_info dev_info; 694 struct bnxt *bp; 695 int rc; 696 697 dev = &rte_eth_devices[port]; 698 if (!is_bnxt_supported(dev)) 699 return -ENOTSUP; 700 701 rc = rte_eth_dev_info_get(port, &dev_info); 702 if (rc != 0) { 703 PMD_DRV_LOG(ERR, 704 "Error during getting device (port %u) info: %s\n", 705 port, strerror(-rc)); 706 707 return rc; 708 } 709 bp = dev->data->dev_private; 710 711 if (vf_id >= dev_info.max_vfs) 712 return -EINVAL; 713 714 if (!BNXT_PF(bp)) { 715 PMD_DRV_LOG(ERR, 716 "Attempt to query VF %d TX drops on non-PF port %d!\n", 717 vf_id, port); 718 return -ENOTSUP; 719 } 720 721 return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id, 722 count); 723 } 724 725 int rte_pmd_bnxt_mac_addr_add(uint16_t port, struct rte_ether_addr *addr, 726 uint32_t vf_id) 727 { 728 struct rte_eth_dev *dev; 729 struct rte_eth_dev_info dev_info; 730 struct bnxt *bp; 731 struct bnxt_filter_info *filter; 732 struct bnxt_vnic_info vnic; 733 struct rte_ether_addr dflt_mac; 734 int rc; 735 736 dev = &rte_eth_devices[port]; 737 if (!is_bnxt_supported(dev)) 738 return -ENOTSUP; 739 740 rc = rte_eth_dev_info_get(port, &dev_info); 741 if (rc != 0) { 742 PMD_DRV_LOG(ERR, 743 "Error during getting device (port %u) info: %s\n", 744 port, strerror(-rc)); 745 746 return rc; 747 } 748 bp = dev->data->dev_private; 749 750 if (vf_id >= dev_info.max_vfs) 751 return -EINVAL; 752 753 if (!BNXT_PF(bp)) { 754 PMD_DRV_LOG(ERR, 755 "Attempt to config VF %d MAC on non-PF port %d!\n", 756 vf_id, port); 757 return -ENOTSUP; 758 } 759 760 /* If the VF currently uses a random MAC, update default to this one */ 761 if (bp->pf.vf_info[vf_id].random_mac) { 762 if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0) 763 bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr); 764 } 765 766 /* query the default VNIC id used by the function */ 767 rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id); 768 if (rc < 0) 769 goto exit; 770 771 memset(&vnic, 0, sizeof(struct bnxt_vnic_info)); 772 vnic.fw_vnic_id = rte_le_to_cpu_16(rc); 773 rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id); 774 if (rc < 0) 775 goto exit; 776 777 STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) { 778 if (filter->flags == 779 HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX && 780 filter->enables == 781 (HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR | 782 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK) && 783 memcmp(addr, filter->l2_addr, RTE_ETHER_ADDR_LEN) == 0) { 784 bnxt_hwrm_clear_l2_filter(bp, filter); 785 break; 786 } 787 } 788 789 if (filter == NULL) 790 filter = bnxt_alloc_vf_filter(bp, vf_id); 791 792 filter->fw_l2_filter_id = UINT64_MAX; 793 filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX; 794 filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR | 795 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK; 796 memcpy(filter->l2_addr, addr, RTE_ETHER_ADDR_LEN); 797 memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN); 798 799 /* Do not add a filter for the default MAC */ 800 if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) || 801 memcmp(filter->l2_addr, dflt_mac.addr_bytes, RTE_ETHER_ADDR_LEN)) 802 rc = bnxt_hwrm_set_l2_filter(bp, vnic.fw_vnic_id, filter); 803 804 exit: 805 return rc; 806 } 807 808 int 809 rte_pmd_bnxt_set_vf_vlan_insert(uint16_t port, uint16_t vf, 810 uint16_t vlan_id) 811 { 812 struct rte_eth_dev *dev; 813 struct rte_eth_dev_info dev_info; 814 struct bnxt *bp; 815 int rc; 816 817 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 818 819 dev = &rte_eth_devices[port]; 820 if (!is_bnxt_supported(dev)) 821 return -ENOTSUP; 822 823 rc = rte_eth_dev_info_get(port, &dev_info); 824 if (rc != 0) { 825 PMD_DRV_LOG(ERR, 826 "Error during getting device (port %u) info: %s\n", 827 port, strerror(-rc)); 828 829 return rc; 830 } 831 bp = dev->data->dev_private; 832 833 if (vf >= dev_info.max_vfs) 834 return -EINVAL; 835 836 if (!BNXT_PF(bp)) { 837 PMD_DRV_LOG(ERR, 838 "Attempt to set VF %d vlan insert on non-PF port %d!\n", 839 vf, port); 840 return -ENOTSUP; 841 } 842 843 bp->pf.vf_info[vf].dflt_vlan = vlan_id; 844 if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) == 845 bp->pf.vf_info[vf].dflt_vlan) 846 return 0; 847 848 rc = bnxt_hwrm_set_vf_vlan(bp, vf); 849 850 return rc; 851 } 852 853 int rte_pmd_bnxt_set_vf_persist_stats(uint16_t port, uint16_t vf, uint8_t on) 854 { 855 struct rte_eth_dev_info dev_info; 856 struct rte_eth_dev *dev; 857 uint32_t func_flags; 858 struct bnxt *bp; 859 int rc; 860 861 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); 862 863 if (on > 1) 864 return -EINVAL; 865 866 dev = &rte_eth_devices[port]; 867 rc = rte_eth_dev_info_get(port, &dev_info); 868 if (rc != 0) { 869 PMD_DRV_LOG(ERR, 870 "Error during getting device (port %u) info: %s\n", 871 port, strerror(-rc)); 872 873 return rc; 874 } 875 bp = dev->data->dev_private; 876 877 if (!BNXT_PF(bp)) { 878 PMD_DRV_LOG(ERR, 879 "Attempt to set persist stats on non-PF port %d!\n", 880 port); 881 return -EINVAL; 882 } 883 884 if (vf >= dev_info.max_vfs) 885 return -EINVAL; 886 887 /* Prev setting same as new setting. */ 888 if (on == bp->pf.vf_info[vf].persist_stats) 889 return 0; 890 891 func_flags = bp->pf.vf_info[vf].func_cfg_flags; 892 893 if (on) 894 func_flags |= 895 HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC; 896 else 897 func_flags &= 898 ~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC; 899 900 rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags); 901 if (!rc) { 902 bp->pf.vf_info[vf].persist_stats = on; 903 bp->pf.vf_info[vf].func_cfg_flags = func_flags; 904 } 905 906 return rc; 907 } 908