1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 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 37 #include <rte_dev.h> 38 #include <rte_ethdev.h> 39 #include <rte_malloc.h> 40 #include <rte_cycles.h> 41 42 #include "bnxt.h" 43 #include "bnxt_cpr.h" 44 #include "bnxt_filter.h" 45 #include "bnxt_hwrm.h" 46 #include "bnxt_ring.h" 47 #include "bnxt_rxq.h" 48 #include "bnxt_rxr.h" 49 #include "bnxt_stats.h" 50 #include "bnxt_txq.h" 51 #include "bnxt_txr.h" 52 #include "bnxt_vnic.h" 53 #include "hsi_struct_def_dpdk.h" 54 55 #define DRV_MODULE_NAME "bnxt" 56 static const char bnxt_version[] = 57 "Broadcom Cumulus driver " DRV_MODULE_NAME "\n"; 58 59 #define PCI_VENDOR_ID_BROADCOM 0x14E4 60 61 #define BROADCOM_DEV_ID_57301 0x16c8 62 #define BROADCOM_DEV_ID_57302 0x16c9 63 #define BROADCOM_DEV_ID_57304_PF 0x16ca 64 #define BROADCOM_DEV_ID_57304_VF 0x16cb 65 #define BROADCOM_DEV_ID_57417_MF 0x16cc 66 #define BROADCOM_DEV_ID_NS2 0x16cd 67 #define BROADCOM_DEV_ID_57311 0x16ce 68 #define BROADCOM_DEV_ID_57312 0x16cf 69 #define BROADCOM_DEV_ID_57402 0x16d0 70 #define BROADCOM_DEV_ID_57404 0x16d1 71 #define BROADCOM_DEV_ID_57406_PF 0x16d2 72 #define BROADCOM_DEV_ID_57406_VF 0x16d3 73 #define BROADCOM_DEV_ID_57402_MF 0x16d4 74 #define BROADCOM_DEV_ID_57407_RJ45 0x16d5 75 #define BROADCOM_DEV_ID_57412 0x16d6 76 #define BROADCOM_DEV_ID_57414 0x16d7 77 #define BROADCOM_DEV_ID_57416_RJ45 0x16d8 78 #define BROADCOM_DEV_ID_57417_RJ45 0x16d9 79 #define BROADCOM_DEV_ID_5741X_VF 0x16dc 80 #define BROADCOM_DEV_ID_57412_MF 0x16de 81 #define BROADCOM_DEV_ID_57314 0x16df 82 #define BROADCOM_DEV_ID_57317_RJ45 0x16e0 83 #define BROADCOM_DEV_ID_5731X_VF 0x16e1 84 #define BROADCOM_DEV_ID_57417_SFP 0x16e2 85 #define BROADCOM_DEV_ID_57416_SFP 0x16e3 86 #define BROADCOM_DEV_ID_57317_SFP 0x16e4 87 #define BROADCOM_DEV_ID_57404_MF 0x16e7 88 #define BROADCOM_DEV_ID_57406_MF 0x16e8 89 #define BROADCOM_DEV_ID_57407_SFP 0x16e9 90 #define BROADCOM_DEV_ID_57407_MF 0x16ea 91 #define BROADCOM_DEV_ID_57414_MF 0x16ec 92 #define BROADCOM_DEV_ID_57416_MF 0x16ee 93 94 static struct rte_pci_id bnxt_pci_id_map[] = { 95 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) }, 96 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302) }, 97 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF) }, 98 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) }, 99 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) }, 100 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402) }, 101 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404) }, 102 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF) }, 103 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) }, 104 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402_MF) }, 105 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57314) }, 106 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_RJ45) }, 107 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404_MF) }, 108 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF) }, 109 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_SFP) }, 110 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) }, 111 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) }, 112 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57311) }, 113 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57312) }, 114 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) }, 115 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) }, 116 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) }, 117 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) }, 118 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) }, 119 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) }, 120 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) }, 121 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) }, 122 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) }, 123 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) }, 124 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) }, 125 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) }, 126 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) }, 127 { .vendor_id = 0, /* sentinel */ }, 128 }; 129 130 #define BNXT_ETH_RSS_SUPPORT ( \ 131 ETH_RSS_IPV4 | \ 132 ETH_RSS_NONFRAG_IPV4_TCP | \ 133 ETH_RSS_NONFRAG_IPV4_UDP | \ 134 ETH_RSS_IPV6 | \ 135 ETH_RSS_NONFRAG_IPV6_TCP | \ 136 ETH_RSS_NONFRAG_IPV6_UDP) 137 138 /***********************/ 139 140 /* 141 * High level utility functions 142 */ 143 144 static void bnxt_free_mem(struct bnxt *bp) 145 { 146 bnxt_free_filter_mem(bp); 147 bnxt_free_vnic_attributes(bp); 148 bnxt_free_vnic_mem(bp); 149 150 bnxt_free_stats(bp); 151 bnxt_free_tx_rings(bp); 152 bnxt_free_rx_rings(bp); 153 bnxt_free_def_cp_ring(bp); 154 } 155 156 static int bnxt_alloc_mem(struct bnxt *bp) 157 { 158 int rc; 159 160 /* Default completion ring */ 161 rc = bnxt_init_def_ring_struct(bp, SOCKET_ID_ANY); 162 if (rc) 163 goto alloc_mem_err; 164 165 rc = bnxt_alloc_rings(bp, 0, NULL, NULL, 166 bp->def_cp_ring, "def_cp"); 167 if (rc) 168 goto alloc_mem_err; 169 170 rc = bnxt_alloc_vnic_mem(bp); 171 if (rc) 172 goto alloc_mem_err; 173 174 rc = bnxt_alloc_vnic_attributes(bp); 175 if (rc) 176 goto alloc_mem_err; 177 178 rc = bnxt_alloc_filter_mem(bp); 179 if (rc) 180 goto alloc_mem_err; 181 182 return 0; 183 184 alloc_mem_err: 185 bnxt_free_mem(bp); 186 return rc; 187 } 188 189 static int bnxt_init_chip(struct bnxt *bp) 190 { 191 unsigned int i, rss_idx, fw_idx; 192 int rc; 193 194 rc = bnxt_alloc_all_hwrm_stat_ctxs(bp); 195 if (rc) { 196 RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc); 197 goto err_out; 198 } 199 200 rc = bnxt_alloc_hwrm_rings(bp); 201 if (rc) { 202 RTE_LOG(ERR, PMD, "HWRM ring alloc failure rc: %x\n", rc); 203 goto err_out; 204 } 205 206 rc = bnxt_alloc_all_hwrm_ring_grps(bp); 207 if (rc) { 208 RTE_LOG(ERR, PMD, "HWRM ring grp alloc failure: %x\n", rc); 209 goto err_out; 210 } 211 212 rc = bnxt_mq_rx_configure(bp); 213 if (rc) { 214 RTE_LOG(ERR, PMD, "MQ mode configure failure rc: %x\n", rc); 215 goto err_out; 216 } 217 218 /* VNIC configuration */ 219 for (i = 0; i < bp->nr_vnics; i++) { 220 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 221 222 rc = bnxt_hwrm_vnic_alloc(bp, vnic); 223 if (rc) { 224 RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n", 225 rc); 226 goto err_out; 227 } 228 229 rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic); 230 if (rc) { 231 RTE_LOG(ERR, PMD, 232 "HWRM vnic ctx alloc failure rc: %x\n", rc); 233 goto err_out; 234 } 235 236 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 237 if (rc) { 238 RTE_LOG(ERR, PMD, "HWRM vnic cfg failure rc: %x\n", rc); 239 goto err_out; 240 } 241 242 rc = bnxt_set_hwrm_vnic_filters(bp, vnic); 243 if (rc) { 244 RTE_LOG(ERR, PMD, "HWRM vnic filter failure rc: %x\n", 245 rc); 246 goto err_out; 247 } 248 if (vnic->rss_table && vnic->hash_type) { 249 /* 250 * Fill the RSS hash & redirection table with 251 * ring group ids for all VNICs 252 */ 253 for (rss_idx = 0, fw_idx = 0; 254 rss_idx < HW_HASH_INDEX_SIZE; 255 rss_idx++, fw_idx++) { 256 if (vnic->fw_grp_ids[fw_idx] == 257 INVALID_HW_RING_ID) 258 fw_idx = 0; 259 vnic->rss_table[rss_idx] = 260 vnic->fw_grp_ids[fw_idx]; 261 } 262 rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic); 263 if (rc) { 264 RTE_LOG(ERR, PMD, 265 "HWRM vnic set RSS failure rc: %x\n", 266 rc); 267 goto err_out; 268 } 269 } 270 } 271 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]); 272 if (rc) { 273 RTE_LOG(ERR, PMD, 274 "HWRM cfa l2 rx mask failure rc: %x\n", rc); 275 goto err_out; 276 } 277 278 return 0; 279 280 err_out: 281 bnxt_free_all_hwrm_resources(bp); 282 283 return rc; 284 } 285 286 static int bnxt_shutdown_nic(struct bnxt *bp) 287 { 288 bnxt_free_all_hwrm_resources(bp); 289 bnxt_free_all_filters(bp); 290 bnxt_free_all_vnics(bp); 291 return 0; 292 } 293 294 static int bnxt_init_nic(struct bnxt *bp) 295 { 296 int rc; 297 298 bnxt_init_ring_grps(bp); 299 bnxt_init_vnics(bp); 300 bnxt_init_filters(bp); 301 302 rc = bnxt_init_chip(bp); 303 if (rc) 304 return rc; 305 306 return 0; 307 } 308 309 /* 310 * Device configuration and status function 311 */ 312 313 static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, 314 struct rte_eth_dev_info *dev_info) 315 { 316 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 317 uint16_t max_vnics, i, j, vpool, vrxq; 318 319 /* MAC Specifics */ 320 dev_info->max_mac_addrs = MAX_NUM_MAC_ADDR; 321 dev_info->max_hash_mac_addrs = 0; 322 323 /* PF/VF specifics */ 324 if (BNXT_PF(bp)) { 325 dev_info->max_rx_queues = bp->pf.max_rx_rings; 326 dev_info->max_tx_queues = bp->pf.max_tx_rings; 327 dev_info->max_vfs = bp->pf.active_vfs; 328 dev_info->reta_size = bp->pf.max_rsscos_ctx; 329 max_vnics = bp->pf.max_vnics; 330 } else { 331 dev_info->max_rx_queues = bp->vf.max_rx_rings; 332 dev_info->max_tx_queues = bp->vf.max_tx_rings; 333 dev_info->reta_size = bp->vf.max_rsscos_ctx; 334 max_vnics = bp->vf.max_vnics; 335 } 336 337 /* Fast path specifics */ 338 dev_info->min_rx_bufsize = 1; 339 dev_info->max_rx_pktlen = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN 340 + VLAN_TAG_SIZE; 341 dev_info->rx_offload_capa = 0; 342 dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM | 343 DEV_TX_OFFLOAD_TCP_CKSUM | 344 DEV_TX_OFFLOAD_UDP_CKSUM | 345 DEV_TX_OFFLOAD_TCP_TSO; 346 347 /* *INDENT-OFF* */ 348 dev_info->default_rxconf = (struct rte_eth_rxconf) { 349 .rx_thresh = { 350 .pthresh = 8, 351 .hthresh = 8, 352 .wthresh = 0, 353 }, 354 .rx_free_thresh = 32, 355 .rx_drop_en = 0, 356 }; 357 358 dev_info->default_txconf = (struct rte_eth_txconf) { 359 .tx_thresh = { 360 .pthresh = 32, 361 .hthresh = 0, 362 .wthresh = 0, 363 }, 364 .tx_free_thresh = 32, 365 .tx_rs_thresh = 32, 366 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | 367 ETH_TXQ_FLAGS_NOOFFLOADS, 368 }; 369 /* *INDENT-ON* */ 370 371 /* 372 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim 373 * need further investigation. 374 */ 375 376 /* VMDq resources */ 377 vpool = 64; /* ETH_64_POOLS */ 378 vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */ 379 for (i = 0; i < 4; vpool >>= 1, i++) { 380 if (max_vnics > vpool) { 381 for (j = 0; j < 5; vrxq >>= 1, j++) { 382 if (dev_info->max_rx_queues > vrxq) { 383 if (vpool > vrxq) 384 vpool = vrxq; 385 goto found; 386 } 387 } 388 /* Not enough resources to support VMDq */ 389 break; 390 } 391 } 392 /* Not enough resources to support VMDq */ 393 vpool = 0; 394 vrxq = 0; 395 found: 396 dev_info->max_vmdq_pools = vpool; 397 dev_info->vmdq_queue_num = vrxq; 398 399 dev_info->vmdq_pool_base = 0; 400 dev_info->vmdq_queue_base = 0; 401 } 402 403 /* Configure the device based on the configuration provided */ 404 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) 405 { 406 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 407 int rc; 408 409 bp->rx_queues = (void *)eth_dev->data->rx_queues; 410 bp->tx_queues = (void *)eth_dev->data->tx_queues; 411 412 /* Inherit new configurations */ 413 bp->rx_nr_rings = eth_dev->data->nb_rx_queues; 414 bp->tx_nr_rings = eth_dev->data->nb_tx_queues; 415 bp->rx_cp_nr_rings = bp->rx_nr_rings; 416 bp->tx_cp_nr_rings = bp->tx_nr_rings; 417 418 if (eth_dev->data->dev_conf.rxmode.jumbo_frame) 419 eth_dev->data->mtu = 420 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 421 ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE; 422 rc = bnxt_set_hwrm_link_config(bp, true); 423 return rc; 424 } 425 426 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) 427 { 428 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 429 int rc; 430 431 rc = bnxt_hwrm_func_reset(bp); 432 if (rc) { 433 RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc); 434 rc = -1; 435 goto error; 436 } 437 438 rc = bnxt_alloc_mem(bp); 439 if (rc) 440 goto error; 441 442 rc = bnxt_init_nic(bp); 443 if (rc) 444 goto error; 445 446 return 0; 447 448 error: 449 bnxt_shutdown_nic(bp); 450 bnxt_free_tx_mbufs(bp); 451 bnxt_free_rx_mbufs(bp); 452 bnxt_free_mem(bp); 453 return rc; 454 } 455 456 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev) 457 { 458 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 459 460 eth_dev->data->dev_link.link_status = 1; 461 bnxt_set_hwrm_link_config(bp, true); 462 return 0; 463 } 464 465 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) 466 { 467 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 468 469 eth_dev->data->dev_link.link_status = 0; 470 bnxt_set_hwrm_link_config(bp, false); 471 return 0; 472 } 473 474 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) 475 { 476 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 477 478 bnxt_free_tx_mbufs(bp); 479 bnxt_free_rx_mbufs(bp); 480 bnxt_free_mem(bp); 481 if (eth_dev->data->mac_addrs != NULL) { 482 rte_free(eth_dev->data->mac_addrs); 483 eth_dev->data->mac_addrs = NULL; 484 } 485 if (bp->grp_info != NULL) { 486 rte_free(bp->grp_info); 487 bp->grp_info = NULL; 488 } 489 } 490 491 /* Unload the driver, release resources */ 492 static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) 493 { 494 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 495 496 if (bp->eth_dev->data->dev_started) { 497 /* TBD: STOP HW queues DMA */ 498 eth_dev->data->dev_link.link_status = 0; 499 } 500 bnxt_shutdown_nic(bp); 501 } 502 503 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, 504 uint32_t index) 505 { 506 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 507 uint64_t pool_mask = eth_dev->data->mac_pool_sel[index]; 508 struct bnxt_vnic_info *vnic; 509 struct bnxt_filter_info *filter, *temp_filter; 510 int i; 511 512 /* 513 * Loop through all VNICs from the specified filter flow pools to 514 * remove the corresponding MAC addr filter 515 */ 516 for (i = 0; i < MAX_FF_POOLS; i++) { 517 if (!(pool_mask & (1 << i))) 518 continue; 519 520 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 521 filter = STAILQ_FIRST(&vnic->filter); 522 while (filter) { 523 temp_filter = STAILQ_NEXT(filter, next); 524 if (filter->mac_index == index) { 525 STAILQ_REMOVE(&vnic->filter, filter, 526 bnxt_filter_info, next); 527 bnxt_hwrm_clear_filter(bp, filter); 528 filter->mac_index = INVALID_MAC_INDEX; 529 memset(&filter->l2_addr, 0, 530 ETHER_ADDR_LEN); 531 STAILQ_INSERT_TAIL( 532 &bp->free_filter_list, 533 filter, next); 534 } 535 filter = temp_filter; 536 } 537 } 538 } 539 } 540 541 static void bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, 542 struct ether_addr *mac_addr, 543 uint32_t index, uint32_t pool) 544 { 545 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 546 struct bnxt_vnic_info *vnic = STAILQ_FIRST(&bp->ff_pool[pool]); 547 struct bnxt_filter_info *filter; 548 549 if (BNXT_VF(bp)) { 550 RTE_LOG(ERR, PMD, "Cannot add MAC address to a VF interface\n"); 551 return; 552 } 553 554 if (!vnic) { 555 RTE_LOG(ERR, PMD, "VNIC not found for pool %d!\n", pool); 556 return; 557 } 558 /* Attach requested MAC address to the new l2_filter */ 559 STAILQ_FOREACH(filter, &vnic->filter, next) { 560 if (filter->mac_index == index) { 561 RTE_LOG(ERR, PMD, 562 "MAC addr already existed for pool %d\n", pool); 563 return; 564 } 565 } 566 filter = bnxt_alloc_filter(bp); 567 if (!filter) { 568 RTE_LOG(ERR, PMD, "L2 filter alloc failed\n"); 569 return; 570 } 571 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 572 filter->mac_index = index; 573 memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN); 574 bnxt_hwrm_set_filter(bp, vnic, filter); 575 } 576 577 static int bnxt_link_update_op(struct rte_eth_dev *eth_dev, 578 int wait_to_complete) 579 { 580 int rc = 0; 581 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 582 struct rte_eth_link new; 583 unsigned int cnt = BNXT_LINK_WAIT_CNT; 584 585 memset(&new, 0, sizeof(new)); 586 do { 587 /* Retrieve link info from hardware */ 588 rc = bnxt_get_hwrm_link_config(bp, &new); 589 if (rc) { 590 new.link_speed = ETH_LINK_SPEED_100M; 591 new.link_duplex = ETH_LINK_FULL_DUPLEX; 592 RTE_LOG(ERR, PMD, 593 "Failed to retrieve link rc = 0x%x!", rc); 594 goto out; 595 } 596 if (!wait_to_complete) 597 break; 598 599 rte_delay_ms(BNXT_LINK_WAIT_INTERVAL); 600 601 } while (!new.link_status && cnt--); 602 603 /* Timed out or success */ 604 if (new.link_status) { 605 /* Update only if success */ 606 eth_dev->data->dev_link.link_duplex = new.link_duplex; 607 eth_dev->data->dev_link.link_speed = new.link_speed; 608 } 609 eth_dev->data->dev_link.link_status = new.link_status; 610 out: 611 return rc; 612 } 613 614 static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) 615 { 616 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 617 struct bnxt_vnic_info *vnic; 618 619 if (bp->vnic_info == NULL) 620 return; 621 622 vnic = &bp->vnic_info[0]; 623 624 vnic->flags |= BNXT_VNIC_INFO_PROMISC; 625 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic); 626 } 627 628 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) 629 { 630 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 631 struct bnxt_vnic_info *vnic; 632 633 if (bp->vnic_info == NULL) 634 return; 635 636 vnic = &bp->vnic_info[0]; 637 638 vnic->flags &= ~BNXT_VNIC_INFO_PROMISC; 639 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic); 640 } 641 642 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) 643 { 644 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 645 struct bnxt_vnic_info *vnic; 646 647 if (bp->vnic_info == NULL) 648 return; 649 650 vnic = &bp->vnic_info[0]; 651 652 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 653 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic); 654 } 655 656 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) 657 { 658 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 659 struct bnxt_vnic_info *vnic; 660 661 if (bp->vnic_info == NULL) 662 return; 663 664 vnic = &bp->vnic_info[0]; 665 666 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 667 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic); 668 } 669 670 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, 671 struct rte_eth_rss_reta_entry64 *reta_conf, 672 uint16_t reta_size) 673 { 674 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 675 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 676 struct bnxt_vnic_info *vnic; 677 int i; 678 679 if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)) 680 return -EINVAL; 681 682 if (reta_size != HW_HASH_INDEX_SIZE) { 683 RTE_LOG(ERR, PMD, "The configured hash table lookup size " 684 "(%d) must equal the size supported by the hardware " 685 "(%d)\n", reta_size, HW_HASH_INDEX_SIZE); 686 return -EINVAL; 687 } 688 /* Update the RSS VNIC(s) */ 689 for (i = 0; i < MAX_FF_POOLS; i++) { 690 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 691 memcpy(vnic->rss_table, reta_conf, reta_size); 692 693 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 694 } 695 } 696 return 0; 697 } 698 699 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, 700 struct rte_eth_rss_reta_entry64 *reta_conf, 701 uint16_t reta_size) 702 { 703 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 704 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 705 706 /* Retrieve from the default VNIC */ 707 if (!vnic) 708 return -EINVAL; 709 if (!vnic->rss_table) 710 return -EINVAL; 711 712 if (reta_size != HW_HASH_INDEX_SIZE) { 713 RTE_LOG(ERR, PMD, "The configured hash table lookup size " 714 "(%d) must equal the size supported by the hardware " 715 "(%d)\n", reta_size, HW_HASH_INDEX_SIZE); 716 return -EINVAL; 717 } 718 /* EW - need to revisit here copying from u64 to u16 */ 719 memcpy(reta_conf, vnic->rss_table, reta_size); 720 721 return 0; 722 } 723 724 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, 725 struct rte_eth_rss_conf *rss_conf) 726 { 727 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 728 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 729 struct bnxt_vnic_info *vnic; 730 uint16_t hash_type = 0; 731 int i; 732 733 /* 734 * If RSS enablement were different than dev_configure, 735 * then return -EINVAL 736 */ 737 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { 738 if (!rss_conf->rss_hf) 739 return -EINVAL; 740 } else { 741 if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT) 742 return -EINVAL; 743 } 744 if (rss_conf->rss_hf & ETH_RSS_IPV4) 745 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 746 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) 747 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 748 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) 749 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 750 if (rss_conf->rss_hf & ETH_RSS_IPV6) 751 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 752 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) 753 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 754 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) 755 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 756 757 /* Update the RSS VNIC(s) */ 758 for (i = 0; i < MAX_FF_POOLS; i++) { 759 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 760 vnic->hash_type = hash_type; 761 762 /* 763 * Use the supplied key if the key length is 764 * acceptable and the rss_key is not NULL 765 */ 766 if (rss_conf->rss_key && 767 rss_conf->rss_key_len <= HW_HASH_KEY_SIZE) 768 memcpy(vnic->rss_hash_key, rss_conf->rss_key, 769 rss_conf->rss_key_len); 770 771 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 772 } 773 } 774 return 0; 775 } 776 777 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, 778 struct rte_eth_rss_conf *rss_conf) 779 { 780 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 781 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 782 int len; 783 uint32_t hash_types; 784 785 /* RSS configuration is the same for all VNICs */ 786 if (vnic && vnic->rss_hash_key) { 787 if (rss_conf->rss_key) { 788 len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ? 789 rss_conf->rss_key_len : HW_HASH_KEY_SIZE; 790 memcpy(rss_conf->rss_key, vnic->rss_hash_key, len); 791 } 792 793 hash_types = vnic->hash_type; 794 rss_conf->rss_hf = 0; 795 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) { 796 rss_conf->rss_hf |= ETH_RSS_IPV4; 797 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 798 } 799 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) { 800 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 801 hash_types &= 802 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 803 } 804 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) { 805 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 806 hash_types &= 807 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 808 } 809 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) { 810 rss_conf->rss_hf |= ETH_RSS_IPV6; 811 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 812 } 813 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) { 814 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 815 hash_types &= 816 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 817 } 818 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) { 819 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 820 hash_types &= 821 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 822 } 823 if (hash_types) { 824 RTE_LOG(ERR, PMD, 825 "Unknwon RSS config from firmware (%08x), RSS disabled", 826 vnic->hash_type); 827 return -ENOTSUP; 828 } 829 } else { 830 rss_conf->rss_hf = 0; 831 } 832 return 0; 833 } 834 835 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev, 836 struct rte_eth_fc_conf *fc_conf __rte_unused) 837 { 838 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 839 struct rte_eth_link link_info; 840 int rc; 841 842 rc = bnxt_get_hwrm_link_config(bp, &link_info); 843 if (rc) 844 return rc; 845 846 memset(fc_conf, 0, sizeof(*fc_conf)); 847 if (bp->link_info.auto_pause) 848 fc_conf->autoneg = 1; 849 switch (bp->link_info.pause) { 850 case 0: 851 fc_conf->mode = RTE_FC_NONE; 852 break; 853 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX: 854 fc_conf->mode = RTE_FC_TX_PAUSE; 855 break; 856 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX: 857 fc_conf->mode = RTE_FC_RX_PAUSE; 858 break; 859 case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 860 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX): 861 fc_conf->mode = RTE_FC_FULL; 862 break; 863 } 864 return 0; 865 } 866 867 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, 868 struct rte_eth_fc_conf *fc_conf) 869 { 870 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 871 872 if (BNXT_NPAR_PF(bp) || BNXT_VF(bp)) { 873 RTE_LOG(ERR, PMD, "Flow Control Settings cannot be modified\n"); 874 return -ENOTSUP; 875 } 876 877 switch (fc_conf->mode) { 878 case RTE_FC_NONE: 879 bp->link_info.auto_pause = 0; 880 bp->link_info.force_pause = 0; 881 break; 882 case RTE_FC_RX_PAUSE: 883 if (fc_conf->autoneg) { 884 bp->link_info.auto_pause = 885 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 886 bp->link_info.force_pause = 0; 887 } else { 888 bp->link_info.auto_pause = 0; 889 bp->link_info.force_pause = 890 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 891 } 892 break; 893 case RTE_FC_TX_PAUSE: 894 if (fc_conf->autoneg) { 895 bp->link_info.auto_pause = 896 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; 897 bp->link_info.force_pause = 0; 898 } else { 899 bp->link_info.auto_pause = 0; 900 bp->link_info.force_pause = 901 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; 902 } 903 break; 904 case RTE_FC_FULL: 905 if (fc_conf->autoneg) { 906 bp->link_info.auto_pause = 907 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX | 908 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 909 bp->link_info.force_pause = 0; 910 } else { 911 bp->link_info.auto_pause = 0; 912 bp->link_info.force_pause = 913 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX | 914 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 915 } 916 break; 917 } 918 return bnxt_set_hwrm_link_config(bp, true); 919 } 920 921 /* 922 * Initialization 923 */ 924 925 static struct eth_dev_ops bnxt_dev_ops = { 926 .dev_infos_get = bnxt_dev_info_get_op, 927 .dev_close = bnxt_dev_close_op, 928 .dev_configure = bnxt_dev_configure_op, 929 .dev_start = bnxt_dev_start_op, 930 .dev_stop = bnxt_dev_stop_op, 931 .dev_set_link_up = bnxt_dev_set_link_up_op, 932 .dev_set_link_down = bnxt_dev_set_link_down_op, 933 .stats_get = bnxt_stats_get_op, 934 .stats_reset = bnxt_stats_reset_op, 935 .rx_queue_setup = bnxt_rx_queue_setup_op, 936 .rx_queue_release = bnxt_rx_queue_release_op, 937 .tx_queue_setup = bnxt_tx_queue_setup_op, 938 .tx_queue_release = bnxt_tx_queue_release_op, 939 .reta_update = bnxt_reta_update_op, 940 .reta_query = bnxt_reta_query_op, 941 .rss_hash_update = bnxt_rss_hash_update_op, 942 .rss_hash_conf_get = bnxt_rss_hash_conf_get_op, 943 .link_update = bnxt_link_update_op, 944 .promiscuous_enable = bnxt_promiscuous_enable_op, 945 .promiscuous_disable = bnxt_promiscuous_disable_op, 946 .allmulticast_enable = bnxt_allmulticast_enable_op, 947 .allmulticast_disable = bnxt_allmulticast_disable_op, 948 .mac_addr_add = bnxt_mac_addr_add_op, 949 .mac_addr_remove = bnxt_mac_addr_remove_op, 950 .flow_ctrl_get = bnxt_flow_ctrl_get_op, 951 .flow_ctrl_set = bnxt_flow_ctrl_set_op, 952 }; 953 954 static bool bnxt_vf_pciid(uint16_t id) 955 { 956 if (id == BROADCOM_DEV_ID_57304_VF || 957 id == BROADCOM_DEV_ID_57406_VF || 958 id == BROADCOM_DEV_ID_5731X_VF || 959 id == BROADCOM_DEV_ID_5741X_VF) 960 return true; 961 return false; 962 } 963 964 static int bnxt_init_board(struct rte_eth_dev *eth_dev) 965 { 966 int rc; 967 struct bnxt *bp = eth_dev->data->dev_private; 968 969 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 970 if (!eth_dev->pci_dev->mem_resource[0].addr) { 971 RTE_LOG(ERR, PMD, 972 "Cannot find PCI device base address, aborting\n"); 973 rc = -ENODEV; 974 goto init_err_disable; 975 } 976 977 bp->eth_dev = eth_dev; 978 bp->pdev = eth_dev->pci_dev; 979 980 bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr; 981 if (!bp->bar0) { 982 RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n"); 983 rc = -ENOMEM; 984 goto init_err_release; 985 } 986 return 0; 987 988 init_err_release: 989 if (bp->bar0) 990 bp->bar0 = NULL; 991 992 init_err_disable: 993 994 return rc; 995 } 996 997 static int 998 bnxt_dev_init(struct rte_eth_dev *eth_dev) 999 { 1000 static int version_printed; 1001 struct bnxt *bp; 1002 int rc; 1003 1004 if (version_printed++ == 0) 1005 RTE_LOG(INFO, PMD, "%s", bnxt_version); 1006 1007 rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev); 1008 bp = eth_dev->data->dev_private; 1009 1010 if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id)) 1011 bp->flags |= BNXT_FLAG_VF; 1012 1013 rc = bnxt_init_board(eth_dev); 1014 if (rc) { 1015 RTE_LOG(ERR, PMD, 1016 "Board initialization failed rc: %x\n", rc); 1017 goto error; 1018 } 1019 eth_dev->dev_ops = &bnxt_dev_ops; 1020 eth_dev->rx_pkt_burst = &bnxt_recv_pkts; 1021 eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; 1022 1023 rc = bnxt_alloc_hwrm_resources(bp); 1024 if (rc) { 1025 RTE_LOG(ERR, PMD, 1026 "hwrm resource allocation failure rc: %x\n", rc); 1027 goto error_free; 1028 } 1029 rc = bnxt_hwrm_ver_get(bp); 1030 if (rc) 1031 goto error_free; 1032 bnxt_hwrm_queue_qportcfg(bp); 1033 1034 bnxt_hwrm_func_qcfg(bp); 1035 1036 /* Get the MAX capabilities for this function */ 1037 rc = bnxt_hwrm_func_qcaps(bp); 1038 if (rc) { 1039 RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc); 1040 goto error_free; 1041 } 1042 eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", 1043 ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR, 0); 1044 if (eth_dev->data->mac_addrs == NULL) { 1045 RTE_LOG(ERR, PMD, 1046 "Failed to alloc %u bytes needed to store MAC addr tbl", 1047 ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR); 1048 rc = -ENOMEM; 1049 goto error_free; 1050 } 1051 /* Copy the permanent MAC from the qcap response address now. */ 1052 if (BNXT_PF(bp)) 1053 memcpy(bp->mac_addr, bp->pf.mac_addr, sizeof(bp->mac_addr)); 1054 else 1055 memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr)); 1056 memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN); 1057 bp->grp_info = rte_zmalloc("bnxt_grp_info", 1058 sizeof(*bp->grp_info) * bp->max_ring_grps, 0); 1059 if (!bp->grp_info) { 1060 RTE_LOG(ERR, PMD, 1061 "Failed to alloc %zu bytes needed to store group info table\n", 1062 sizeof(*bp->grp_info) * bp->max_ring_grps); 1063 rc = -ENOMEM; 1064 goto error_free; 1065 } 1066 1067 rc = bnxt_hwrm_func_driver_register(bp, 0, 1068 bp->pf.vf_req_fwd); 1069 if (rc) { 1070 RTE_LOG(ERR, PMD, 1071 "Failed to register driver"); 1072 rc = -EBUSY; 1073 goto error_free; 1074 } 1075 1076 RTE_LOG(INFO, PMD, 1077 DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n", 1078 eth_dev->pci_dev->mem_resource[0].phys_addr, 1079 eth_dev->pci_dev->mem_resource[0].addr); 1080 1081 return 0; 1082 1083 error_free: 1084 eth_dev->driver->eth_dev_uninit(eth_dev); 1085 error: 1086 return rc; 1087 } 1088 1089 static int 1090 bnxt_dev_uninit(struct rte_eth_dev *eth_dev) { 1091 struct bnxt *bp = eth_dev->data->dev_private; 1092 int rc; 1093 1094 if (eth_dev->data->mac_addrs != NULL) { 1095 rte_free(eth_dev->data->mac_addrs); 1096 eth_dev->data->mac_addrs = NULL; 1097 } 1098 if (bp->grp_info != NULL) { 1099 rte_free(bp->grp_info); 1100 bp->grp_info = NULL; 1101 } 1102 rc = bnxt_hwrm_func_driver_unregister(bp, 0); 1103 bnxt_free_hwrm_resources(bp); 1104 eth_dev->dev_ops = NULL; 1105 eth_dev->rx_pkt_burst = NULL; 1106 eth_dev->tx_pkt_burst = NULL; 1107 1108 return rc; 1109 } 1110 1111 static struct eth_driver bnxt_rte_pmd = { 1112 .pci_drv = { 1113 .id_table = bnxt_pci_id_map, 1114 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | 1115 RTE_PCI_DRV_DETACHABLE, 1116 .probe = rte_eth_dev_pci_probe, 1117 .remove = rte_eth_dev_pci_remove 1118 }, 1119 .eth_dev_init = bnxt_dev_init, 1120 .eth_dev_uninit = bnxt_dev_uninit, 1121 .dev_private_size = sizeof(struct bnxt), 1122 }; 1123 1124 DRIVER_REGISTER_PCI(net_bnxt, bnxt_rte_pmd.pci_drv); 1125 DRIVER_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map); 1126