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