1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2018 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <inttypes.h> 7 #include <stdbool.h> 8 9 #include <rte_dev.h> 10 #include <rte_ethdev_driver.h> 11 #include <rte_ethdev_pci.h> 12 #include <rte_malloc.h> 13 #include <rte_cycles.h> 14 15 #include "bnxt.h" 16 #include "bnxt_cpr.h" 17 #include "bnxt_filter.h" 18 #include "bnxt_hwrm.h" 19 #include "bnxt_irq.h" 20 #include "bnxt_ring.h" 21 #include "bnxt_rxq.h" 22 #include "bnxt_rxr.h" 23 #include "bnxt_stats.h" 24 #include "bnxt_txq.h" 25 #include "bnxt_txr.h" 26 #include "bnxt_vnic.h" 27 #include "hsi_struct_def_dpdk.h" 28 #include "bnxt_nvm_defs.h" 29 30 #define DRV_MODULE_NAME "bnxt" 31 static const char bnxt_version[] = 32 "Broadcom Cumulus driver " DRV_MODULE_NAME "\n"; 33 int bnxt_logtype_driver; 34 35 #define PCI_VENDOR_ID_BROADCOM 0x14E4 36 37 #define BROADCOM_DEV_ID_STRATUS_NIC_VF 0x1609 38 #define BROADCOM_DEV_ID_STRATUS_NIC 0x1614 39 #define BROADCOM_DEV_ID_57414_VF 0x16c1 40 #define BROADCOM_DEV_ID_57301 0x16c8 41 #define BROADCOM_DEV_ID_57302 0x16c9 42 #define BROADCOM_DEV_ID_57304_PF 0x16ca 43 #define BROADCOM_DEV_ID_57304_VF 0x16cb 44 #define BROADCOM_DEV_ID_57417_MF 0x16cc 45 #define BROADCOM_DEV_ID_NS2 0x16cd 46 #define BROADCOM_DEV_ID_57311 0x16ce 47 #define BROADCOM_DEV_ID_57312 0x16cf 48 #define BROADCOM_DEV_ID_57402 0x16d0 49 #define BROADCOM_DEV_ID_57404 0x16d1 50 #define BROADCOM_DEV_ID_57406_PF 0x16d2 51 #define BROADCOM_DEV_ID_57406_VF 0x16d3 52 #define BROADCOM_DEV_ID_57402_MF 0x16d4 53 #define BROADCOM_DEV_ID_57407_RJ45 0x16d5 54 #define BROADCOM_DEV_ID_57412 0x16d6 55 #define BROADCOM_DEV_ID_57414 0x16d7 56 #define BROADCOM_DEV_ID_57416_RJ45 0x16d8 57 #define BROADCOM_DEV_ID_57417_RJ45 0x16d9 58 #define BROADCOM_DEV_ID_5741X_VF 0x16dc 59 #define BROADCOM_DEV_ID_57412_MF 0x16de 60 #define BROADCOM_DEV_ID_57314 0x16df 61 #define BROADCOM_DEV_ID_57317_RJ45 0x16e0 62 #define BROADCOM_DEV_ID_5731X_VF 0x16e1 63 #define BROADCOM_DEV_ID_57417_SFP 0x16e2 64 #define BROADCOM_DEV_ID_57416_SFP 0x16e3 65 #define BROADCOM_DEV_ID_57317_SFP 0x16e4 66 #define BROADCOM_DEV_ID_57404_MF 0x16e7 67 #define BROADCOM_DEV_ID_57406_MF 0x16e8 68 #define BROADCOM_DEV_ID_57407_SFP 0x16e9 69 #define BROADCOM_DEV_ID_57407_MF 0x16ea 70 #define BROADCOM_DEV_ID_57414_MF 0x16ec 71 #define BROADCOM_DEV_ID_57416_MF 0x16ee 72 73 static const struct rte_pci_id bnxt_pci_id_map[] = { 74 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 75 BROADCOM_DEV_ID_STRATUS_NIC_VF) }, 76 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) }, 77 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) }, 78 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) }, 79 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302) }, 80 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF) }, 81 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) }, 82 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) }, 83 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402) }, 84 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404) }, 85 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF) }, 86 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) }, 87 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402_MF) }, 88 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_RJ45) }, 89 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404_MF) }, 90 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF) }, 91 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_SFP) }, 92 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) }, 93 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) }, 94 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) }, 95 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57314) }, 96 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) }, 97 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57311) }, 98 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57312) }, 99 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) }, 100 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) }, 101 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) }, 102 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) }, 103 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) }, 104 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) }, 105 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) }, 106 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) }, 107 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) }, 108 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) }, 109 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) }, 110 { .vendor_id = 0, /* sentinel */ }, 111 }; 112 113 #define BNXT_ETH_RSS_SUPPORT ( \ 114 ETH_RSS_IPV4 | \ 115 ETH_RSS_NONFRAG_IPV4_TCP | \ 116 ETH_RSS_NONFRAG_IPV4_UDP | \ 117 ETH_RSS_IPV6 | \ 118 ETH_RSS_NONFRAG_IPV6_TCP | \ 119 ETH_RSS_NONFRAG_IPV6_UDP) 120 121 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask); 122 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev); 123 124 /***********************/ 125 126 /* 127 * High level utility functions 128 */ 129 130 static void bnxt_free_mem(struct bnxt *bp) 131 { 132 bnxt_free_filter_mem(bp); 133 bnxt_free_vnic_attributes(bp); 134 bnxt_free_vnic_mem(bp); 135 136 bnxt_free_stats(bp); 137 bnxt_free_tx_rings(bp); 138 bnxt_free_rx_rings(bp); 139 bnxt_free_def_cp_ring(bp); 140 } 141 142 static int bnxt_alloc_mem(struct bnxt *bp) 143 { 144 int rc; 145 146 /* Default completion ring */ 147 rc = bnxt_init_def_ring_struct(bp, SOCKET_ID_ANY); 148 if (rc) 149 goto alloc_mem_err; 150 151 rc = bnxt_alloc_rings(bp, 0, NULL, NULL, 152 bp->def_cp_ring, "def_cp"); 153 if (rc) 154 goto alloc_mem_err; 155 156 rc = bnxt_alloc_vnic_mem(bp); 157 if (rc) 158 goto alloc_mem_err; 159 160 rc = bnxt_alloc_vnic_attributes(bp); 161 if (rc) 162 goto alloc_mem_err; 163 164 rc = bnxt_alloc_filter_mem(bp); 165 if (rc) 166 goto alloc_mem_err; 167 168 return 0; 169 170 alloc_mem_err: 171 bnxt_free_mem(bp); 172 return rc; 173 } 174 175 static int bnxt_init_chip(struct bnxt *bp) 176 { 177 unsigned int i; 178 struct rte_eth_link new; 179 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev); 180 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 181 uint32_t intr_vector = 0; 182 uint32_t queue_id, base = BNXT_MISC_VEC_ID; 183 uint32_t vec = BNXT_MISC_VEC_ID; 184 int rc; 185 186 /* disable uio/vfio intr/eventfd mapping */ 187 rte_intr_disable(intr_handle); 188 189 if (bp->eth_dev->data->mtu > ETHER_MTU) { 190 bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 1; 191 bp->flags |= BNXT_FLAG_JUMBO; 192 } else { 193 bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 0; 194 bp->flags &= ~BNXT_FLAG_JUMBO; 195 } 196 197 rc = bnxt_alloc_all_hwrm_stat_ctxs(bp); 198 if (rc) { 199 PMD_DRV_LOG(ERR, "HWRM stat ctx alloc failure rc: %x\n", rc); 200 goto err_out; 201 } 202 203 rc = bnxt_alloc_hwrm_rings(bp); 204 if (rc) { 205 PMD_DRV_LOG(ERR, "HWRM ring alloc failure rc: %x\n", rc); 206 goto err_out; 207 } 208 209 rc = bnxt_alloc_all_hwrm_ring_grps(bp); 210 if (rc) { 211 PMD_DRV_LOG(ERR, "HWRM ring grp alloc failure: %x\n", rc); 212 goto err_out; 213 } 214 215 rc = bnxt_mq_rx_configure(bp); 216 if (rc) { 217 PMD_DRV_LOG(ERR, "MQ mode configure failure rc: %x\n", rc); 218 goto err_out; 219 } 220 221 /* VNIC configuration */ 222 for (i = 0; i < bp->nr_vnics; i++) { 223 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 224 225 rc = bnxt_hwrm_vnic_alloc(bp, vnic); 226 if (rc) { 227 PMD_DRV_LOG(ERR, "HWRM vnic %d alloc failure rc: %x\n", 228 i, rc); 229 goto err_out; 230 } 231 232 rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic); 233 if (rc) { 234 PMD_DRV_LOG(ERR, 235 "HWRM vnic %d ctx alloc failure rc: %x\n", 236 i, rc); 237 goto err_out; 238 } 239 240 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 241 if (rc) { 242 PMD_DRV_LOG(ERR, "HWRM vnic %d cfg failure rc: %x\n", 243 i, rc); 244 goto err_out; 245 } 246 247 rc = bnxt_set_hwrm_vnic_filters(bp, vnic); 248 if (rc) { 249 PMD_DRV_LOG(ERR, 250 "HWRM vnic %d filter failure rc: %x\n", 251 i, rc); 252 goto err_out; 253 } 254 255 rc = bnxt_vnic_rss_configure(bp, vnic); 256 if (rc) { 257 PMD_DRV_LOG(ERR, 258 "HWRM vnic set RSS failure rc: %x\n", rc); 259 goto err_out; 260 } 261 262 bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 263 264 if (bp->eth_dev->data->dev_conf.rxmode.enable_lro) 265 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1); 266 else 267 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0); 268 } 269 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL); 270 if (rc) { 271 PMD_DRV_LOG(ERR, 272 "HWRM cfa l2 rx mask failure rc: %x\n", rc); 273 goto err_out; 274 } 275 276 /* check and configure queue intr-vector mapping */ 277 if ((rte_intr_cap_multiple(intr_handle) || 278 !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) && 279 bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) { 280 intr_vector = bp->eth_dev->data->nb_rx_queues; 281 PMD_DRV_LOG(DEBUG, "intr_vector = %d\n", intr_vector); 282 if (intr_vector > bp->rx_cp_nr_rings) { 283 PMD_DRV_LOG(ERR, "At most %d intr queues supported", 284 bp->rx_cp_nr_rings); 285 return -ENOTSUP; 286 } 287 if (rte_intr_efd_enable(intr_handle, intr_vector)) 288 return -1; 289 } 290 291 if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { 292 intr_handle->intr_vec = 293 rte_zmalloc("intr_vec", 294 bp->eth_dev->data->nb_rx_queues * 295 sizeof(int), 0); 296 if (intr_handle->intr_vec == NULL) { 297 PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues" 298 " intr_vec", bp->eth_dev->data->nb_rx_queues); 299 return -ENOMEM; 300 } 301 PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p " 302 "intr_handle->nb_efd = %d intr_handle->max_intr = %d\n", 303 intr_handle->intr_vec, intr_handle->nb_efd, 304 intr_handle->max_intr); 305 } 306 307 for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues; 308 queue_id++) { 309 intr_handle->intr_vec[queue_id] = vec; 310 if (vec < base + intr_handle->nb_efd - 1) 311 vec++; 312 } 313 314 /* enable uio/vfio intr/eventfd mapping */ 315 rte_intr_enable(intr_handle); 316 317 rc = bnxt_get_hwrm_link_config(bp, &new); 318 if (rc) { 319 PMD_DRV_LOG(ERR, "HWRM Get link config failure rc: %x\n", rc); 320 goto err_out; 321 } 322 323 if (!bp->link_info.link_up) { 324 rc = bnxt_set_hwrm_link_config(bp, true); 325 if (rc) { 326 PMD_DRV_LOG(ERR, 327 "HWRM link config failure rc: %x\n", rc); 328 goto err_out; 329 } 330 } 331 bnxt_print_link_info(bp->eth_dev); 332 333 return 0; 334 335 err_out: 336 bnxt_free_all_hwrm_resources(bp); 337 338 /* Some of the error status returned by FW may not be from errno.h */ 339 if (rc > 0) 340 rc = -EIO; 341 342 return rc; 343 } 344 345 static int bnxt_shutdown_nic(struct bnxt *bp) 346 { 347 bnxt_free_all_hwrm_resources(bp); 348 bnxt_free_all_filters(bp); 349 bnxt_free_all_vnics(bp); 350 return 0; 351 } 352 353 static int bnxt_init_nic(struct bnxt *bp) 354 { 355 int rc; 356 357 rc = bnxt_init_ring_grps(bp); 358 if (rc) 359 return rc; 360 361 bnxt_init_vnics(bp); 362 bnxt_init_filters(bp); 363 364 rc = bnxt_init_chip(bp); 365 if (rc) 366 return rc; 367 368 return 0; 369 } 370 371 /* 372 * Device configuration and status function 373 */ 374 375 static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, 376 struct rte_eth_dev_info *dev_info) 377 { 378 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 379 uint16_t max_vnics, i, j, vpool, vrxq; 380 unsigned int max_rx_rings; 381 382 dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 383 384 /* MAC Specifics */ 385 dev_info->max_mac_addrs = bp->max_l2_ctx; 386 dev_info->max_hash_mac_addrs = 0; 387 388 /* PF/VF specifics */ 389 if (BNXT_PF(bp)) 390 dev_info->max_vfs = bp->pdev->max_vfs; 391 max_rx_rings = RTE_MIN(bp->max_vnics, RTE_MIN(bp->max_l2_ctx, 392 RTE_MIN(bp->max_rsscos_ctx, 393 bp->max_stat_ctx))); 394 /* For the sake of symmetry, max_rx_queues = max_tx_queues */ 395 dev_info->max_rx_queues = max_rx_rings; 396 dev_info->max_tx_queues = max_rx_rings; 397 dev_info->reta_size = bp->max_rsscos_ctx; 398 dev_info->hash_key_size = 40; 399 max_vnics = bp->max_vnics; 400 401 /* Fast path specifics */ 402 dev_info->min_rx_bufsize = 1; 403 dev_info->max_rx_pktlen = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN 404 + VLAN_TAG_SIZE; 405 dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP | 406 DEV_RX_OFFLOAD_IPV4_CKSUM | 407 DEV_RX_OFFLOAD_UDP_CKSUM | 408 DEV_RX_OFFLOAD_TCP_CKSUM | 409 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM; 410 dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT | 411 DEV_TX_OFFLOAD_IPV4_CKSUM | 412 DEV_TX_OFFLOAD_TCP_CKSUM | 413 DEV_TX_OFFLOAD_UDP_CKSUM | 414 DEV_TX_OFFLOAD_TCP_TSO | 415 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | 416 DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 417 DEV_TX_OFFLOAD_GRE_TNL_TSO | 418 DEV_TX_OFFLOAD_IPIP_TNL_TSO | 419 DEV_TX_OFFLOAD_GENEVE_TNL_TSO; 420 421 /* *INDENT-OFF* */ 422 dev_info->default_rxconf = (struct rte_eth_rxconf) { 423 .rx_thresh = { 424 .pthresh = 8, 425 .hthresh = 8, 426 .wthresh = 0, 427 }, 428 .rx_free_thresh = 32, 429 .rx_drop_en = 0, 430 }; 431 432 dev_info->default_txconf = (struct rte_eth_txconf) { 433 .tx_thresh = { 434 .pthresh = 32, 435 .hthresh = 0, 436 .wthresh = 0, 437 }, 438 .tx_free_thresh = 32, 439 .tx_rs_thresh = 32, 440 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | 441 ETH_TXQ_FLAGS_NOOFFLOADS, 442 }; 443 eth_dev->data->dev_conf.intr_conf.lsc = 1; 444 445 eth_dev->data->dev_conf.intr_conf.rxq = 1; 446 447 /* *INDENT-ON* */ 448 449 /* 450 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim 451 * need further investigation. 452 */ 453 454 /* VMDq resources */ 455 vpool = 64; /* ETH_64_POOLS */ 456 vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */ 457 for (i = 0; i < 4; vpool >>= 1, i++) { 458 if (max_vnics > vpool) { 459 for (j = 0; j < 5; vrxq >>= 1, j++) { 460 if (dev_info->max_rx_queues > vrxq) { 461 if (vpool > vrxq) 462 vpool = vrxq; 463 goto found; 464 } 465 } 466 /* Not enough resources to support VMDq */ 467 break; 468 } 469 } 470 /* Not enough resources to support VMDq */ 471 vpool = 0; 472 vrxq = 0; 473 found: 474 dev_info->max_vmdq_pools = vpool; 475 dev_info->vmdq_queue_num = vrxq; 476 477 dev_info->vmdq_pool_base = 0; 478 dev_info->vmdq_queue_base = 0; 479 } 480 481 /* Configure the device based on the configuration provided */ 482 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) 483 { 484 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 485 486 bp->rx_queues = (void *)eth_dev->data->rx_queues; 487 bp->tx_queues = (void *)eth_dev->data->tx_queues; 488 489 /* Inherit new configurations */ 490 if (eth_dev->data->nb_rx_queues > bp->max_rx_rings || 491 eth_dev->data->nb_tx_queues > bp->max_tx_rings || 492 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues + 1 > 493 bp->max_cp_rings || 494 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues > 495 bp->max_stat_ctx || 496 (uint32_t)(eth_dev->data->nb_rx_queues + 1) > bp->max_ring_grps) { 497 PMD_DRV_LOG(ERR, 498 "Insufficient resources to support requested config\n"); 499 PMD_DRV_LOG(ERR, 500 "Num Queues Requested: Tx %d, Rx %d\n", 501 eth_dev->data->nb_tx_queues, 502 eth_dev->data->nb_rx_queues); 503 PMD_DRV_LOG(ERR, 504 "Res available: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d\n", 505 bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings, 506 bp->max_stat_ctx, bp->max_ring_grps); 507 return -ENOSPC; 508 } 509 510 bp->rx_nr_rings = eth_dev->data->nb_rx_queues; 511 bp->tx_nr_rings = eth_dev->data->nb_tx_queues; 512 bp->rx_cp_nr_rings = bp->rx_nr_rings; 513 bp->tx_cp_nr_rings = bp->tx_nr_rings; 514 515 if (eth_dev->data->dev_conf.rxmode.jumbo_frame) 516 eth_dev->data->mtu = 517 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 518 ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE; 519 return 0; 520 } 521 522 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev) 523 { 524 struct rte_eth_link *link = ð_dev->data->dev_link; 525 526 if (link->link_status) 527 PMD_DRV_LOG(INFO, "Port %d Link Up - speed %u Mbps - %s\n", 528 eth_dev->data->port_id, 529 (uint32_t)link->link_speed, 530 (link->link_duplex == ETH_LINK_FULL_DUPLEX) ? 531 ("full-duplex") : ("half-duplex\n")); 532 else 533 PMD_DRV_LOG(INFO, "Port %d Link Down\n", 534 eth_dev->data->port_id); 535 } 536 537 static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev) 538 { 539 bnxt_print_link_info(eth_dev); 540 return 0; 541 } 542 543 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) 544 { 545 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 546 int vlan_mask = 0; 547 int rc; 548 549 if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) { 550 PMD_DRV_LOG(ERR, 551 "RxQ cnt %d > CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n", 552 bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS); 553 } 554 bp->dev_stopped = 0; 555 556 rc = bnxt_init_nic(bp); 557 if (rc) 558 goto error; 559 560 bnxt_link_update_op(eth_dev, 1); 561 562 if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter) 563 vlan_mask |= ETH_VLAN_FILTER_MASK; 564 if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip) 565 vlan_mask |= ETH_VLAN_STRIP_MASK; 566 rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask); 567 if (rc) 568 goto error; 569 570 bp->flags |= BNXT_FLAG_INIT_DONE; 571 return 0; 572 573 error: 574 bnxt_shutdown_nic(bp); 575 bnxt_free_tx_mbufs(bp); 576 bnxt_free_rx_mbufs(bp); 577 return rc; 578 } 579 580 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev) 581 { 582 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 583 int rc = 0; 584 585 if (!bp->link_info.link_up) 586 rc = bnxt_set_hwrm_link_config(bp, true); 587 if (!rc) 588 eth_dev->data->dev_link.link_status = 1; 589 590 bnxt_print_link_info(eth_dev); 591 return 0; 592 } 593 594 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) 595 { 596 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 597 598 eth_dev->data->dev_link.link_status = 0; 599 bnxt_set_hwrm_link_config(bp, false); 600 bp->link_info.link_up = 0; 601 602 return 0; 603 } 604 605 /* Unload the driver, release resources */ 606 static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) 607 { 608 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 609 610 if (bp->eth_dev->data->dev_started) { 611 /* TBD: STOP HW queues DMA */ 612 eth_dev->data->dev_link.link_status = 0; 613 } 614 bnxt_set_hwrm_link_config(bp, false); 615 bnxt_hwrm_port_clr_stats(bp); 616 bp->flags &= ~BNXT_FLAG_INIT_DONE; 617 bnxt_shutdown_nic(bp); 618 bp->dev_stopped = 1; 619 } 620 621 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) 622 { 623 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 624 625 if (bp->dev_stopped == 0) 626 bnxt_dev_stop_op(eth_dev); 627 628 bnxt_free_tx_mbufs(bp); 629 bnxt_free_rx_mbufs(bp); 630 bnxt_free_mem(bp); 631 if (eth_dev->data->mac_addrs != NULL) { 632 rte_free(eth_dev->data->mac_addrs); 633 eth_dev->data->mac_addrs = NULL; 634 } 635 if (bp->grp_info != NULL) { 636 rte_free(bp->grp_info); 637 bp->grp_info = NULL; 638 } 639 } 640 641 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, 642 uint32_t index) 643 { 644 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 645 uint64_t pool_mask = eth_dev->data->mac_pool_sel[index]; 646 struct bnxt_vnic_info *vnic; 647 struct bnxt_filter_info *filter, *temp_filter; 648 uint32_t pool = RTE_MIN(MAX_FF_POOLS, ETH_64_POOLS); 649 uint32_t i; 650 651 /* 652 * Loop through all VNICs from the specified filter flow pools to 653 * remove the corresponding MAC addr filter 654 */ 655 for (i = 0; i < pool; i++) { 656 if (!(pool_mask & (1ULL << i))) 657 continue; 658 659 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 660 filter = STAILQ_FIRST(&vnic->filter); 661 while (filter) { 662 temp_filter = STAILQ_NEXT(filter, next); 663 if (filter->mac_index == index) { 664 STAILQ_REMOVE(&vnic->filter, filter, 665 bnxt_filter_info, next); 666 bnxt_hwrm_clear_l2_filter(bp, filter); 667 filter->mac_index = INVALID_MAC_INDEX; 668 memset(&filter->l2_addr, 0, 669 ETHER_ADDR_LEN); 670 STAILQ_INSERT_TAIL( 671 &bp->free_filter_list, 672 filter, next); 673 } 674 filter = temp_filter; 675 } 676 } 677 } 678 } 679 680 static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, 681 struct ether_addr *mac_addr, 682 uint32_t index, uint32_t pool) 683 { 684 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 685 struct bnxt_vnic_info *vnic = STAILQ_FIRST(&bp->ff_pool[pool]); 686 struct bnxt_filter_info *filter; 687 688 if (BNXT_VF(bp)) { 689 PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n"); 690 return -ENOTSUP; 691 } 692 693 if (!vnic) { 694 PMD_DRV_LOG(ERR, "VNIC not found for pool %d!\n", pool); 695 return -EINVAL; 696 } 697 /* Attach requested MAC address to the new l2_filter */ 698 STAILQ_FOREACH(filter, &vnic->filter, next) { 699 if (filter->mac_index == index) { 700 PMD_DRV_LOG(ERR, 701 "MAC addr already existed for pool %d\n", pool); 702 return 0; 703 } 704 } 705 filter = bnxt_alloc_filter(bp); 706 if (!filter) { 707 PMD_DRV_LOG(ERR, "L2 filter alloc failed\n"); 708 return -ENODEV; 709 } 710 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 711 filter->mac_index = index; 712 memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN); 713 return bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 714 } 715 716 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) 717 { 718 int rc = 0; 719 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 720 struct rte_eth_link new; 721 unsigned int cnt = BNXT_LINK_WAIT_CNT; 722 723 memset(&new, 0, sizeof(new)); 724 do { 725 /* Retrieve link info from hardware */ 726 rc = bnxt_get_hwrm_link_config(bp, &new); 727 if (rc) { 728 new.link_speed = ETH_LINK_SPEED_100M; 729 new.link_duplex = ETH_LINK_FULL_DUPLEX; 730 PMD_DRV_LOG(ERR, 731 "Failed to retrieve link rc = 0x%x!\n", rc); 732 goto out; 733 } 734 rte_delay_ms(BNXT_LINK_WAIT_INTERVAL); 735 736 if (!wait_to_complete) 737 break; 738 } while (!new.link_status && cnt--); 739 740 out: 741 /* Timed out or success */ 742 if (new.link_status != eth_dev->data->dev_link.link_status || 743 new.link_speed != eth_dev->data->dev_link.link_speed) { 744 memcpy(ð_dev->data->dev_link, &new, 745 sizeof(struct rte_eth_link)); 746 bnxt_print_link_info(eth_dev); 747 } 748 749 return rc; 750 } 751 752 static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) 753 { 754 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 755 struct bnxt_vnic_info *vnic; 756 757 if (bp->vnic_info == NULL) 758 return; 759 760 vnic = &bp->vnic_info[0]; 761 762 vnic->flags |= BNXT_VNIC_INFO_PROMISC; 763 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 764 } 765 766 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) 767 { 768 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 769 struct bnxt_vnic_info *vnic; 770 771 if (bp->vnic_info == NULL) 772 return; 773 774 vnic = &bp->vnic_info[0]; 775 776 vnic->flags &= ~BNXT_VNIC_INFO_PROMISC; 777 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 778 } 779 780 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) 781 { 782 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 783 struct bnxt_vnic_info *vnic; 784 785 if (bp->vnic_info == NULL) 786 return; 787 788 vnic = &bp->vnic_info[0]; 789 790 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 791 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 792 } 793 794 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) 795 { 796 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 797 struct bnxt_vnic_info *vnic; 798 799 if (bp->vnic_info == NULL) 800 return; 801 802 vnic = &bp->vnic_info[0]; 803 804 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 805 bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 806 } 807 808 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, 809 struct rte_eth_rss_reta_entry64 *reta_conf, 810 uint16_t reta_size) 811 { 812 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 813 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 814 struct bnxt_vnic_info *vnic; 815 int i; 816 817 if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)) 818 return -EINVAL; 819 820 if (reta_size != HW_HASH_INDEX_SIZE) { 821 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 822 "(%d) must equal the size supported by the hardware " 823 "(%d)\n", reta_size, HW_HASH_INDEX_SIZE); 824 return -EINVAL; 825 } 826 /* Update the RSS VNIC(s) */ 827 for (i = 0; i < MAX_FF_POOLS; i++) { 828 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 829 memcpy(vnic->rss_table, reta_conf, reta_size); 830 831 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 832 } 833 } 834 return 0; 835 } 836 837 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, 838 struct rte_eth_rss_reta_entry64 *reta_conf, 839 uint16_t reta_size) 840 { 841 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 842 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 843 struct rte_intr_handle *intr_handle 844 = &bp->pdev->intr_handle; 845 846 /* Retrieve from the default VNIC */ 847 if (!vnic) 848 return -EINVAL; 849 if (!vnic->rss_table) 850 return -EINVAL; 851 852 if (reta_size != HW_HASH_INDEX_SIZE) { 853 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 854 "(%d) must equal the size supported by the hardware " 855 "(%d)\n", reta_size, HW_HASH_INDEX_SIZE); 856 return -EINVAL; 857 } 858 /* EW - need to revisit here copying from uint64_t to uint16_t */ 859 memcpy(reta_conf, vnic->rss_table, reta_size); 860 861 if (rte_intr_allow_others(intr_handle)) { 862 if (eth_dev->data->dev_conf.intr_conf.lsc != 0) 863 bnxt_dev_lsc_intr_setup(eth_dev); 864 } 865 866 return 0; 867 } 868 869 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, 870 struct rte_eth_rss_conf *rss_conf) 871 { 872 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 873 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 874 struct bnxt_vnic_info *vnic; 875 uint16_t hash_type = 0; 876 int i; 877 878 /* 879 * If RSS enablement were different than dev_configure, 880 * then return -EINVAL 881 */ 882 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { 883 if (!rss_conf->rss_hf) 884 PMD_DRV_LOG(ERR, "Hash type NONE\n"); 885 } else { 886 if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT) 887 return -EINVAL; 888 } 889 890 bp->flags |= BNXT_FLAG_UPDATE_HASH; 891 memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf)); 892 893 if (rss_conf->rss_hf & ETH_RSS_IPV4) 894 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 895 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) 896 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 897 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) 898 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 899 if (rss_conf->rss_hf & ETH_RSS_IPV6) 900 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 901 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) 902 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 903 if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) 904 hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 905 906 /* Update the RSS VNIC(s) */ 907 for (i = 0; i < MAX_FF_POOLS; i++) { 908 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 909 vnic->hash_type = hash_type; 910 911 /* 912 * Use the supplied key if the key length is 913 * acceptable and the rss_key is not NULL 914 */ 915 if (rss_conf->rss_key && 916 rss_conf->rss_key_len <= HW_HASH_KEY_SIZE) 917 memcpy(vnic->rss_hash_key, rss_conf->rss_key, 918 rss_conf->rss_key_len); 919 920 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 921 } 922 } 923 return 0; 924 } 925 926 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, 927 struct rte_eth_rss_conf *rss_conf) 928 { 929 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 930 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 931 int len; 932 uint32_t hash_types; 933 934 /* RSS configuration is the same for all VNICs */ 935 if (vnic && vnic->rss_hash_key) { 936 if (rss_conf->rss_key) { 937 len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ? 938 rss_conf->rss_key_len : HW_HASH_KEY_SIZE; 939 memcpy(rss_conf->rss_key, vnic->rss_hash_key, len); 940 } 941 942 hash_types = vnic->hash_type; 943 rss_conf->rss_hf = 0; 944 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) { 945 rss_conf->rss_hf |= ETH_RSS_IPV4; 946 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 947 } 948 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) { 949 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 950 hash_types &= 951 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 952 } 953 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) { 954 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 955 hash_types &= 956 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 957 } 958 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) { 959 rss_conf->rss_hf |= ETH_RSS_IPV6; 960 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 961 } 962 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) { 963 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 964 hash_types &= 965 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 966 } 967 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) { 968 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 969 hash_types &= 970 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 971 } 972 if (hash_types) { 973 PMD_DRV_LOG(ERR, 974 "Unknwon RSS config from firmware (%08x), RSS disabled", 975 vnic->hash_type); 976 return -ENOTSUP; 977 } 978 } else { 979 rss_conf->rss_hf = 0; 980 } 981 return 0; 982 } 983 984 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev, 985 struct rte_eth_fc_conf *fc_conf) 986 { 987 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 988 struct rte_eth_link link_info; 989 int rc; 990 991 rc = bnxt_get_hwrm_link_config(bp, &link_info); 992 if (rc) 993 return rc; 994 995 memset(fc_conf, 0, sizeof(*fc_conf)); 996 if (bp->link_info.auto_pause) 997 fc_conf->autoneg = 1; 998 switch (bp->link_info.pause) { 999 case 0: 1000 fc_conf->mode = RTE_FC_NONE; 1001 break; 1002 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX: 1003 fc_conf->mode = RTE_FC_TX_PAUSE; 1004 break; 1005 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX: 1006 fc_conf->mode = RTE_FC_RX_PAUSE; 1007 break; 1008 case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1009 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX): 1010 fc_conf->mode = RTE_FC_FULL; 1011 break; 1012 } 1013 return 0; 1014 } 1015 1016 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, 1017 struct rte_eth_fc_conf *fc_conf) 1018 { 1019 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1020 1021 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 1022 PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n"); 1023 return -ENOTSUP; 1024 } 1025 1026 switch (fc_conf->mode) { 1027 case RTE_FC_NONE: 1028 bp->link_info.auto_pause = 0; 1029 bp->link_info.force_pause = 0; 1030 break; 1031 case RTE_FC_RX_PAUSE: 1032 if (fc_conf->autoneg) { 1033 bp->link_info.auto_pause = 1034 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 1035 bp->link_info.force_pause = 0; 1036 } else { 1037 bp->link_info.auto_pause = 0; 1038 bp->link_info.force_pause = 1039 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 1040 } 1041 break; 1042 case RTE_FC_TX_PAUSE: 1043 if (fc_conf->autoneg) { 1044 bp->link_info.auto_pause = 1045 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; 1046 bp->link_info.force_pause = 0; 1047 } else { 1048 bp->link_info.auto_pause = 0; 1049 bp->link_info.force_pause = 1050 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; 1051 } 1052 break; 1053 case RTE_FC_FULL: 1054 if (fc_conf->autoneg) { 1055 bp->link_info.auto_pause = 1056 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX | 1057 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 1058 bp->link_info.force_pause = 0; 1059 } else { 1060 bp->link_info.auto_pause = 0; 1061 bp->link_info.force_pause = 1062 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX | 1063 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 1064 } 1065 break; 1066 } 1067 return bnxt_set_hwrm_link_config(bp, true); 1068 } 1069 1070 /* Add UDP tunneling port */ 1071 static int 1072 bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, 1073 struct rte_eth_udp_tunnel *udp_tunnel) 1074 { 1075 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 1076 uint16_t tunnel_type = 0; 1077 int rc = 0; 1078 1079 switch (udp_tunnel->prot_type) { 1080 case RTE_TUNNEL_TYPE_VXLAN: 1081 if (bp->vxlan_port_cnt) { 1082 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 1083 udp_tunnel->udp_port); 1084 if (bp->vxlan_port != udp_tunnel->udp_port) { 1085 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 1086 return -ENOSPC; 1087 } 1088 bp->vxlan_port_cnt++; 1089 return 0; 1090 } 1091 tunnel_type = 1092 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN; 1093 bp->vxlan_port_cnt++; 1094 break; 1095 case RTE_TUNNEL_TYPE_GENEVE: 1096 if (bp->geneve_port_cnt) { 1097 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 1098 udp_tunnel->udp_port); 1099 if (bp->geneve_port != udp_tunnel->udp_port) { 1100 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 1101 return -ENOSPC; 1102 } 1103 bp->geneve_port_cnt++; 1104 return 0; 1105 } 1106 tunnel_type = 1107 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE; 1108 bp->geneve_port_cnt++; 1109 break; 1110 default: 1111 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 1112 return -ENOTSUP; 1113 } 1114 rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port, 1115 tunnel_type); 1116 return rc; 1117 } 1118 1119 static int 1120 bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev, 1121 struct rte_eth_udp_tunnel *udp_tunnel) 1122 { 1123 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 1124 uint16_t tunnel_type = 0; 1125 uint16_t port = 0; 1126 int rc = 0; 1127 1128 switch (udp_tunnel->prot_type) { 1129 case RTE_TUNNEL_TYPE_VXLAN: 1130 if (!bp->vxlan_port_cnt) { 1131 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 1132 return -EINVAL; 1133 } 1134 if (bp->vxlan_port != udp_tunnel->udp_port) { 1135 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 1136 udp_tunnel->udp_port, bp->vxlan_port); 1137 return -EINVAL; 1138 } 1139 if (--bp->vxlan_port_cnt) 1140 return 0; 1141 1142 tunnel_type = 1143 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN; 1144 port = bp->vxlan_fw_dst_port_id; 1145 break; 1146 case RTE_TUNNEL_TYPE_GENEVE: 1147 if (!bp->geneve_port_cnt) { 1148 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 1149 return -EINVAL; 1150 } 1151 if (bp->geneve_port != udp_tunnel->udp_port) { 1152 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 1153 udp_tunnel->udp_port, bp->geneve_port); 1154 return -EINVAL; 1155 } 1156 if (--bp->geneve_port_cnt) 1157 return 0; 1158 1159 tunnel_type = 1160 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE; 1161 port = bp->geneve_fw_dst_port_id; 1162 break; 1163 default: 1164 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 1165 return -ENOTSUP; 1166 } 1167 1168 rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type); 1169 if (!rc) { 1170 if (tunnel_type == 1171 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN) 1172 bp->vxlan_port = 0; 1173 if (tunnel_type == 1174 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE) 1175 bp->geneve_port = 0; 1176 } 1177 return rc; 1178 } 1179 1180 static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 1181 { 1182 struct bnxt_filter_info *filter, *temp_filter, *new_filter; 1183 struct bnxt_vnic_info *vnic; 1184 unsigned int i; 1185 int rc = 0; 1186 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN; 1187 1188 /* Cycle through all VNICs */ 1189 for (i = 0; i < bp->nr_vnics; i++) { 1190 /* 1191 * For each VNIC and each associated filter(s) 1192 * if VLAN exists && VLAN matches vlan_id 1193 * remove the MAC+VLAN filter 1194 * add a new MAC only filter 1195 * else 1196 * VLAN filter doesn't exist, just skip and continue 1197 */ 1198 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 1199 filter = STAILQ_FIRST(&vnic->filter); 1200 while (filter) { 1201 temp_filter = STAILQ_NEXT(filter, next); 1202 1203 if (filter->enables & chk && 1204 filter->l2_ovlan == vlan_id) { 1205 /* Must delete the filter */ 1206 STAILQ_REMOVE(&vnic->filter, filter, 1207 bnxt_filter_info, next); 1208 bnxt_hwrm_clear_l2_filter(bp, filter); 1209 STAILQ_INSERT_TAIL( 1210 &bp->free_filter_list, 1211 filter, next); 1212 1213 /* 1214 * Need to examine to see if the MAC 1215 * filter already existed or not before 1216 * allocating a new one 1217 */ 1218 1219 new_filter = bnxt_alloc_filter(bp); 1220 if (!new_filter) { 1221 PMD_DRV_LOG(ERR, 1222 "MAC/VLAN filter alloc failed\n"); 1223 rc = -ENOMEM; 1224 goto exit; 1225 } 1226 STAILQ_INSERT_TAIL(&vnic->filter, 1227 new_filter, next); 1228 /* Inherit MAC from previous filter */ 1229 new_filter->mac_index = 1230 filter->mac_index; 1231 memcpy(new_filter->l2_addr, 1232 filter->l2_addr, ETHER_ADDR_LEN); 1233 /* MAC only filter */ 1234 rc = bnxt_hwrm_set_l2_filter(bp, 1235 vnic->fw_vnic_id, 1236 new_filter); 1237 if (rc) 1238 goto exit; 1239 PMD_DRV_LOG(INFO, 1240 "Del Vlan filter for %d\n", 1241 vlan_id); 1242 } 1243 filter = temp_filter; 1244 } 1245 } 1246 } 1247 exit: 1248 return rc; 1249 } 1250 1251 static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 1252 { 1253 struct bnxt_filter_info *filter, *temp_filter, *new_filter; 1254 struct bnxt_vnic_info *vnic; 1255 unsigned int i; 1256 int rc = 0; 1257 uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN | 1258 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK; 1259 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN; 1260 1261 /* Cycle through all VNICs */ 1262 for (i = 0; i < bp->nr_vnics; i++) { 1263 /* 1264 * For each VNIC and each associated filter(s) 1265 * if VLAN exists: 1266 * if VLAN matches vlan_id 1267 * VLAN filter already exists, just skip and continue 1268 * else 1269 * add a new MAC+VLAN filter 1270 * else 1271 * Remove the old MAC only filter 1272 * Add a new MAC+VLAN filter 1273 */ 1274 STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) { 1275 filter = STAILQ_FIRST(&vnic->filter); 1276 while (filter) { 1277 temp_filter = STAILQ_NEXT(filter, next); 1278 1279 if (filter->enables & chk) { 1280 if (filter->l2_ovlan == vlan_id) 1281 goto cont; 1282 } else { 1283 /* Must delete the MAC filter */ 1284 STAILQ_REMOVE(&vnic->filter, filter, 1285 bnxt_filter_info, next); 1286 bnxt_hwrm_clear_l2_filter(bp, filter); 1287 filter->l2_ovlan = 0; 1288 STAILQ_INSERT_TAIL( 1289 &bp->free_filter_list, 1290 filter, next); 1291 } 1292 new_filter = bnxt_alloc_filter(bp); 1293 if (!new_filter) { 1294 PMD_DRV_LOG(ERR, 1295 "MAC/VLAN filter alloc failed\n"); 1296 rc = -ENOMEM; 1297 goto exit; 1298 } 1299 STAILQ_INSERT_TAIL(&vnic->filter, new_filter, 1300 next); 1301 /* Inherit MAC from the previous filter */ 1302 new_filter->mac_index = filter->mac_index; 1303 memcpy(new_filter->l2_addr, filter->l2_addr, 1304 ETHER_ADDR_LEN); 1305 /* MAC + VLAN ID filter */ 1306 new_filter->l2_ovlan = vlan_id; 1307 new_filter->l2_ovlan_mask = 0xF000; 1308 new_filter->enables |= en; 1309 rc = bnxt_hwrm_set_l2_filter(bp, 1310 vnic->fw_vnic_id, 1311 new_filter); 1312 if (rc) 1313 goto exit; 1314 PMD_DRV_LOG(INFO, 1315 "Added Vlan filter for %d\n", vlan_id); 1316 cont: 1317 filter = temp_filter; 1318 } 1319 } 1320 } 1321 exit: 1322 return rc; 1323 } 1324 1325 static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, 1326 uint16_t vlan_id, int on) 1327 { 1328 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 1329 1330 /* These operations apply to ALL existing MAC/VLAN filters */ 1331 if (on) 1332 return bnxt_add_vlan_filter(bp, vlan_id); 1333 else 1334 return bnxt_del_vlan_filter(bp, vlan_id); 1335 } 1336 1337 static int 1338 bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) 1339 { 1340 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1341 unsigned int i; 1342 1343 if (mask & ETH_VLAN_FILTER_MASK) { 1344 if (!dev->data->dev_conf.rxmode.hw_vlan_filter) { 1345 /* Remove any VLAN filters programmed */ 1346 for (i = 0; i < 4095; i++) 1347 bnxt_del_vlan_filter(bp, i); 1348 } 1349 PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n", 1350 dev->data->dev_conf.rxmode.hw_vlan_filter); 1351 } 1352 1353 if (mask & ETH_VLAN_STRIP_MASK) { 1354 /* Enable or disable VLAN stripping */ 1355 for (i = 0; i < bp->nr_vnics; i++) { 1356 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 1357 if (dev->data->dev_conf.rxmode.hw_vlan_strip) 1358 vnic->vlan_strip = true; 1359 else 1360 vnic->vlan_strip = false; 1361 bnxt_hwrm_vnic_cfg(bp, vnic); 1362 } 1363 PMD_DRV_LOG(DEBUG, "VLAN Strip Offload: %d\n", 1364 dev->data->dev_conf.rxmode.hw_vlan_strip); 1365 } 1366 1367 if (mask & ETH_VLAN_EXTEND_MASK) 1368 PMD_DRV_LOG(ERR, "Extend VLAN Not supported\n"); 1369 1370 return 0; 1371 } 1372 1373 static void 1374 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr) 1375 { 1376 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1377 /* Default Filter is tied to VNIC 0 */ 1378 struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; 1379 struct bnxt_filter_info *filter; 1380 int rc; 1381 1382 if (BNXT_VF(bp)) 1383 return; 1384 1385 memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr)); 1386 1387 STAILQ_FOREACH(filter, &vnic->filter, next) { 1388 /* Default Filter is at Index 0 */ 1389 if (filter->mac_index != 0) 1390 continue; 1391 rc = bnxt_hwrm_clear_l2_filter(bp, filter); 1392 if (rc) 1393 break; 1394 memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN); 1395 memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN); 1396 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX; 1397 filter->enables |= 1398 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR | 1399 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK; 1400 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 1401 if (rc) 1402 break; 1403 filter->mac_index = 0; 1404 PMD_DRV_LOG(DEBUG, "Set MAC addr\n"); 1405 } 1406 } 1407 1408 static int 1409 bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, 1410 struct ether_addr *mc_addr_set, 1411 uint32_t nb_mc_addr) 1412 { 1413 struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; 1414 char *mc_addr_list = (char *)mc_addr_set; 1415 struct bnxt_vnic_info *vnic; 1416 uint32_t off = 0, i = 0; 1417 1418 vnic = &bp->vnic_info[0]; 1419 1420 if (nb_mc_addr > BNXT_MAX_MC_ADDRS) { 1421 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 1422 goto allmulti; 1423 } 1424 1425 /* TODO Check for Duplicate mcast addresses */ 1426 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 1427 for (i = 0; i < nb_mc_addr; i++) { 1428 memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN); 1429 off += ETHER_ADDR_LEN; 1430 } 1431 1432 vnic->mc_addr_cnt = i; 1433 1434 allmulti: 1435 return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1436 } 1437 1438 static int 1439 bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) 1440 { 1441 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1442 uint8_t fw_major = (bp->fw_ver >> 24) & 0xff; 1443 uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff; 1444 uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff; 1445 int ret; 1446 1447 ret = snprintf(fw_version, fw_size, "%d.%d.%d", 1448 fw_major, fw_minor, fw_updt); 1449 1450 ret += 1; /* add the size of '\0' */ 1451 if (fw_size < (uint32_t)ret) 1452 return ret; 1453 else 1454 return 0; 1455 } 1456 1457 static void 1458 bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 1459 struct rte_eth_rxq_info *qinfo) 1460 { 1461 struct bnxt_rx_queue *rxq; 1462 1463 rxq = dev->data->rx_queues[queue_id]; 1464 1465 qinfo->mp = rxq->mb_pool; 1466 qinfo->scattered_rx = dev->data->scattered_rx; 1467 qinfo->nb_desc = rxq->nb_rx_desc; 1468 1469 qinfo->conf.rx_free_thresh = rxq->rx_free_thresh; 1470 qinfo->conf.rx_drop_en = 0; 1471 qinfo->conf.rx_deferred_start = 0; 1472 } 1473 1474 static void 1475 bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 1476 struct rte_eth_txq_info *qinfo) 1477 { 1478 struct bnxt_tx_queue *txq; 1479 1480 txq = dev->data->tx_queues[queue_id]; 1481 1482 qinfo->nb_desc = txq->nb_tx_desc; 1483 1484 qinfo->conf.tx_thresh.pthresh = txq->pthresh; 1485 qinfo->conf.tx_thresh.hthresh = txq->hthresh; 1486 qinfo->conf.tx_thresh.wthresh = txq->wthresh; 1487 1488 qinfo->conf.tx_free_thresh = txq->tx_free_thresh; 1489 qinfo->conf.tx_rs_thresh = 0; 1490 qinfo->conf.txq_flags = txq->txq_flags; 1491 qinfo->conf.tx_deferred_start = txq->tx_deferred_start; 1492 } 1493 1494 static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) 1495 { 1496 struct bnxt *bp = eth_dev->data->dev_private; 1497 struct rte_eth_dev_info dev_info; 1498 uint32_t max_dev_mtu; 1499 uint32_t rc = 0; 1500 uint32_t i; 1501 1502 bnxt_dev_info_get_op(eth_dev, &dev_info); 1503 max_dev_mtu = dev_info.max_rx_pktlen - 1504 ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE * 2; 1505 1506 if (new_mtu < ETHER_MIN_MTU || new_mtu > max_dev_mtu) { 1507 PMD_DRV_LOG(ERR, "MTU requested must be within (%d, %d)\n", 1508 ETHER_MIN_MTU, max_dev_mtu); 1509 return -EINVAL; 1510 } 1511 1512 1513 if (new_mtu > ETHER_MTU) { 1514 bp->flags |= BNXT_FLAG_JUMBO; 1515 eth_dev->data->dev_conf.rxmode.jumbo_frame = 1; 1516 } else { 1517 eth_dev->data->dev_conf.rxmode.jumbo_frame = 0; 1518 bp->flags &= ~BNXT_FLAG_JUMBO; 1519 } 1520 1521 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = 1522 new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2; 1523 1524 eth_dev->data->mtu = new_mtu; 1525 PMD_DRV_LOG(INFO, "New MTU is %d\n", eth_dev->data->mtu); 1526 1527 for (i = 0; i < bp->nr_vnics; i++) { 1528 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 1529 1530 vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN + 1531 ETHER_CRC_LEN + VLAN_TAG_SIZE * 2; 1532 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 1533 if (rc) 1534 break; 1535 1536 rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 1537 if (rc) 1538 return rc; 1539 } 1540 1541 return rc; 1542 } 1543 1544 static int 1545 bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on) 1546 { 1547 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1548 uint16_t vlan = bp->vlan; 1549 int rc; 1550 1551 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 1552 PMD_DRV_LOG(ERR, 1553 "PVID cannot be modified for this function\n"); 1554 return -ENOTSUP; 1555 } 1556 bp->vlan = on ? pvid : 0; 1557 1558 rc = bnxt_hwrm_set_default_vlan(bp, 0, 0); 1559 if (rc) 1560 bp->vlan = vlan; 1561 return rc; 1562 } 1563 1564 static int 1565 bnxt_dev_led_on_op(struct rte_eth_dev *dev) 1566 { 1567 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1568 1569 return bnxt_hwrm_port_led_cfg(bp, true); 1570 } 1571 1572 static int 1573 bnxt_dev_led_off_op(struct rte_eth_dev *dev) 1574 { 1575 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1576 1577 return bnxt_hwrm_port_led_cfg(bp, false); 1578 } 1579 1580 static uint32_t 1581 bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) 1582 { 1583 uint32_t desc = 0, raw_cons = 0, cons; 1584 struct bnxt_cp_ring_info *cpr; 1585 struct bnxt_rx_queue *rxq; 1586 struct rx_pkt_cmpl *rxcmp; 1587 uint16_t cmp_type; 1588 uint8_t cmp = 1; 1589 bool valid; 1590 1591 rxq = dev->data->rx_queues[rx_queue_id]; 1592 cpr = rxq->cp_ring; 1593 valid = cpr->valid; 1594 1595 while (raw_cons < rxq->nb_rx_desc) { 1596 cons = RING_CMP(cpr->cp_ring_struct, raw_cons); 1597 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 1598 1599 if (!CMPL_VALID(rxcmp, valid)) 1600 goto nothing_to_do; 1601 valid = FLIP_VALID(cons, cpr->cp_ring_struct->ring_mask, valid); 1602 cmp_type = CMP_TYPE(rxcmp); 1603 if (cmp_type == RX_TPA_END_CMPL_TYPE_RX_TPA_END) { 1604 cmp = (rte_le_to_cpu_32( 1605 ((struct rx_tpa_end_cmpl *) 1606 (rxcmp))->agg_bufs_v1) & 1607 RX_TPA_END_CMPL_AGG_BUFS_MASK) >> 1608 RX_TPA_END_CMPL_AGG_BUFS_SFT; 1609 desc++; 1610 } else if (cmp_type == 0x11) { 1611 desc++; 1612 cmp = (rxcmp->agg_bufs_v1 & 1613 RX_PKT_CMPL_AGG_BUFS_MASK) >> 1614 RX_PKT_CMPL_AGG_BUFS_SFT; 1615 } else { 1616 cmp = 1; 1617 } 1618 nothing_to_do: 1619 raw_cons += cmp ? cmp : 2; 1620 } 1621 1622 return desc; 1623 } 1624 1625 static int 1626 bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset) 1627 { 1628 struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue; 1629 struct bnxt_rx_ring_info *rxr; 1630 struct bnxt_cp_ring_info *cpr; 1631 struct bnxt_sw_rx_bd *rx_buf; 1632 struct rx_pkt_cmpl *rxcmp; 1633 uint32_t cons, cp_cons; 1634 1635 if (!rxq) 1636 return -EINVAL; 1637 1638 cpr = rxq->cp_ring; 1639 rxr = rxq->rx_ring; 1640 1641 if (offset >= rxq->nb_rx_desc) 1642 return -EINVAL; 1643 1644 cons = RING_CMP(cpr->cp_ring_struct, offset); 1645 cp_cons = cpr->cp_raw_cons; 1646 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 1647 1648 if (cons > cp_cons) { 1649 if (CMPL_VALID(rxcmp, cpr->valid)) 1650 return RTE_ETH_RX_DESC_DONE; 1651 } else { 1652 if (CMPL_VALID(rxcmp, !cpr->valid)) 1653 return RTE_ETH_RX_DESC_DONE; 1654 } 1655 rx_buf = &rxr->rx_buf_ring[cons]; 1656 if (rx_buf->mbuf == NULL) 1657 return RTE_ETH_RX_DESC_UNAVAIL; 1658 1659 1660 return RTE_ETH_RX_DESC_AVAIL; 1661 } 1662 1663 static int 1664 bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset) 1665 { 1666 struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; 1667 struct bnxt_tx_ring_info *txr; 1668 struct bnxt_cp_ring_info *cpr; 1669 struct bnxt_sw_tx_bd *tx_buf; 1670 struct tx_pkt_cmpl *txcmp; 1671 uint32_t cons, cp_cons; 1672 1673 if (!txq) 1674 return -EINVAL; 1675 1676 cpr = txq->cp_ring; 1677 txr = txq->tx_ring; 1678 1679 if (offset >= txq->nb_tx_desc) 1680 return -EINVAL; 1681 1682 cons = RING_CMP(cpr->cp_ring_struct, offset); 1683 txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 1684 cp_cons = cpr->cp_raw_cons; 1685 1686 if (cons > cp_cons) { 1687 if (CMPL_VALID(txcmp, cpr->valid)) 1688 return RTE_ETH_TX_DESC_UNAVAIL; 1689 } else { 1690 if (CMPL_VALID(txcmp, !cpr->valid)) 1691 return RTE_ETH_TX_DESC_UNAVAIL; 1692 } 1693 tx_buf = &txr->tx_buf_ring[cons]; 1694 if (tx_buf->mbuf == NULL) 1695 return RTE_ETH_TX_DESC_DONE; 1696 1697 return RTE_ETH_TX_DESC_FULL; 1698 } 1699 1700 static struct bnxt_filter_info * 1701 bnxt_match_and_validate_ether_filter(struct bnxt *bp, 1702 struct rte_eth_ethertype_filter *efilter, 1703 struct bnxt_vnic_info *vnic0, 1704 struct bnxt_vnic_info *vnic, 1705 int *ret) 1706 { 1707 struct bnxt_filter_info *mfilter = NULL; 1708 int match = 0; 1709 *ret = 0; 1710 1711 if (efilter->ether_type == ETHER_TYPE_IPv4 || 1712 efilter->ether_type == ETHER_TYPE_IPv6) { 1713 PMD_DRV_LOG(ERR, "invalid ether_type(0x%04x) in" 1714 " ethertype filter.", efilter->ether_type); 1715 *ret = -EINVAL; 1716 goto exit; 1717 } 1718 if (efilter->queue >= bp->rx_nr_rings) { 1719 PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue); 1720 *ret = -EINVAL; 1721 goto exit; 1722 } 1723 1724 vnic0 = STAILQ_FIRST(&bp->ff_pool[0]); 1725 vnic = STAILQ_FIRST(&bp->ff_pool[efilter->queue]); 1726 if (vnic == NULL) { 1727 PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue); 1728 *ret = -EINVAL; 1729 goto exit; 1730 } 1731 1732 if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) { 1733 STAILQ_FOREACH(mfilter, &vnic0->filter, next) { 1734 if ((!memcmp(efilter->mac_addr.addr_bytes, 1735 mfilter->l2_addr, ETHER_ADDR_LEN) && 1736 mfilter->flags == 1737 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP && 1738 mfilter->ethertype == efilter->ether_type)) { 1739 match = 1; 1740 break; 1741 } 1742 } 1743 } else { 1744 STAILQ_FOREACH(mfilter, &vnic->filter, next) 1745 if ((!memcmp(efilter->mac_addr.addr_bytes, 1746 mfilter->l2_addr, ETHER_ADDR_LEN) && 1747 mfilter->ethertype == efilter->ether_type && 1748 mfilter->flags == 1749 HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX)) { 1750 match = 1; 1751 break; 1752 } 1753 } 1754 1755 if (match) 1756 *ret = -EEXIST; 1757 1758 exit: 1759 return mfilter; 1760 } 1761 1762 static int 1763 bnxt_ethertype_filter(struct rte_eth_dev *dev, 1764 enum rte_filter_op filter_op, 1765 void *arg) 1766 { 1767 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 1768 struct rte_eth_ethertype_filter *efilter = 1769 (struct rte_eth_ethertype_filter *)arg; 1770 struct bnxt_filter_info *bfilter, *filter1; 1771 struct bnxt_vnic_info *vnic, *vnic0; 1772 int ret; 1773 1774 if (filter_op == RTE_ETH_FILTER_NOP) 1775 return 0; 1776 1777 if (arg == NULL) { 1778 PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.", 1779 filter_op); 1780 return -EINVAL; 1781 } 1782 1783 vnic0 = STAILQ_FIRST(&bp->ff_pool[0]); 1784 vnic = STAILQ_FIRST(&bp->ff_pool[efilter->queue]); 1785 1786 switch (filter_op) { 1787 case RTE_ETH_FILTER_ADD: 1788 bnxt_match_and_validate_ether_filter(bp, efilter, 1789 vnic0, vnic, &ret); 1790 if (ret < 0) 1791 return ret; 1792 1793 bfilter = bnxt_get_unused_filter(bp); 1794 if (bfilter == NULL) { 1795 PMD_DRV_LOG(ERR, 1796 "Not enough resources for a new filter.\n"); 1797 return -ENOMEM; 1798 } 1799 bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER; 1800 memcpy(bfilter->l2_addr, efilter->mac_addr.addr_bytes, 1801 ETHER_ADDR_LEN); 1802 memcpy(bfilter->dst_macaddr, efilter->mac_addr.addr_bytes, 1803 ETHER_ADDR_LEN); 1804 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR; 1805 bfilter->ethertype = efilter->ether_type; 1806 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 1807 1808 filter1 = bnxt_get_l2_filter(bp, bfilter, vnic0); 1809 if (filter1 == NULL) { 1810 ret = -1; 1811 goto cleanup; 1812 } 1813 bfilter->enables |= 1814 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 1815 bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id; 1816 1817 bfilter->dst_id = vnic->fw_vnic_id; 1818 1819 if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) { 1820 bfilter->flags = 1821 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP; 1822 } 1823 1824 ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter); 1825 if (ret) 1826 goto cleanup; 1827 STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next); 1828 break; 1829 case RTE_ETH_FILTER_DELETE: 1830 filter1 = bnxt_match_and_validate_ether_filter(bp, efilter, 1831 vnic0, vnic, &ret); 1832 if (ret == -EEXIST) { 1833 ret = bnxt_hwrm_clear_ntuple_filter(bp, filter1); 1834 1835 STAILQ_REMOVE(&vnic->filter, filter1, bnxt_filter_info, 1836 next); 1837 bnxt_free_filter(bp, filter1); 1838 } else if (ret == 0) { 1839 PMD_DRV_LOG(ERR, "No matching filter found\n"); 1840 } 1841 break; 1842 default: 1843 PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op); 1844 ret = -EINVAL; 1845 goto error; 1846 } 1847 return ret; 1848 cleanup: 1849 bnxt_free_filter(bp, bfilter); 1850 error: 1851 return ret; 1852 } 1853 1854 static inline int 1855 parse_ntuple_filter(struct bnxt *bp, 1856 struct rte_eth_ntuple_filter *nfilter, 1857 struct bnxt_filter_info *bfilter) 1858 { 1859 uint32_t en = 0; 1860 1861 if (nfilter->queue >= bp->rx_nr_rings) { 1862 PMD_DRV_LOG(ERR, "Invalid queue %d\n", nfilter->queue); 1863 return -EINVAL; 1864 } 1865 1866 switch (nfilter->dst_port_mask) { 1867 case UINT16_MAX: 1868 bfilter->dst_port_mask = -1; 1869 bfilter->dst_port = nfilter->dst_port; 1870 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT | 1871 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 1872 break; 1873 default: 1874 PMD_DRV_LOG(ERR, "invalid dst_port mask."); 1875 return -EINVAL; 1876 } 1877 1878 bfilter->ip_addr_type = NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 1879 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 1880 1881 switch (nfilter->proto_mask) { 1882 case UINT8_MAX: 1883 if (nfilter->proto == 17) /* IPPROTO_UDP */ 1884 bfilter->ip_protocol = 17; 1885 else if (nfilter->proto == 6) /* IPPROTO_TCP */ 1886 bfilter->ip_protocol = 6; 1887 else 1888 return -EINVAL; 1889 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 1890 break; 1891 default: 1892 PMD_DRV_LOG(ERR, "invalid protocol mask."); 1893 return -EINVAL; 1894 } 1895 1896 switch (nfilter->dst_ip_mask) { 1897 case UINT32_MAX: 1898 bfilter->dst_ipaddr_mask[0] = -1; 1899 bfilter->dst_ipaddr[0] = nfilter->dst_ip; 1900 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR | 1901 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 1902 break; 1903 default: 1904 PMD_DRV_LOG(ERR, "invalid dst_ip mask."); 1905 return -EINVAL; 1906 } 1907 1908 switch (nfilter->src_ip_mask) { 1909 case UINT32_MAX: 1910 bfilter->src_ipaddr_mask[0] = -1; 1911 bfilter->src_ipaddr[0] = nfilter->src_ip; 1912 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR | 1913 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 1914 break; 1915 default: 1916 PMD_DRV_LOG(ERR, "invalid src_ip mask."); 1917 return -EINVAL; 1918 } 1919 1920 switch (nfilter->src_port_mask) { 1921 case UINT16_MAX: 1922 bfilter->src_port_mask = -1; 1923 bfilter->src_port = nfilter->src_port; 1924 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT | 1925 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 1926 break; 1927 default: 1928 PMD_DRV_LOG(ERR, "invalid src_port mask."); 1929 return -EINVAL; 1930 } 1931 1932 //TODO Priority 1933 //nfilter->priority = (uint8_t)filter->priority; 1934 1935 bfilter->enables = en; 1936 return 0; 1937 } 1938 1939 static struct bnxt_filter_info* 1940 bnxt_match_ntuple_filter(struct bnxt *bp, 1941 struct bnxt_filter_info *bfilter, 1942 struct bnxt_vnic_info **mvnic) 1943 { 1944 struct bnxt_filter_info *mfilter = NULL; 1945 int i; 1946 1947 for (i = bp->nr_vnics - 1; i >= 0; i--) { 1948 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 1949 STAILQ_FOREACH(mfilter, &vnic->filter, next) { 1950 if (bfilter->src_ipaddr[0] == mfilter->src_ipaddr[0] && 1951 bfilter->src_ipaddr_mask[0] == 1952 mfilter->src_ipaddr_mask[0] && 1953 bfilter->src_port == mfilter->src_port && 1954 bfilter->src_port_mask == mfilter->src_port_mask && 1955 bfilter->dst_ipaddr[0] == mfilter->dst_ipaddr[0] && 1956 bfilter->dst_ipaddr_mask[0] == 1957 mfilter->dst_ipaddr_mask[0] && 1958 bfilter->dst_port == mfilter->dst_port && 1959 bfilter->dst_port_mask == mfilter->dst_port_mask && 1960 bfilter->flags == mfilter->flags && 1961 bfilter->enables == mfilter->enables) { 1962 if (mvnic) 1963 *mvnic = vnic; 1964 return mfilter; 1965 } 1966 } 1967 } 1968 return NULL; 1969 } 1970 1971 static int 1972 bnxt_cfg_ntuple_filter(struct bnxt *bp, 1973 struct rte_eth_ntuple_filter *nfilter, 1974 enum rte_filter_op filter_op) 1975 { 1976 struct bnxt_filter_info *bfilter, *mfilter, *filter1; 1977 struct bnxt_vnic_info *vnic, *vnic0, *mvnic; 1978 int ret; 1979 1980 if (nfilter->flags != RTE_5TUPLE_FLAGS) { 1981 PMD_DRV_LOG(ERR, "only 5tuple is supported."); 1982 return -EINVAL; 1983 } 1984 1985 if (nfilter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) { 1986 PMD_DRV_LOG(ERR, "Ntuple filter: TCP flags not supported\n"); 1987 return -EINVAL; 1988 } 1989 1990 bfilter = bnxt_get_unused_filter(bp); 1991 if (bfilter == NULL) { 1992 PMD_DRV_LOG(ERR, 1993 "Not enough resources for a new filter.\n"); 1994 return -ENOMEM; 1995 } 1996 ret = parse_ntuple_filter(bp, nfilter, bfilter); 1997 if (ret < 0) 1998 goto free_filter; 1999 2000 vnic = STAILQ_FIRST(&bp->ff_pool[nfilter->queue]); 2001 vnic0 = STAILQ_FIRST(&bp->ff_pool[0]); 2002 filter1 = STAILQ_FIRST(&vnic0->filter); 2003 if (filter1 == NULL) { 2004 ret = -1; 2005 goto free_filter; 2006 } 2007 2008 bfilter->dst_id = vnic->fw_vnic_id; 2009 bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id; 2010 bfilter->enables |= 2011 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 2012 bfilter->ethertype = 0x800; 2013 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2014 2015 mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic); 2016 2017 if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD && 2018 bfilter->dst_id == mfilter->dst_id) { 2019 PMD_DRV_LOG(ERR, "filter exists.\n"); 2020 ret = -EEXIST; 2021 goto free_filter; 2022 } else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD && 2023 bfilter->dst_id != mfilter->dst_id) { 2024 mfilter->dst_id = vnic->fw_vnic_id; 2025 ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter); 2026 STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next); 2027 STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next); 2028 PMD_DRV_LOG(ERR, "filter with matching pattern exists.\n"); 2029 PMD_DRV_LOG(ERR, " Updated it to the new destination queue\n"); 2030 goto free_filter; 2031 } 2032 if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) { 2033 PMD_DRV_LOG(ERR, "filter doesn't exist."); 2034 ret = -ENOENT; 2035 goto free_filter; 2036 } 2037 2038 if (filter_op == RTE_ETH_FILTER_ADD) { 2039 bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER; 2040 ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter); 2041 if (ret) 2042 goto free_filter; 2043 STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next); 2044 } else { 2045 if (mfilter == NULL) { 2046 /* This should not happen. But for Coverity! */ 2047 ret = -ENOENT; 2048 goto free_filter; 2049 } 2050 ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter); 2051 2052 STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next); 2053 bnxt_free_filter(bp, mfilter); 2054 mfilter->fw_l2_filter_id = -1; 2055 bnxt_free_filter(bp, bfilter); 2056 bfilter->fw_l2_filter_id = -1; 2057 } 2058 2059 return 0; 2060 free_filter: 2061 bfilter->fw_l2_filter_id = -1; 2062 bnxt_free_filter(bp, bfilter); 2063 return ret; 2064 } 2065 2066 static int 2067 bnxt_ntuple_filter(struct rte_eth_dev *dev, 2068 enum rte_filter_op filter_op, 2069 void *arg) 2070 { 2071 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2072 int ret; 2073 2074 if (filter_op == RTE_ETH_FILTER_NOP) 2075 return 0; 2076 2077 if (arg == NULL) { 2078 PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.", 2079 filter_op); 2080 return -EINVAL; 2081 } 2082 2083 switch (filter_op) { 2084 case RTE_ETH_FILTER_ADD: 2085 ret = bnxt_cfg_ntuple_filter(bp, 2086 (struct rte_eth_ntuple_filter *)arg, 2087 filter_op); 2088 break; 2089 case RTE_ETH_FILTER_DELETE: 2090 ret = bnxt_cfg_ntuple_filter(bp, 2091 (struct rte_eth_ntuple_filter *)arg, 2092 filter_op); 2093 break; 2094 default: 2095 PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op); 2096 ret = -EINVAL; 2097 break; 2098 } 2099 return ret; 2100 } 2101 2102 static int 2103 bnxt_parse_fdir_filter(struct bnxt *bp, 2104 struct rte_eth_fdir_filter *fdir, 2105 struct bnxt_filter_info *filter) 2106 { 2107 enum rte_fdir_mode fdir_mode = 2108 bp->eth_dev->data->dev_conf.fdir_conf.mode; 2109 struct bnxt_vnic_info *vnic0, *vnic; 2110 struct bnxt_filter_info *filter1; 2111 uint32_t en = 0; 2112 int i; 2113 2114 if (fdir_mode == RTE_FDIR_MODE_PERFECT_TUNNEL) 2115 return -EINVAL; 2116 2117 filter->l2_ovlan = fdir->input.flow_ext.vlan_tci; 2118 en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID; 2119 2120 switch (fdir->input.flow_type) { 2121 case RTE_ETH_FLOW_IPV4: 2122 case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: 2123 /* FALLTHROUGH */ 2124 filter->src_ipaddr[0] = fdir->input.flow.ip4_flow.src_ip; 2125 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2126 filter->dst_ipaddr[0] = fdir->input.flow.ip4_flow.dst_ip; 2127 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2128 filter->ip_protocol = fdir->input.flow.ip4_flow.proto; 2129 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2130 filter->ip_addr_type = 2131 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 2132 filter->src_ipaddr_mask[0] = 0xffffffff; 2133 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2134 filter->dst_ipaddr_mask[0] = 0xffffffff; 2135 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2136 filter->ethertype = 0x800; 2137 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2138 break; 2139 case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: 2140 filter->src_port = fdir->input.flow.tcp4_flow.src_port; 2141 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 2142 filter->dst_port = fdir->input.flow.tcp4_flow.dst_port; 2143 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 2144 filter->dst_port_mask = 0xffff; 2145 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 2146 filter->src_port_mask = 0xffff; 2147 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 2148 filter->src_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.src_ip; 2149 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2150 filter->dst_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.dst_ip; 2151 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2152 filter->ip_protocol = 6; 2153 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2154 filter->ip_addr_type = 2155 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 2156 filter->src_ipaddr_mask[0] = 0xffffffff; 2157 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2158 filter->dst_ipaddr_mask[0] = 0xffffffff; 2159 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2160 filter->ethertype = 0x800; 2161 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2162 break; 2163 case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: 2164 filter->src_port = fdir->input.flow.udp4_flow.src_port; 2165 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 2166 filter->dst_port = fdir->input.flow.udp4_flow.dst_port; 2167 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 2168 filter->dst_port_mask = 0xffff; 2169 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 2170 filter->src_port_mask = 0xffff; 2171 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 2172 filter->src_ipaddr[0] = fdir->input.flow.udp4_flow.ip.src_ip; 2173 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2174 filter->dst_ipaddr[0] = fdir->input.flow.udp4_flow.ip.dst_ip; 2175 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2176 filter->ip_protocol = 17; 2177 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2178 filter->ip_addr_type = 2179 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 2180 filter->src_ipaddr_mask[0] = 0xffffffff; 2181 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2182 filter->dst_ipaddr_mask[0] = 0xffffffff; 2183 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2184 filter->ethertype = 0x800; 2185 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2186 break; 2187 case RTE_ETH_FLOW_IPV6: 2188 case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: 2189 /* FALLTHROUGH */ 2190 filter->ip_addr_type = 2191 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 2192 filter->ip_protocol = fdir->input.flow.ipv6_flow.proto; 2193 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2194 rte_memcpy(filter->src_ipaddr, 2195 fdir->input.flow.ipv6_flow.src_ip, 16); 2196 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2197 rte_memcpy(filter->dst_ipaddr, 2198 fdir->input.flow.ipv6_flow.dst_ip, 16); 2199 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2200 memset(filter->dst_ipaddr_mask, 0xff, 16); 2201 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2202 memset(filter->src_ipaddr_mask, 0xff, 16); 2203 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2204 filter->ethertype = 0x86dd; 2205 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2206 break; 2207 case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: 2208 filter->src_port = fdir->input.flow.tcp6_flow.src_port; 2209 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 2210 filter->dst_port = fdir->input.flow.tcp6_flow.dst_port; 2211 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 2212 filter->dst_port_mask = 0xffff; 2213 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 2214 filter->src_port_mask = 0xffff; 2215 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 2216 filter->ip_addr_type = 2217 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 2218 filter->ip_protocol = fdir->input.flow.tcp6_flow.ip.proto; 2219 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2220 rte_memcpy(filter->src_ipaddr, 2221 fdir->input.flow.tcp6_flow.ip.src_ip, 16); 2222 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2223 rte_memcpy(filter->dst_ipaddr, 2224 fdir->input.flow.tcp6_flow.ip.dst_ip, 16); 2225 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2226 memset(filter->dst_ipaddr_mask, 0xff, 16); 2227 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2228 memset(filter->src_ipaddr_mask, 0xff, 16); 2229 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2230 filter->ethertype = 0x86dd; 2231 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2232 break; 2233 case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: 2234 filter->src_port = fdir->input.flow.udp6_flow.src_port; 2235 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 2236 filter->dst_port = fdir->input.flow.udp6_flow.dst_port; 2237 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 2238 filter->dst_port_mask = 0xffff; 2239 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 2240 filter->src_port_mask = 0xffff; 2241 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 2242 filter->ip_addr_type = 2243 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 2244 filter->ip_protocol = fdir->input.flow.udp6_flow.ip.proto; 2245 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 2246 rte_memcpy(filter->src_ipaddr, 2247 fdir->input.flow.udp6_flow.ip.src_ip, 16); 2248 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 2249 rte_memcpy(filter->dst_ipaddr, 2250 fdir->input.flow.udp6_flow.ip.dst_ip, 16); 2251 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 2252 memset(filter->dst_ipaddr_mask, 0xff, 16); 2253 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 2254 memset(filter->src_ipaddr_mask, 0xff, 16); 2255 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 2256 filter->ethertype = 0x86dd; 2257 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2258 break; 2259 case RTE_ETH_FLOW_L2_PAYLOAD: 2260 filter->ethertype = fdir->input.flow.l2_flow.ether_type; 2261 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2262 break; 2263 case RTE_ETH_FLOW_VXLAN: 2264 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 2265 return -EINVAL; 2266 filter->vni = fdir->input.flow.tunnel_flow.tunnel_id; 2267 filter->tunnel_type = 2268 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN; 2269 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE; 2270 break; 2271 case RTE_ETH_FLOW_NVGRE: 2272 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 2273 return -EINVAL; 2274 filter->vni = fdir->input.flow.tunnel_flow.tunnel_id; 2275 filter->tunnel_type = 2276 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE; 2277 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE; 2278 break; 2279 case RTE_ETH_FLOW_UNKNOWN: 2280 case RTE_ETH_FLOW_RAW: 2281 case RTE_ETH_FLOW_FRAG_IPV4: 2282 case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: 2283 case RTE_ETH_FLOW_FRAG_IPV6: 2284 case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: 2285 case RTE_ETH_FLOW_IPV6_EX: 2286 case RTE_ETH_FLOW_IPV6_TCP_EX: 2287 case RTE_ETH_FLOW_IPV6_UDP_EX: 2288 case RTE_ETH_FLOW_GENEVE: 2289 /* FALLTHROUGH */ 2290 default: 2291 return -EINVAL; 2292 } 2293 2294 vnic0 = STAILQ_FIRST(&bp->ff_pool[0]); 2295 vnic = STAILQ_FIRST(&bp->ff_pool[fdir->action.rx_queue]); 2296 if (vnic == NULL) { 2297 PMD_DRV_LOG(ERR, "Invalid queue %d\n", fdir->action.rx_queue); 2298 return -EINVAL; 2299 } 2300 2301 2302 if (fdir_mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) { 2303 rte_memcpy(filter->dst_macaddr, 2304 fdir->input.flow.mac_vlan_flow.mac_addr.addr_bytes, 6); 2305 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR; 2306 } 2307 2308 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) { 2309 filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP; 2310 filter1 = STAILQ_FIRST(&vnic0->filter); 2311 //filter1 = bnxt_get_l2_filter(bp, filter, vnic0); 2312 } else { 2313 filter->dst_id = vnic->fw_vnic_id; 2314 for (i = 0; i < ETHER_ADDR_LEN; i++) 2315 if (filter->dst_macaddr[i] == 0x00) 2316 filter1 = STAILQ_FIRST(&vnic0->filter); 2317 else 2318 filter1 = bnxt_get_l2_filter(bp, filter, vnic); 2319 } 2320 2321 if (filter1 == NULL) 2322 return -EINVAL; 2323 2324 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 2325 filter->fw_l2_filter_id = filter1->fw_l2_filter_id; 2326 2327 filter->enables = en; 2328 2329 return 0; 2330 } 2331 2332 static struct bnxt_filter_info * 2333 bnxt_match_fdir(struct bnxt *bp, struct bnxt_filter_info *nf, 2334 struct bnxt_vnic_info **mvnic) 2335 { 2336 struct bnxt_filter_info *mf = NULL; 2337 int i; 2338 2339 for (i = bp->nr_vnics - 1; i >= 0; i--) { 2340 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 2341 2342 STAILQ_FOREACH(mf, &vnic->filter, next) { 2343 if (mf->filter_type == nf->filter_type && 2344 mf->flags == nf->flags && 2345 mf->src_port == nf->src_port && 2346 mf->src_port_mask == nf->src_port_mask && 2347 mf->dst_port == nf->dst_port && 2348 mf->dst_port_mask == nf->dst_port_mask && 2349 mf->ip_protocol == nf->ip_protocol && 2350 mf->ip_addr_type == nf->ip_addr_type && 2351 mf->ethertype == nf->ethertype && 2352 mf->vni == nf->vni && 2353 mf->tunnel_type == nf->tunnel_type && 2354 mf->l2_ovlan == nf->l2_ovlan && 2355 mf->l2_ovlan_mask == nf->l2_ovlan_mask && 2356 mf->l2_ivlan == nf->l2_ivlan && 2357 mf->l2_ivlan_mask == nf->l2_ivlan_mask && 2358 !memcmp(mf->l2_addr, nf->l2_addr, ETHER_ADDR_LEN) && 2359 !memcmp(mf->l2_addr_mask, nf->l2_addr_mask, 2360 ETHER_ADDR_LEN) && 2361 !memcmp(mf->src_macaddr, nf->src_macaddr, 2362 ETHER_ADDR_LEN) && 2363 !memcmp(mf->dst_macaddr, nf->dst_macaddr, 2364 ETHER_ADDR_LEN) && 2365 !memcmp(mf->src_ipaddr, nf->src_ipaddr, 2366 sizeof(nf->src_ipaddr)) && 2367 !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask, 2368 sizeof(nf->src_ipaddr_mask)) && 2369 !memcmp(mf->dst_ipaddr, nf->dst_ipaddr, 2370 sizeof(nf->dst_ipaddr)) && 2371 !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask, 2372 sizeof(nf->dst_ipaddr_mask))) { 2373 if (mvnic) 2374 *mvnic = vnic; 2375 return mf; 2376 } 2377 } 2378 } 2379 return NULL; 2380 } 2381 2382 static int 2383 bnxt_fdir_filter(struct rte_eth_dev *dev, 2384 enum rte_filter_op filter_op, 2385 void *arg) 2386 { 2387 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2388 struct rte_eth_fdir_filter *fdir = (struct rte_eth_fdir_filter *)arg; 2389 struct bnxt_filter_info *filter, *match; 2390 struct bnxt_vnic_info *vnic, *mvnic; 2391 int ret = 0, i; 2392 2393 if (filter_op == RTE_ETH_FILTER_NOP) 2394 return 0; 2395 2396 if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH) 2397 return -EINVAL; 2398 2399 switch (filter_op) { 2400 case RTE_ETH_FILTER_ADD: 2401 case RTE_ETH_FILTER_DELETE: 2402 filter = bnxt_get_unused_filter(bp); 2403 if (filter == NULL) { 2404 PMD_DRV_LOG(ERR, 2405 "Not enough resources for a new flow.\n"); 2406 return -ENOMEM; 2407 } 2408 2409 ret = bnxt_parse_fdir_filter(bp, fdir, filter); 2410 if (ret != 0) 2411 goto free_filter; 2412 filter->filter_type = HWRM_CFA_NTUPLE_FILTER; 2413 2414 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 2415 vnic = STAILQ_FIRST(&bp->ff_pool[0]); 2416 else 2417 vnic = STAILQ_FIRST(&bp->ff_pool[fdir->action.rx_queue]); 2418 2419 match = bnxt_match_fdir(bp, filter, &mvnic); 2420 if (match != NULL && filter_op == RTE_ETH_FILTER_ADD) { 2421 if (match->dst_id == vnic->fw_vnic_id) { 2422 PMD_DRV_LOG(ERR, "Flow already exists.\n"); 2423 ret = -EEXIST; 2424 goto free_filter; 2425 } else { 2426 match->dst_id = vnic->fw_vnic_id; 2427 ret = bnxt_hwrm_set_ntuple_filter(bp, 2428 match->dst_id, 2429 match); 2430 STAILQ_REMOVE(&mvnic->filter, match, 2431 bnxt_filter_info, next); 2432 STAILQ_INSERT_TAIL(&vnic->filter, match, next); 2433 PMD_DRV_LOG(ERR, 2434 "Filter with matching pattern exist\n"); 2435 PMD_DRV_LOG(ERR, 2436 "Updated it to new destination q\n"); 2437 goto free_filter; 2438 } 2439 } 2440 if (match == NULL && filter_op == RTE_ETH_FILTER_DELETE) { 2441 PMD_DRV_LOG(ERR, "Flow does not exist.\n"); 2442 ret = -ENOENT; 2443 goto free_filter; 2444 } 2445 2446 if (filter_op == RTE_ETH_FILTER_ADD) { 2447 ret = bnxt_hwrm_set_ntuple_filter(bp, 2448 filter->dst_id, 2449 filter); 2450 if (ret) 2451 goto free_filter; 2452 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 2453 } else { 2454 ret = bnxt_hwrm_clear_ntuple_filter(bp, match); 2455 STAILQ_REMOVE(&vnic->filter, match, 2456 bnxt_filter_info, next); 2457 bnxt_free_filter(bp, match); 2458 filter->fw_l2_filter_id = -1; 2459 bnxt_free_filter(bp, filter); 2460 } 2461 break; 2462 case RTE_ETH_FILTER_FLUSH: 2463 for (i = bp->nr_vnics - 1; i >= 0; i--) { 2464 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 2465 2466 STAILQ_FOREACH(filter, &vnic->filter, next) { 2467 if (filter->filter_type == 2468 HWRM_CFA_NTUPLE_FILTER) { 2469 ret = 2470 bnxt_hwrm_clear_ntuple_filter(bp, 2471 filter); 2472 STAILQ_REMOVE(&vnic->filter, filter, 2473 bnxt_filter_info, next); 2474 } 2475 } 2476 } 2477 return ret; 2478 case RTE_ETH_FILTER_UPDATE: 2479 case RTE_ETH_FILTER_STATS: 2480 case RTE_ETH_FILTER_INFO: 2481 PMD_DRV_LOG(ERR, "operation %u not implemented", filter_op); 2482 break; 2483 default: 2484 PMD_DRV_LOG(ERR, "unknown operation %u", filter_op); 2485 ret = -EINVAL; 2486 break; 2487 } 2488 return ret; 2489 2490 free_filter: 2491 filter->fw_l2_filter_id = -1; 2492 bnxt_free_filter(bp, filter); 2493 return ret; 2494 } 2495 2496 static int 2497 bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused, 2498 enum rte_filter_type filter_type, 2499 enum rte_filter_op filter_op, void *arg) 2500 { 2501 int ret = 0; 2502 2503 switch (filter_type) { 2504 case RTE_ETH_FILTER_TUNNEL: 2505 PMD_DRV_LOG(ERR, 2506 "filter type: %d: To be implemented\n", filter_type); 2507 break; 2508 case RTE_ETH_FILTER_FDIR: 2509 ret = bnxt_fdir_filter(dev, filter_op, arg); 2510 break; 2511 case RTE_ETH_FILTER_NTUPLE: 2512 ret = bnxt_ntuple_filter(dev, filter_op, arg); 2513 break; 2514 case RTE_ETH_FILTER_ETHERTYPE: 2515 ret = bnxt_ethertype_filter(dev, filter_op, arg); 2516 break; 2517 case RTE_ETH_FILTER_GENERIC: 2518 if (filter_op != RTE_ETH_FILTER_GET) 2519 return -EINVAL; 2520 *(const void **)arg = &bnxt_flow_ops; 2521 break; 2522 default: 2523 PMD_DRV_LOG(ERR, 2524 "Filter type (%d) not supported", filter_type); 2525 ret = -EINVAL; 2526 break; 2527 } 2528 return ret; 2529 } 2530 2531 static const uint32_t * 2532 bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev) 2533 { 2534 static const uint32_t ptypes[] = { 2535 RTE_PTYPE_L2_ETHER_VLAN, 2536 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 2537 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 2538 RTE_PTYPE_L4_ICMP, 2539 RTE_PTYPE_L4_TCP, 2540 RTE_PTYPE_L4_UDP, 2541 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 2542 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 2543 RTE_PTYPE_INNER_L4_ICMP, 2544 RTE_PTYPE_INNER_L4_TCP, 2545 RTE_PTYPE_INNER_L4_UDP, 2546 RTE_PTYPE_UNKNOWN 2547 }; 2548 2549 if (dev->rx_pkt_burst == bnxt_recv_pkts) 2550 return ptypes; 2551 return NULL; 2552 } 2553 2554 static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count, 2555 int reg_win) 2556 { 2557 uint32_t reg_base = *reg_arr & 0xfffff000; 2558 uint32_t win_off; 2559 int i; 2560 2561 for (i = 0; i < count; i++) { 2562 if ((reg_arr[i] & 0xfffff000) != reg_base) 2563 return -ERANGE; 2564 } 2565 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4; 2566 rte_cpu_to_le_32(rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off)); 2567 return 0; 2568 } 2569 2570 static int bnxt_map_ptp_regs(struct bnxt *bp) 2571 { 2572 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2573 uint32_t *reg_arr; 2574 int rc, i; 2575 2576 reg_arr = ptp->rx_regs; 2577 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5); 2578 if (rc) 2579 return rc; 2580 2581 reg_arr = ptp->tx_regs; 2582 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6); 2583 if (rc) 2584 return rc; 2585 2586 for (i = 0; i < BNXT_PTP_RX_REGS; i++) 2587 ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff); 2588 2589 for (i = 0; i < BNXT_PTP_TX_REGS; i++) 2590 ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff); 2591 2592 return 0; 2593 } 2594 2595 static void bnxt_unmap_ptp_regs(struct bnxt *bp) 2596 { 2597 rte_cpu_to_le_32(rte_write32(0, (uint8_t *)bp->bar0 + 2598 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16)); 2599 rte_cpu_to_le_32(rte_write32(0, (uint8_t *)bp->bar0 + 2600 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20)); 2601 } 2602 2603 static uint64_t bnxt_cc_read(struct bnxt *bp) 2604 { 2605 uint64_t ns; 2606 2607 ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2608 BNXT_GRCPF_REG_SYNC_TIME)); 2609 ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2610 BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32; 2611 return ns; 2612 } 2613 2614 static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts) 2615 { 2616 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2617 uint32_t fifo; 2618 2619 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2620 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 2621 if (fifo & BNXT_PTP_TX_FIFO_EMPTY) 2622 return -EAGAIN; 2623 2624 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2625 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 2626 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2627 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L])); 2628 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2629 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32; 2630 2631 return 0; 2632 } 2633 2634 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) 2635 { 2636 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2637 struct bnxt_pf_info *pf = &bp->pf; 2638 uint16_t port_id; 2639 uint32_t fifo; 2640 2641 if (!ptp) 2642 return -ENODEV; 2643 2644 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2645 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 2646 if (!(fifo & BNXT_PTP_RX_FIFO_PENDING)) 2647 return -EAGAIN; 2648 2649 port_id = pf->port_id; 2650 rte_cpu_to_le_32(rte_write32(1 << port_id, (uint8_t *)bp->bar0 + 2651 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV])); 2652 2653 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2654 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 2655 if (fifo & BNXT_PTP_RX_FIFO_PENDING) { 2656 /* bnxt_clr_rx_ts(bp); TBD */ 2657 return -EBUSY; 2658 } 2659 2660 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2661 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L])); 2662 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 2663 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32; 2664 2665 return 0; 2666 } 2667 2668 static int 2669 bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) 2670 { 2671 uint64_t ns; 2672 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2673 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2674 2675 if (!ptp) 2676 return 0; 2677 2678 ns = rte_timespec_to_ns(ts); 2679 /* Set the timecounters to a new value. */ 2680 ptp->tc.nsec = ns; 2681 2682 return 0; 2683 } 2684 2685 static int 2686 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) 2687 { 2688 uint64_t ns, systime_cycles; 2689 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2690 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2691 2692 if (!ptp) 2693 return 0; 2694 2695 systime_cycles = bnxt_cc_read(bp); 2696 ns = rte_timecounter_update(&ptp->tc, systime_cycles); 2697 *ts = rte_ns_to_timespec(ns); 2698 2699 return 0; 2700 } 2701 static int 2702 bnxt_timesync_enable(struct rte_eth_dev *dev) 2703 { 2704 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2705 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2706 uint32_t shift = 0; 2707 2708 if (!ptp) 2709 return 0; 2710 2711 ptp->rx_filter = 1; 2712 ptp->tx_tstamp_en = 1; 2713 ptp->rxctl = BNXT_PTP_MSG_EVENTS; 2714 2715 if (!bnxt_hwrm_ptp_cfg(bp)) 2716 bnxt_map_ptp_regs(bp); 2717 2718 memset(&ptp->tc, 0, sizeof(struct rte_timecounter)); 2719 memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 2720 memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 2721 2722 ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 2723 ptp->tc.cc_shift = shift; 2724 ptp->tc.nsec_mask = (1ULL << shift) - 1; 2725 2726 ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 2727 ptp->rx_tstamp_tc.cc_shift = shift; 2728 ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 2729 2730 ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 2731 ptp->tx_tstamp_tc.cc_shift = shift; 2732 ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 2733 2734 return 0; 2735 } 2736 2737 static int 2738 bnxt_timesync_disable(struct rte_eth_dev *dev) 2739 { 2740 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2741 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2742 2743 if (!ptp) 2744 return 0; 2745 2746 ptp->rx_filter = 0; 2747 ptp->tx_tstamp_en = 0; 2748 ptp->rxctl = 0; 2749 2750 bnxt_hwrm_ptp_cfg(bp); 2751 2752 bnxt_unmap_ptp_regs(bp); 2753 2754 return 0; 2755 } 2756 2757 static int 2758 bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 2759 struct timespec *timestamp, 2760 uint32_t flags __rte_unused) 2761 { 2762 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2763 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2764 uint64_t rx_tstamp_cycles = 0; 2765 uint64_t ns; 2766 2767 if (!ptp) 2768 return 0; 2769 2770 bnxt_get_rx_ts(bp, &rx_tstamp_cycles); 2771 ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles); 2772 *timestamp = rte_ns_to_timespec(ns); 2773 return 0; 2774 } 2775 2776 static int 2777 bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 2778 struct timespec *timestamp) 2779 { 2780 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2781 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2782 uint64_t tx_tstamp_cycles = 0; 2783 uint64_t ns; 2784 2785 if (!ptp) 2786 return 0; 2787 2788 bnxt_get_tx_ts(bp, &tx_tstamp_cycles); 2789 ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles); 2790 *timestamp = rte_ns_to_timespec(ns); 2791 2792 return 0; 2793 } 2794 2795 static int 2796 bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 2797 { 2798 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2799 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 2800 2801 if (!ptp) 2802 return 0; 2803 2804 ptp->tc.nsec += delta; 2805 2806 return 0; 2807 } 2808 2809 static int 2810 bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) 2811 { 2812 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2813 int rc; 2814 uint32_t dir_entries; 2815 uint32_t entry_length; 2816 2817 PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x\n", 2818 bp->pdev->addr.domain, bp->pdev->addr.bus, 2819 bp->pdev->addr.devid, bp->pdev->addr.function); 2820 2821 rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length); 2822 if (rc != 0) 2823 return rc; 2824 2825 return dir_entries * entry_length; 2826 } 2827 2828 static int 2829 bnxt_get_eeprom_op(struct rte_eth_dev *dev, 2830 struct rte_dev_eeprom_info *in_eeprom) 2831 { 2832 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2833 uint32_t index; 2834 uint32_t offset; 2835 2836 PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d " 2837 "len = %d\n", bp->pdev->addr.domain, 2838 bp->pdev->addr.bus, bp->pdev->addr.devid, 2839 bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length); 2840 2841 if (in_eeprom->offset == 0) /* special offset value to get directory */ 2842 return bnxt_get_nvram_directory(bp, in_eeprom->length, 2843 in_eeprom->data); 2844 2845 index = in_eeprom->offset >> 24; 2846 offset = in_eeprom->offset & 0xffffff; 2847 2848 if (index != 0) 2849 return bnxt_hwrm_get_nvram_item(bp, index - 1, offset, 2850 in_eeprom->length, in_eeprom->data); 2851 2852 return 0; 2853 } 2854 2855 static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type) 2856 { 2857 switch (dir_type) { 2858 case BNX_DIR_TYPE_CHIMP_PATCH: 2859 case BNX_DIR_TYPE_BOOTCODE: 2860 case BNX_DIR_TYPE_BOOTCODE_2: 2861 case BNX_DIR_TYPE_APE_FW: 2862 case BNX_DIR_TYPE_APE_PATCH: 2863 case BNX_DIR_TYPE_KONG_FW: 2864 case BNX_DIR_TYPE_KONG_PATCH: 2865 case BNX_DIR_TYPE_BONO_FW: 2866 case BNX_DIR_TYPE_BONO_PATCH: 2867 return true; 2868 } 2869 2870 return false; 2871 } 2872 2873 static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type) 2874 { 2875 switch (dir_type) { 2876 case BNX_DIR_TYPE_AVS: 2877 case BNX_DIR_TYPE_EXP_ROM_MBA: 2878 case BNX_DIR_TYPE_PCIE: 2879 case BNX_DIR_TYPE_TSCF_UCODE: 2880 case BNX_DIR_TYPE_EXT_PHY: 2881 case BNX_DIR_TYPE_CCM: 2882 case BNX_DIR_TYPE_ISCSI_BOOT: 2883 case BNX_DIR_TYPE_ISCSI_BOOT_IPV6: 2884 case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6: 2885 return true; 2886 } 2887 2888 return false; 2889 } 2890 2891 static bool bnxt_dir_type_is_executable(uint16_t dir_type) 2892 { 2893 return bnxt_dir_type_is_ape_bin_format(dir_type) || 2894 bnxt_dir_type_is_other_exec_format(dir_type); 2895 } 2896 2897 static int 2898 bnxt_set_eeprom_op(struct rte_eth_dev *dev, 2899 struct rte_dev_eeprom_info *in_eeprom) 2900 { 2901 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2902 uint8_t index, dir_op; 2903 uint16_t type, ext, ordinal, attr; 2904 2905 PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d " 2906 "len = %d\n", bp->pdev->addr.domain, 2907 bp->pdev->addr.bus, bp->pdev->addr.devid, 2908 bp->pdev->addr.function, in_eeprom->offset, in_eeprom->length); 2909 2910 if (!BNXT_PF(bp)) { 2911 PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n"); 2912 return -EINVAL; 2913 } 2914 2915 type = in_eeprom->magic >> 16; 2916 2917 if (type == 0xffff) { /* special value for directory operations */ 2918 index = in_eeprom->magic & 0xff; 2919 dir_op = in_eeprom->magic >> 8; 2920 if (index == 0) 2921 return -EINVAL; 2922 switch (dir_op) { 2923 case 0x0e: /* erase */ 2924 if (in_eeprom->offset != ~in_eeprom->magic) 2925 return -EINVAL; 2926 return bnxt_hwrm_erase_nvram_directory(bp, index - 1); 2927 default: 2928 return -EINVAL; 2929 } 2930 } 2931 2932 /* Create or re-write an NVM item: */ 2933 if (bnxt_dir_type_is_executable(type) == true) 2934 return -EOPNOTSUPP; 2935 ext = in_eeprom->magic & 0xffff; 2936 ordinal = in_eeprom->offset >> 16; 2937 attr = in_eeprom->offset & 0xffff; 2938 2939 return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr, 2940 in_eeprom->data, in_eeprom->length); 2941 return 0; 2942 } 2943 2944 /* 2945 * Initialization 2946 */ 2947 2948 static const struct eth_dev_ops bnxt_dev_ops = { 2949 .dev_infos_get = bnxt_dev_info_get_op, 2950 .dev_close = bnxt_dev_close_op, 2951 .dev_configure = bnxt_dev_configure_op, 2952 .dev_start = bnxt_dev_start_op, 2953 .dev_stop = bnxt_dev_stop_op, 2954 .dev_set_link_up = bnxt_dev_set_link_up_op, 2955 .dev_set_link_down = bnxt_dev_set_link_down_op, 2956 .stats_get = bnxt_stats_get_op, 2957 .stats_reset = bnxt_stats_reset_op, 2958 .rx_queue_setup = bnxt_rx_queue_setup_op, 2959 .rx_queue_release = bnxt_rx_queue_release_op, 2960 .tx_queue_setup = bnxt_tx_queue_setup_op, 2961 .tx_queue_release = bnxt_tx_queue_release_op, 2962 .rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op, 2963 .rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op, 2964 .reta_update = bnxt_reta_update_op, 2965 .reta_query = bnxt_reta_query_op, 2966 .rss_hash_update = bnxt_rss_hash_update_op, 2967 .rss_hash_conf_get = bnxt_rss_hash_conf_get_op, 2968 .link_update = bnxt_link_update_op, 2969 .promiscuous_enable = bnxt_promiscuous_enable_op, 2970 .promiscuous_disable = bnxt_promiscuous_disable_op, 2971 .allmulticast_enable = bnxt_allmulticast_enable_op, 2972 .allmulticast_disable = bnxt_allmulticast_disable_op, 2973 .mac_addr_add = bnxt_mac_addr_add_op, 2974 .mac_addr_remove = bnxt_mac_addr_remove_op, 2975 .flow_ctrl_get = bnxt_flow_ctrl_get_op, 2976 .flow_ctrl_set = bnxt_flow_ctrl_set_op, 2977 .udp_tunnel_port_add = bnxt_udp_tunnel_port_add_op, 2978 .udp_tunnel_port_del = bnxt_udp_tunnel_port_del_op, 2979 .vlan_filter_set = bnxt_vlan_filter_set_op, 2980 .vlan_offload_set = bnxt_vlan_offload_set_op, 2981 .vlan_pvid_set = bnxt_vlan_pvid_set_op, 2982 .mtu_set = bnxt_mtu_set_op, 2983 .mac_addr_set = bnxt_set_default_mac_addr_op, 2984 .xstats_get = bnxt_dev_xstats_get_op, 2985 .xstats_get_names = bnxt_dev_xstats_get_names_op, 2986 .xstats_reset = bnxt_dev_xstats_reset_op, 2987 .fw_version_get = bnxt_fw_version_get, 2988 .set_mc_addr_list = bnxt_dev_set_mc_addr_list_op, 2989 .rxq_info_get = bnxt_rxq_info_get_op, 2990 .txq_info_get = bnxt_txq_info_get_op, 2991 .dev_led_on = bnxt_dev_led_on_op, 2992 .dev_led_off = bnxt_dev_led_off_op, 2993 .xstats_get_by_id = bnxt_dev_xstats_get_by_id_op, 2994 .xstats_get_names_by_id = bnxt_dev_xstats_get_names_by_id_op, 2995 .rx_queue_count = bnxt_rx_queue_count_op, 2996 .rx_descriptor_status = bnxt_rx_descriptor_status_op, 2997 .tx_descriptor_status = bnxt_tx_descriptor_status_op, 2998 .rx_queue_start = bnxt_rx_queue_start, 2999 .rx_queue_stop = bnxt_rx_queue_stop, 3000 .tx_queue_start = bnxt_tx_queue_start, 3001 .tx_queue_stop = bnxt_tx_queue_stop, 3002 .filter_ctrl = bnxt_filter_ctrl_op, 3003 .dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op, 3004 .get_eeprom_length = bnxt_get_eeprom_length_op, 3005 .get_eeprom = bnxt_get_eeprom_op, 3006 .set_eeprom = bnxt_set_eeprom_op, 3007 .timesync_enable = bnxt_timesync_enable, 3008 .timesync_disable = bnxt_timesync_disable, 3009 .timesync_read_time = bnxt_timesync_read_time, 3010 .timesync_write_time = bnxt_timesync_write_time, 3011 .timesync_adjust_time = bnxt_timesync_adjust_time, 3012 .timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp, 3013 .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, 3014 }; 3015 3016 static bool bnxt_vf_pciid(uint16_t id) 3017 { 3018 if (id == BROADCOM_DEV_ID_57304_VF || 3019 id == BROADCOM_DEV_ID_57406_VF || 3020 id == BROADCOM_DEV_ID_5731X_VF || 3021 id == BROADCOM_DEV_ID_5741X_VF || 3022 id == BROADCOM_DEV_ID_57414_VF || 3023 id == BROADCOM_DEV_ID_STRATUS_NIC_VF) 3024 return true; 3025 return false; 3026 } 3027 3028 static int bnxt_init_board(struct rte_eth_dev *eth_dev) 3029 { 3030 struct bnxt *bp = eth_dev->data->dev_private; 3031 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 3032 int rc; 3033 3034 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 3035 if (!pci_dev->mem_resource[0].addr) { 3036 PMD_DRV_LOG(ERR, 3037 "Cannot find PCI device base address, aborting\n"); 3038 rc = -ENODEV; 3039 goto init_err_disable; 3040 } 3041 3042 bp->eth_dev = eth_dev; 3043 bp->pdev = pci_dev; 3044 3045 bp->bar0 = (void *)pci_dev->mem_resource[0].addr; 3046 if (!bp->bar0) { 3047 PMD_DRV_LOG(ERR, "Cannot map device registers, aborting\n"); 3048 rc = -ENOMEM; 3049 goto init_err_release; 3050 } 3051 return 0; 3052 3053 init_err_release: 3054 if (bp->bar0) 3055 bp->bar0 = NULL; 3056 3057 init_err_disable: 3058 3059 return rc; 3060 } 3061 3062 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); 3063 3064 #define ALLOW_FUNC(x) \ 3065 { \ 3066 typeof(x) arg = (x); \ 3067 bp->pf.vf_req_fwd[((arg) >> 5)] &= \ 3068 ~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \ 3069 } 3070 static int 3071 bnxt_dev_init(struct rte_eth_dev *eth_dev) 3072 { 3073 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 3074 char mz_name[RTE_MEMZONE_NAMESIZE]; 3075 const struct rte_memzone *mz = NULL; 3076 static int version_printed; 3077 uint32_t total_alloc_len; 3078 rte_iova_t mz_phys_addr; 3079 struct bnxt *bp; 3080 int rc; 3081 3082 if (version_printed++ == 0) 3083 PMD_DRV_LOG(INFO, "%s\n", bnxt_version); 3084 3085 rte_eth_copy_pci_info(eth_dev, pci_dev); 3086 3087 bp = eth_dev->data->dev_private; 3088 3089 rte_atomic64_init(&bp->rx_mbuf_alloc_fail); 3090 bp->dev_stopped = 1; 3091 3092 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 3093 goto skip_init; 3094 3095 if (bnxt_vf_pciid(pci_dev->id.device_id)) 3096 bp->flags |= BNXT_FLAG_VF; 3097 3098 rc = bnxt_init_board(eth_dev); 3099 if (rc) { 3100 PMD_DRV_LOG(ERR, 3101 "Board initialization failed rc: %x\n", rc); 3102 goto error; 3103 } 3104 skip_init: 3105 eth_dev->dev_ops = &bnxt_dev_ops; 3106 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 3107 return 0; 3108 eth_dev->rx_pkt_burst = &bnxt_recv_pkts; 3109 eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; 3110 3111 if (BNXT_PF(bp) && pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) { 3112 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 3113 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain, 3114 pci_dev->addr.bus, pci_dev->addr.devid, 3115 pci_dev->addr.function, "rx_port_stats"); 3116 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 3117 mz = rte_memzone_lookup(mz_name); 3118 total_alloc_len = RTE_CACHE_LINE_ROUNDUP( 3119 sizeof(struct rx_port_stats) + 512); 3120 if (!mz) { 3121 mz = rte_memzone_reserve(mz_name, total_alloc_len, 3122 SOCKET_ID_ANY, 3123 RTE_MEMZONE_2MB | 3124 RTE_MEMZONE_SIZE_HINT_ONLY | 3125 RTE_MEMZONE_IOVA_CONTIG); 3126 if (mz == NULL) 3127 return -ENOMEM; 3128 } 3129 memset(mz->addr, 0, mz->len); 3130 mz_phys_addr = mz->iova; 3131 if ((unsigned long)mz->addr == mz_phys_addr) { 3132 PMD_DRV_LOG(WARNING, 3133 "Memzone physical address same as virtual.\n"); 3134 PMD_DRV_LOG(WARNING, 3135 "Using rte_mem_virt2iova()\n"); 3136 mz_phys_addr = rte_mem_virt2iova(mz->addr); 3137 if (mz_phys_addr == 0) { 3138 PMD_DRV_LOG(ERR, 3139 "unable to map address to physical memory\n"); 3140 return -ENOMEM; 3141 } 3142 } 3143 3144 bp->rx_mem_zone = (const void *)mz; 3145 bp->hw_rx_port_stats = mz->addr; 3146 bp->hw_rx_port_stats_map = mz_phys_addr; 3147 3148 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 3149 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain, 3150 pci_dev->addr.bus, pci_dev->addr.devid, 3151 pci_dev->addr.function, "tx_port_stats"); 3152 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 3153 mz = rte_memzone_lookup(mz_name); 3154 total_alloc_len = RTE_CACHE_LINE_ROUNDUP( 3155 sizeof(struct tx_port_stats) + 512); 3156 if (!mz) { 3157 mz = rte_memzone_reserve(mz_name, 3158 total_alloc_len, 3159 SOCKET_ID_ANY, 3160 RTE_MEMZONE_2MB | 3161 RTE_MEMZONE_SIZE_HINT_ONLY | 3162 RTE_MEMZONE_IOVA_CONTIG); 3163 if (mz == NULL) 3164 return -ENOMEM; 3165 } 3166 memset(mz->addr, 0, mz->len); 3167 mz_phys_addr = mz->iova; 3168 if ((unsigned long)mz->addr == mz_phys_addr) { 3169 PMD_DRV_LOG(WARNING, 3170 "Memzone physical address same as virtual.\n"); 3171 PMD_DRV_LOG(WARNING, 3172 "Using rte_mem_virt2iova()\n"); 3173 mz_phys_addr = rte_mem_virt2iova(mz->addr); 3174 if (mz_phys_addr == 0) { 3175 PMD_DRV_LOG(ERR, 3176 "unable to map address to physical memory\n"); 3177 return -ENOMEM; 3178 } 3179 } 3180 3181 bp->tx_mem_zone = (const void *)mz; 3182 bp->hw_tx_port_stats = mz->addr; 3183 bp->hw_tx_port_stats_map = mz_phys_addr; 3184 3185 bp->flags |= BNXT_FLAG_PORT_STATS; 3186 } 3187 3188 rc = bnxt_alloc_hwrm_resources(bp); 3189 if (rc) { 3190 PMD_DRV_LOG(ERR, 3191 "hwrm resource allocation failure rc: %x\n", rc); 3192 goto error_free; 3193 } 3194 rc = bnxt_hwrm_ver_get(bp); 3195 if (rc) 3196 goto error_free; 3197 rc = bnxt_hwrm_queue_qportcfg(bp); 3198 if (rc) { 3199 PMD_DRV_LOG(ERR, "hwrm queue qportcfg failed\n"); 3200 goto error_free; 3201 } 3202 3203 rc = bnxt_hwrm_func_qcfg(bp); 3204 if (rc) { 3205 PMD_DRV_LOG(ERR, "hwrm func qcfg failed\n"); 3206 goto error_free; 3207 } 3208 3209 /* Get the MAX capabilities for this function */ 3210 rc = bnxt_hwrm_func_qcaps(bp); 3211 if (rc) { 3212 PMD_DRV_LOG(ERR, "hwrm query capability failure rc: %x\n", rc); 3213 goto error_free; 3214 } 3215 if (bp->max_tx_rings == 0) { 3216 PMD_DRV_LOG(ERR, "No TX rings available!\n"); 3217 rc = -EBUSY; 3218 goto error_free; 3219 } 3220 eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", 3221 ETHER_ADDR_LEN * bp->max_l2_ctx, 0); 3222 if (eth_dev->data->mac_addrs == NULL) { 3223 PMD_DRV_LOG(ERR, 3224 "Failed to alloc %u bytes needed to store MAC addr tbl", 3225 ETHER_ADDR_LEN * bp->max_l2_ctx); 3226 rc = -ENOMEM; 3227 goto error_free; 3228 } 3229 3230 if (check_zero_bytes(bp->dflt_mac_addr, ETHER_ADDR_LEN)) { 3231 PMD_DRV_LOG(ERR, 3232 "Invalid MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", 3233 bp->dflt_mac_addr[0], bp->dflt_mac_addr[1], 3234 bp->dflt_mac_addr[2], bp->dflt_mac_addr[3], 3235 bp->dflt_mac_addr[4], bp->dflt_mac_addr[5]); 3236 rc = -EINVAL; 3237 goto error_free; 3238 } 3239 /* Copy the permanent MAC from the qcap response address now. */ 3240 memcpy(bp->mac_addr, bp->dflt_mac_addr, sizeof(bp->mac_addr)); 3241 memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN); 3242 3243 if (bp->max_ring_grps < bp->rx_cp_nr_rings) { 3244 /* 1 ring is for default completion ring */ 3245 PMD_DRV_LOG(ERR, "Insufficient resource: Ring Group\n"); 3246 rc = -ENOSPC; 3247 goto error_free; 3248 } 3249 3250 bp->grp_info = rte_zmalloc("bnxt_grp_info", 3251 sizeof(*bp->grp_info) * bp->max_ring_grps, 0); 3252 if (!bp->grp_info) { 3253 PMD_DRV_LOG(ERR, 3254 "Failed to alloc %zu bytes to store group info table\n", 3255 sizeof(*bp->grp_info) * bp->max_ring_grps); 3256 rc = -ENOMEM; 3257 goto error_free; 3258 } 3259 3260 /* Forward all requests if firmware is new enough */ 3261 if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) && 3262 (bp->fw_ver < ((20 << 24) | (7 << 16)))) || 3263 ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) { 3264 memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd)); 3265 } else { 3266 PMD_DRV_LOG(WARNING, 3267 "Firmware too old for VF mailbox functionality\n"); 3268 memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd)); 3269 } 3270 3271 /* 3272 * The following are used for driver cleanup. If we disallow these, 3273 * VF drivers can't clean up cleanly. 3274 */ 3275 ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR); 3276 ALLOW_FUNC(HWRM_VNIC_FREE); 3277 ALLOW_FUNC(HWRM_RING_FREE); 3278 ALLOW_FUNC(HWRM_RING_GRP_FREE); 3279 ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE); 3280 ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE); 3281 ALLOW_FUNC(HWRM_STAT_CTX_FREE); 3282 ALLOW_FUNC(HWRM_PORT_PHY_QCFG); 3283 ALLOW_FUNC(HWRM_VNIC_TPA_CFG); 3284 rc = bnxt_hwrm_func_driver_register(bp); 3285 if (rc) { 3286 PMD_DRV_LOG(ERR, 3287 "Failed to register driver"); 3288 rc = -EBUSY; 3289 goto error_free; 3290 } 3291 3292 PMD_DRV_LOG(INFO, 3293 DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n", 3294 pci_dev->mem_resource[0].phys_addr, 3295 pci_dev->mem_resource[0].addr); 3296 3297 rc = bnxt_hwrm_func_reset(bp); 3298 if (rc) { 3299 PMD_DRV_LOG(ERR, "hwrm chip reset failure rc: %x\n", rc); 3300 rc = -EIO; 3301 goto error_free; 3302 } 3303 3304 if (BNXT_PF(bp)) { 3305 //if (bp->pf.active_vfs) { 3306 // TODO: Deallocate VF resources? 3307 //} 3308 if (bp->pdev->max_vfs) { 3309 rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs); 3310 if (rc) { 3311 PMD_DRV_LOG(ERR, "Failed to allocate VFs\n"); 3312 goto error_free; 3313 } 3314 } else { 3315 rc = bnxt_hwrm_allocate_pf_only(bp); 3316 if (rc) { 3317 PMD_DRV_LOG(ERR, 3318 "Failed to allocate PF resources\n"); 3319 goto error_free; 3320 } 3321 } 3322 } 3323 3324 bnxt_hwrm_port_led_qcaps(bp); 3325 3326 rc = bnxt_setup_int(bp); 3327 if (rc) 3328 goto error_free; 3329 3330 rc = bnxt_alloc_mem(bp); 3331 if (rc) 3332 goto error_free_int; 3333 3334 rc = bnxt_request_int(bp); 3335 if (rc) 3336 goto error_free_int; 3337 3338 rc = bnxt_alloc_def_cp_ring(bp); 3339 if (rc) 3340 goto error_free_int; 3341 3342 bnxt_enable_int(bp); 3343 3344 return 0; 3345 3346 error_free_int: 3347 bnxt_disable_int(bp); 3348 bnxt_free_def_cp_ring(bp); 3349 bnxt_hwrm_func_buf_unrgtr(bp); 3350 bnxt_free_int(bp); 3351 bnxt_free_mem(bp); 3352 error_free: 3353 bnxt_dev_uninit(eth_dev); 3354 error: 3355 return rc; 3356 } 3357 3358 static int 3359 bnxt_dev_uninit(struct rte_eth_dev *eth_dev) { 3360 struct bnxt *bp = eth_dev->data->dev_private; 3361 int rc; 3362 3363 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 3364 return -EPERM; 3365 3366 bnxt_disable_int(bp); 3367 bnxt_free_int(bp); 3368 bnxt_free_mem(bp); 3369 if (eth_dev->data->mac_addrs != NULL) { 3370 rte_free(eth_dev->data->mac_addrs); 3371 eth_dev->data->mac_addrs = NULL; 3372 } 3373 if (bp->grp_info != NULL) { 3374 rte_free(bp->grp_info); 3375 bp->grp_info = NULL; 3376 } 3377 rc = bnxt_hwrm_func_driver_unregister(bp, 0); 3378 bnxt_free_hwrm_resources(bp); 3379 rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone); 3380 rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone); 3381 if (bp->dev_stopped == 0) 3382 bnxt_dev_close_op(eth_dev); 3383 if (bp->pf.vf_info) 3384 rte_free(bp->pf.vf_info); 3385 eth_dev->dev_ops = NULL; 3386 eth_dev->rx_pkt_burst = NULL; 3387 eth_dev->tx_pkt_burst = NULL; 3388 3389 return rc; 3390 } 3391 3392 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 3393 struct rte_pci_device *pci_dev) 3394 { 3395 return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct bnxt), 3396 bnxt_dev_init); 3397 } 3398 3399 static int bnxt_pci_remove(struct rte_pci_device *pci_dev) 3400 { 3401 return rte_eth_dev_pci_generic_remove(pci_dev, bnxt_dev_uninit); 3402 } 3403 3404 static struct rte_pci_driver bnxt_rte_pmd = { 3405 .id_table = bnxt_pci_id_map, 3406 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | 3407 RTE_PCI_DRV_INTR_LSC, 3408 .probe = bnxt_pci_probe, 3409 .remove = bnxt_pci_remove, 3410 }; 3411 3412 static bool 3413 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv) 3414 { 3415 if (strcmp(dev->device->driver->name, drv->driver.name)) 3416 return false; 3417 3418 return true; 3419 } 3420 3421 bool is_bnxt_supported(struct rte_eth_dev *dev) 3422 { 3423 return is_device_supported(dev, &bnxt_rte_pmd); 3424 } 3425 3426 RTE_INIT(bnxt_init_log); 3427 static void 3428 bnxt_init_log(void) 3429 { 3430 bnxt_logtype_driver = rte_log_register("pmd.bnxt.driver"); 3431 if (bnxt_logtype_driver >= 0) 3432 rte_log_set_level(bnxt_logtype_driver, RTE_LOG_NOTICE); 3433 } 3434 3435 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd); 3436 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map); 3437 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci"); 3438