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