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 #include <rte_alarm.h> 15 #include <rte_kvargs.h> 16 17 #include "bnxt.h" 18 #include "bnxt_filter.h" 19 #include "bnxt_hwrm.h" 20 #include "bnxt_irq.h" 21 #include "bnxt_ring.h" 22 #include "bnxt_rxq.h" 23 #include "bnxt_rxr.h" 24 #include "bnxt_stats.h" 25 #include "bnxt_txq.h" 26 #include "bnxt_txr.h" 27 #include "bnxt_vnic.h" 28 #include "hsi_struct_def_dpdk.h" 29 #include "bnxt_nvm_defs.h" 30 31 #define DRV_MODULE_NAME "bnxt" 32 static const char bnxt_version[] = 33 "Broadcom NetXtreme driver " DRV_MODULE_NAME; 34 35 /* 36 * The set of PCI devices this driver supports 37 */ 38 static const struct rte_pci_id bnxt_pci_id_map[] = { 39 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 40 BROADCOM_DEV_ID_STRATUS_NIC_VF1) }, 41 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 42 BROADCOM_DEV_ID_STRATUS_NIC_VF2) }, 43 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_STRATUS_NIC) }, 44 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_VF) }, 45 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301) }, 46 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302) }, 47 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF) }, 48 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF) }, 49 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_NS2) }, 50 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402) }, 51 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404) }, 52 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF) }, 53 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF) }, 54 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402_MF) }, 55 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_RJ45) }, 56 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404_MF) }, 57 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF) }, 58 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_SFP) }, 59 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57407_MF) }, 60 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5741X_VF) }, 61 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_5731X_VF) }, 62 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57314) }, 63 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_MF) }, 64 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57311) }, 65 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57312) }, 66 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412) }, 67 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414) }, 68 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_RJ45) }, 69 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_RJ45) }, 70 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57412_MF) }, 71 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_RJ45) }, 72 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57417_SFP) }, 73 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_SFP) }, 74 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57317_SFP) }, 75 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57414_MF) }, 76 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57416_MF) }, 77 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802) }, 78 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58804) }, 79 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58808) }, 80 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_58802_VF) }, 81 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508) }, 82 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504) }, 83 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502) }, 84 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF1) }, 85 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57500_VF2) }, 86 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF1) }, 87 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF1) }, 88 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF1) }, 89 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57508_MF2) }, 90 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57504_MF2) }, 91 { RTE_PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57502_MF2) }, 92 { .vendor_id = 0, /* sentinel */ }, 93 }; 94 95 #define BNXT_ETH_RSS_SUPPORT ( \ 96 ETH_RSS_IPV4 | \ 97 ETH_RSS_NONFRAG_IPV4_TCP | \ 98 ETH_RSS_NONFRAG_IPV4_UDP | \ 99 ETH_RSS_IPV6 | \ 100 ETH_RSS_NONFRAG_IPV6_TCP | \ 101 ETH_RSS_NONFRAG_IPV6_UDP) 102 103 #define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_VLAN_INSERT | \ 104 DEV_TX_OFFLOAD_IPV4_CKSUM | \ 105 DEV_TX_OFFLOAD_TCP_CKSUM | \ 106 DEV_TX_OFFLOAD_UDP_CKSUM | \ 107 DEV_TX_OFFLOAD_TCP_TSO | \ 108 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | \ 109 DEV_TX_OFFLOAD_VXLAN_TNL_TSO | \ 110 DEV_TX_OFFLOAD_GRE_TNL_TSO | \ 111 DEV_TX_OFFLOAD_IPIP_TNL_TSO | \ 112 DEV_TX_OFFLOAD_GENEVE_TNL_TSO | \ 113 DEV_TX_OFFLOAD_QINQ_INSERT | \ 114 DEV_TX_OFFLOAD_MULTI_SEGS) 115 116 #define BNXT_DEV_RX_OFFLOAD_SUPPORT (DEV_RX_OFFLOAD_VLAN_FILTER | \ 117 DEV_RX_OFFLOAD_VLAN_STRIP | \ 118 DEV_RX_OFFLOAD_IPV4_CKSUM | \ 119 DEV_RX_OFFLOAD_UDP_CKSUM | \ 120 DEV_RX_OFFLOAD_TCP_CKSUM | \ 121 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | \ 122 DEV_RX_OFFLOAD_JUMBO_FRAME | \ 123 DEV_RX_OFFLOAD_KEEP_CRC | \ 124 DEV_RX_OFFLOAD_VLAN_EXTEND | \ 125 DEV_RX_OFFLOAD_TCP_LRO | \ 126 DEV_RX_OFFLOAD_SCATTER | \ 127 DEV_RX_OFFLOAD_RSS_HASH) 128 129 #define BNXT_DEVARG_TRUFLOW "host-based-truflow" 130 #define BNXT_DEVARG_FLOW_XSTAT "flow-xstat" 131 #define BNXT_DEVARG_MAX_NUM_KFLOWS "max-num-kflows" 132 static const char *const bnxt_dev_args[] = { 133 BNXT_DEVARG_TRUFLOW, 134 BNXT_DEVARG_FLOW_XSTAT, 135 BNXT_DEVARG_MAX_NUM_KFLOWS, 136 NULL 137 }; 138 139 /* 140 * truflow == false to disable the feature 141 * truflow == true to enable the feature 142 */ 143 #define BNXT_DEVARG_TRUFLOW_INVALID(truflow) ((truflow) > 1) 144 145 /* 146 * flow_xstat == false to disable the feature 147 * flow_xstat == true to enable the feature 148 */ 149 #define BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat) ((flow_xstat) > 1) 150 151 /* 152 * max_num_kflows must be >= 32 153 * and must be a power-of-2 supported value 154 * return: 1 -> invalid 155 * 0 -> valid 156 */ 157 static int bnxt_devarg_max_num_kflow_invalid(uint16_t max_num_kflows) 158 { 159 if (max_num_kflows < 32 || !rte_is_power_of_2(max_num_kflows)) 160 return 1; 161 return 0; 162 } 163 164 static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask); 165 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev); 166 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); 167 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev); 168 static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev); 169 static void bnxt_cancel_fw_health_check(struct bnxt *bp); 170 static int bnxt_restore_vlan_filters(struct bnxt *bp); 171 static void bnxt_dev_recover(void *arg); 172 static void bnxt_free_error_recovery_info(struct bnxt *bp); 173 174 int is_bnxt_in_error(struct bnxt *bp) 175 { 176 if (bp->flags & BNXT_FLAG_FATAL_ERROR) 177 return -EIO; 178 if (bp->flags & BNXT_FLAG_FW_RESET) 179 return -EBUSY; 180 181 return 0; 182 } 183 184 /***********************/ 185 186 /* 187 * High level utility functions 188 */ 189 190 static uint16_t bnxt_rss_ctxts(const struct bnxt *bp) 191 { 192 if (!BNXT_CHIP_THOR(bp)) 193 return 1; 194 195 return RTE_ALIGN_MUL_CEIL(bp->rx_nr_rings, 196 BNXT_RSS_ENTRIES_PER_CTX_THOR) / 197 BNXT_RSS_ENTRIES_PER_CTX_THOR; 198 } 199 200 static uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp) 201 { 202 if (!BNXT_CHIP_THOR(bp)) 203 return HW_HASH_INDEX_SIZE; 204 205 return bnxt_rss_ctxts(bp) * BNXT_RSS_ENTRIES_PER_CTX_THOR; 206 } 207 208 static void bnxt_free_pf_info(struct bnxt *bp) 209 { 210 rte_free(bp->pf); 211 } 212 213 static void bnxt_free_link_info(struct bnxt *bp) 214 { 215 rte_free(bp->link_info); 216 } 217 218 static void bnxt_free_leds_info(struct bnxt *bp) 219 { 220 rte_free(bp->leds); 221 bp->leds = NULL; 222 } 223 224 static void bnxt_free_flow_stats_info(struct bnxt *bp) 225 { 226 rte_free(bp->flow_stat); 227 bp->flow_stat = NULL; 228 } 229 230 static void bnxt_free_cos_queues(struct bnxt *bp) 231 { 232 rte_free(bp->rx_cos_queue); 233 rte_free(bp->tx_cos_queue); 234 } 235 236 static void bnxt_free_mem(struct bnxt *bp, bool reconfig) 237 { 238 bnxt_free_filter_mem(bp); 239 bnxt_free_vnic_attributes(bp); 240 bnxt_free_vnic_mem(bp); 241 242 /* tx/rx rings are configured as part of *_queue_setup callbacks. 243 * If the number of rings change across fw update, 244 * we don't have much choice except to warn the user. 245 */ 246 if (!reconfig) { 247 bnxt_free_stats(bp); 248 bnxt_free_tx_rings(bp); 249 bnxt_free_rx_rings(bp); 250 } 251 bnxt_free_async_cp_ring(bp); 252 bnxt_free_rxtx_nq_ring(bp); 253 254 rte_free(bp->grp_info); 255 bp->grp_info = NULL; 256 } 257 258 static int bnxt_alloc_pf_info(struct bnxt *bp) 259 { 260 bp->pf = rte_zmalloc("bnxt_pf_info", sizeof(struct bnxt_pf_info), 0); 261 if (bp->pf == NULL) 262 return -ENOMEM; 263 264 return 0; 265 } 266 267 static int bnxt_alloc_link_info(struct bnxt *bp) 268 { 269 bp->link_info = 270 rte_zmalloc("bnxt_link_info", sizeof(struct bnxt_link_info), 0); 271 if (bp->link_info == NULL) 272 return -ENOMEM; 273 274 return 0; 275 } 276 277 static int bnxt_alloc_leds_info(struct bnxt *bp) 278 { 279 bp->leds = rte_zmalloc("bnxt_leds", 280 BNXT_MAX_LED * sizeof(struct bnxt_led_info), 281 0); 282 if (bp->leds == NULL) 283 return -ENOMEM; 284 285 return 0; 286 } 287 288 static int bnxt_alloc_cos_queues(struct bnxt *bp) 289 { 290 bp->rx_cos_queue = 291 rte_zmalloc("bnxt_rx_cosq", 292 BNXT_COS_QUEUE_COUNT * 293 sizeof(struct bnxt_cos_queue_info), 294 0); 295 if (bp->rx_cos_queue == NULL) 296 return -ENOMEM; 297 298 bp->tx_cos_queue = 299 rte_zmalloc("bnxt_tx_cosq", 300 BNXT_COS_QUEUE_COUNT * 301 sizeof(struct bnxt_cos_queue_info), 302 0); 303 if (bp->tx_cos_queue == NULL) 304 return -ENOMEM; 305 306 return 0; 307 } 308 309 static int bnxt_alloc_flow_stats_info(struct bnxt *bp) 310 { 311 bp->flow_stat = rte_zmalloc("bnxt_flow_xstat", 312 sizeof(struct bnxt_flow_stat_info), 0); 313 if (bp->flow_stat == NULL) 314 return -ENOMEM; 315 316 return 0; 317 } 318 319 static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) 320 { 321 int rc; 322 323 rc = bnxt_alloc_ring_grps(bp); 324 if (rc) 325 goto alloc_mem_err; 326 327 rc = bnxt_alloc_async_ring_struct(bp); 328 if (rc) 329 goto alloc_mem_err; 330 331 rc = bnxt_alloc_vnic_mem(bp); 332 if (rc) 333 goto alloc_mem_err; 334 335 rc = bnxt_alloc_vnic_attributes(bp); 336 if (rc) 337 goto alloc_mem_err; 338 339 rc = bnxt_alloc_filter_mem(bp); 340 if (rc) 341 goto alloc_mem_err; 342 343 rc = bnxt_alloc_async_cp_ring(bp); 344 if (rc) 345 goto alloc_mem_err; 346 347 rc = bnxt_alloc_rxtx_nq_ring(bp); 348 if (rc) 349 goto alloc_mem_err; 350 351 if (BNXT_FLOW_XSTATS_EN(bp)) { 352 rc = bnxt_alloc_flow_stats_info(bp); 353 if (rc) 354 goto alloc_mem_err; 355 } 356 357 return 0; 358 359 alloc_mem_err: 360 bnxt_free_mem(bp, reconfig); 361 return rc; 362 } 363 364 static int bnxt_setup_one_vnic(struct bnxt *bp, uint16_t vnic_id) 365 { 366 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 367 struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 368 uint64_t rx_offloads = dev_conf->rxmode.offloads; 369 struct bnxt_rx_queue *rxq; 370 unsigned int j; 371 int rc; 372 373 rc = bnxt_vnic_grp_alloc(bp, vnic); 374 if (rc) 375 goto err_out; 376 377 PMD_DRV_LOG(DEBUG, "vnic[%d] = %p vnic->fw_grp_ids = %p\n", 378 vnic_id, vnic, vnic->fw_grp_ids); 379 380 rc = bnxt_hwrm_vnic_alloc(bp, vnic); 381 if (rc) 382 goto err_out; 383 384 /* Alloc RSS context only if RSS mode is enabled */ 385 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) { 386 int j, nr_ctxs = bnxt_rss_ctxts(bp); 387 388 rc = 0; 389 for (j = 0; j < nr_ctxs; j++) { 390 rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, j); 391 if (rc) 392 break; 393 } 394 if (rc) { 395 PMD_DRV_LOG(ERR, 396 "HWRM vnic %d ctx %d alloc failure rc: %x\n", 397 vnic_id, j, rc); 398 goto err_out; 399 } 400 vnic->num_lb_ctxts = nr_ctxs; 401 } 402 403 /* 404 * Firmware sets pf pair in default vnic cfg. If the VLAN strip 405 * setting is not available at this time, it will not be 406 * configured correctly in the CFA. 407 */ 408 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 409 vnic->vlan_strip = true; 410 else 411 vnic->vlan_strip = false; 412 413 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 414 if (rc) 415 goto err_out; 416 417 rc = bnxt_set_hwrm_vnic_filters(bp, vnic); 418 if (rc) 419 goto err_out; 420 421 for (j = 0; j < bp->rx_num_qs_per_vnic; j++) { 422 rxq = bp->eth_dev->data->rx_queues[j]; 423 424 PMD_DRV_LOG(DEBUG, 425 "rxq[%d]->vnic=%p vnic->fw_grp_ids=%p\n", 426 j, rxq->vnic, rxq->vnic->fw_grp_ids); 427 428 if (BNXT_HAS_RING_GRPS(bp) && rxq->rx_deferred_start) 429 rxq->vnic->fw_grp_ids[j] = INVALID_HW_RING_ID; 430 else 431 vnic->rx_queue_cnt++; 432 } 433 434 PMD_DRV_LOG(DEBUG, "vnic->rx_queue_cnt = %d\n", vnic->rx_queue_cnt); 435 436 rc = bnxt_vnic_rss_configure(bp, vnic); 437 if (rc) 438 goto err_out; 439 440 bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 441 442 if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) 443 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1); 444 else 445 bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0); 446 447 return 0; 448 err_out: 449 PMD_DRV_LOG(ERR, "HWRM vnic %d cfg failure rc: %x\n", 450 vnic_id, rc); 451 return rc; 452 } 453 454 static int bnxt_register_fc_ctx_mem(struct bnxt *bp) 455 { 456 int rc = 0; 457 458 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_in_tbl.dma, 459 &bp->flow_stat->rx_fc_in_tbl.ctx_id); 460 if (rc) 461 return rc; 462 463 PMD_DRV_LOG(DEBUG, 464 "rx_fc_in_tbl.va = %p rx_fc_in_tbl.dma = %p" 465 " rx_fc_in_tbl.ctx_id = %d\n", 466 bp->flow_stat->rx_fc_in_tbl.va, 467 (void *)((uintptr_t)bp->flow_stat->rx_fc_in_tbl.dma), 468 bp->flow_stat->rx_fc_in_tbl.ctx_id); 469 470 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->rx_fc_out_tbl.dma, 471 &bp->flow_stat->rx_fc_out_tbl.ctx_id); 472 if (rc) 473 return rc; 474 475 PMD_DRV_LOG(DEBUG, 476 "rx_fc_out_tbl.va = %p rx_fc_out_tbl.dma = %p" 477 " rx_fc_out_tbl.ctx_id = %d\n", 478 bp->flow_stat->rx_fc_out_tbl.va, 479 (void *)((uintptr_t)bp->flow_stat->rx_fc_out_tbl.dma), 480 bp->flow_stat->rx_fc_out_tbl.ctx_id); 481 482 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_in_tbl.dma, 483 &bp->flow_stat->tx_fc_in_tbl.ctx_id); 484 if (rc) 485 return rc; 486 487 PMD_DRV_LOG(DEBUG, 488 "tx_fc_in_tbl.va = %p tx_fc_in_tbl.dma = %p" 489 " tx_fc_in_tbl.ctx_id = %d\n", 490 bp->flow_stat->tx_fc_in_tbl.va, 491 (void *)((uintptr_t)bp->flow_stat->tx_fc_in_tbl.dma), 492 bp->flow_stat->tx_fc_in_tbl.ctx_id); 493 494 rc = bnxt_hwrm_ctx_rgtr(bp, bp->flow_stat->tx_fc_out_tbl.dma, 495 &bp->flow_stat->tx_fc_out_tbl.ctx_id); 496 if (rc) 497 return rc; 498 499 PMD_DRV_LOG(DEBUG, 500 "tx_fc_out_tbl.va = %p tx_fc_out_tbl.dma = %p" 501 " tx_fc_out_tbl.ctx_id = %d\n", 502 bp->flow_stat->tx_fc_out_tbl.va, 503 (void *)((uintptr_t)bp->flow_stat->tx_fc_out_tbl.dma), 504 bp->flow_stat->tx_fc_out_tbl.ctx_id); 505 506 memset(bp->flow_stat->rx_fc_out_tbl.va, 507 0, 508 bp->flow_stat->rx_fc_out_tbl.size); 509 rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX, 510 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 511 bp->flow_stat->rx_fc_out_tbl.ctx_id, 512 bp->flow_stat->max_fc, 513 true); 514 if (rc) 515 return rc; 516 517 memset(bp->flow_stat->tx_fc_out_tbl.va, 518 0, 519 bp->flow_stat->tx_fc_out_tbl.size); 520 rc = bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX, 521 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 522 bp->flow_stat->tx_fc_out_tbl.ctx_id, 523 bp->flow_stat->max_fc, 524 true); 525 526 return rc; 527 } 528 529 static int bnxt_alloc_ctx_mem_buf(char *type, size_t size, 530 struct bnxt_ctx_mem_buf_info *ctx) 531 { 532 if (!ctx) 533 return -EINVAL; 534 535 ctx->va = rte_zmalloc(type, size, 0); 536 if (ctx->va == NULL) 537 return -ENOMEM; 538 rte_mem_lock_page(ctx->va); 539 ctx->size = size; 540 ctx->dma = rte_mem_virt2iova(ctx->va); 541 if (ctx->dma == RTE_BAD_IOVA) 542 return -ENOMEM; 543 544 return 0; 545 } 546 547 static int bnxt_init_fc_ctx_mem(struct bnxt *bp) 548 { 549 struct rte_pci_device *pdev = bp->pdev; 550 char type[RTE_MEMZONE_NAMESIZE]; 551 uint16_t max_fc; 552 int rc = 0; 553 554 max_fc = bp->flow_stat->max_fc; 555 556 sprintf(type, "bnxt_rx_fc_in_" PCI_PRI_FMT, pdev->addr.domain, 557 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 558 /* 4 bytes for each counter-id */ 559 rc = bnxt_alloc_ctx_mem_buf(type, 560 max_fc * 4, 561 &bp->flow_stat->rx_fc_in_tbl); 562 if (rc) 563 return rc; 564 565 sprintf(type, "bnxt_rx_fc_out_" PCI_PRI_FMT, pdev->addr.domain, 566 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 567 /* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */ 568 rc = bnxt_alloc_ctx_mem_buf(type, 569 max_fc * 16, 570 &bp->flow_stat->rx_fc_out_tbl); 571 if (rc) 572 return rc; 573 574 sprintf(type, "bnxt_tx_fc_in_" PCI_PRI_FMT, pdev->addr.domain, 575 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 576 /* 4 bytes for each counter-id */ 577 rc = bnxt_alloc_ctx_mem_buf(type, 578 max_fc * 4, 579 &bp->flow_stat->tx_fc_in_tbl); 580 if (rc) 581 return rc; 582 583 sprintf(type, "bnxt_tx_fc_out_" PCI_PRI_FMT, pdev->addr.domain, 584 pdev->addr.bus, pdev->addr.devid, pdev->addr.function); 585 /* 16 bytes for each counter - 8 bytes pkt_count, 8 bytes byte_count */ 586 rc = bnxt_alloc_ctx_mem_buf(type, 587 max_fc * 16, 588 &bp->flow_stat->tx_fc_out_tbl); 589 if (rc) 590 return rc; 591 592 rc = bnxt_register_fc_ctx_mem(bp); 593 594 return rc; 595 } 596 597 static int bnxt_init_ctx_mem(struct bnxt *bp) 598 { 599 int rc = 0; 600 601 if (!(bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS) || 602 !(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) || 603 !BNXT_FLOW_XSTATS_EN(bp)) 604 return 0; 605 606 rc = bnxt_hwrm_cfa_counter_qcaps(bp, &bp->flow_stat->max_fc); 607 if (rc) 608 return rc; 609 610 rc = bnxt_init_fc_ctx_mem(bp); 611 612 return rc; 613 } 614 615 static int bnxt_init_chip(struct bnxt *bp) 616 { 617 struct rte_eth_link new; 618 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev); 619 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 620 uint32_t intr_vector = 0; 621 uint32_t queue_id, base = BNXT_MISC_VEC_ID; 622 uint32_t vec = BNXT_MISC_VEC_ID; 623 unsigned int i, j; 624 int rc; 625 626 if (bp->eth_dev->data->mtu > RTE_ETHER_MTU) { 627 bp->eth_dev->data->dev_conf.rxmode.offloads |= 628 DEV_RX_OFFLOAD_JUMBO_FRAME; 629 bp->flags |= BNXT_FLAG_JUMBO; 630 } else { 631 bp->eth_dev->data->dev_conf.rxmode.offloads &= 632 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 633 bp->flags &= ~BNXT_FLAG_JUMBO; 634 } 635 636 /* THOR does not support ring groups. 637 * But we will use the array to save RSS context IDs. 638 */ 639 if (BNXT_CHIP_THOR(bp)) 640 bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR; 641 642 rc = bnxt_alloc_all_hwrm_stat_ctxs(bp); 643 if (rc) { 644 PMD_DRV_LOG(ERR, "HWRM stat ctx alloc failure rc: %x\n", rc); 645 goto err_out; 646 } 647 648 rc = bnxt_alloc_hwrm_rings(bp); 649 if (rc) { 650 PMD_DRV_LOG(ERR, "HWRM ring alloc failure rc: %x\n", rc); 651 goto err_out; 652 } 653 654 rc = bnxt_alloc_all_hwrm_ring_grps(bp); 655 if (rc) { 656 PMD_DRV_LOG(ERR, "HWRM ring grp alloc failure: %x\n", rc); 657 goto err_out; 658 } 659 660 if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_COS_CLASSIFY)) 661 goto skip_cosq_cfg; 662 663 for (j = 0, i = 0; i < BNXT_COS_QUEUE_COUNT; i++) { 664 if (bp->rx_cos_queue[i].id != 0xff) { 665 struct bnxt_vnic_info *vnic = &bp->vnic_info[j++]; 666 667 if (!vnic) { 668 PMD_DRV_LOG(ERR, 669 "Num pools more than FW profile\n"); 670 rc = -EINVAL; 671 goto err_out; 672 } 673 vnic->cos_queue_id = bp->rx_cos_queue[i].id; 674 bp->rx_cosq_cnt++; 675 } 676 } 677 678 skip_cosq_cfg: 679 rc = bnxt_mq_rx_configure(bp); 680 if (rc) { 681 PMD_DRV_LOG(ERR, "MQ mode configure failure rc: %x\n", rc); 682 goto err_out; 683 } 684 685 /* VNIC configuration */ 686 for (i = 0; i < bp->nr_vnics; i++) { 687 rc = bnxt_setup_one_vnic(bp, i); 688 if (rc) 689 goto err_out; 690 } 691 692 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL); 693 if (rc) { 694 PMD_DRV_LOG(ERR, 695 "HWRM cfa l2 rx mask failure rc: %x\n", rc); 696 goto err_out; 697 } 698 699 /* check and configure queue intr-vector mapping */ 700 if ((rte_intr_cap_multiple(intr_handle) || 701 !RTE_ETH_DEV_SRIOV(bp->eth_dev).active) && 702 bp->eth_dev->data->dev_conf.intr_conf.rxq != 0) { 703 intr_vector = bp->eth_dev->data->nb_rx_queues; 704 PMD_DRV_LOG(DEBUG, "intr_vector = %d\n", intr_vector); 705 if (intr_vector > bp->rx_cp_nr_rings) { 706 PMD_DRV_LOG(ERR, "At most %d intr queues supported", 707 bp->rx_cp_nr_rings); 708 return -ENOTSUP; 709 } 710 rc = rte_intr_efd_enable(intr_handle, intr_vector); 711 if (rc) 712 return rc; 713 } 714 715 if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { 716 intr_handle->intr_vec = 717 rte_zmalloc("intr_vec", 718 bp->eth_dev->data->nb_rx_queues * 719 sizeof(int), 0); 720 if (intr_handle->intr_vec == NULL) { 721 PMD_DRV_LOG(ERR, "Failed to allocate %d rx_queues" 722 " intr_vec", bp->eth_dev->data->nb_rx_queues); 723 rc = -ENOMEM; 724 goto err_disable; 725 } 726 PMD_DRV_LOG(DEBUG, "intr_handle->intr_vec = %p " 727 "intr_handle->nb_efd = %d intr_handle->max_intr = %d\n", 728 intr_handle->intr_vec, intr_handle->nb_efd, 729 intr_handle->max_intr); 730 for (queue_id = 0; queue_id < bp->eth_dev->data->nb_rx_queues; 731 queue_id++) { 732 intr_handle->intr_vec[queue_id] = 733 vec + BNXT_RX_VEC_START; 734 if (vec < base + intr_handle->nb_efd - 1) 735 vec++; 736 } 737 } 738 739 /* enable uio/vfio intr/eventfd mapping */ 740 rc = rte_intr_enable(intr_handle); 741 #ifndef RTE_EXEC_ENV_FREEBSD 742 /* In FreeBSD OS, nic_uio driver does not support interrupts */ 743 if (rc) 744 goto err_free; 745 #endif 746 747 rc = bnxt_get_hwrm_link_config(bp, &new); 748 if (rc) { 749 PMD_DRV_LOG(ERR, "HWRM Get link config failure rc: %x\n", rc); 750 goto err_free; 751 } 752 753 if (!bp->link_info->link_up) { 754 rc = bnxt_set_hwrm_link_config(bp, true); 755 if (rc) { 756 PMD_DRV_LOG(ERR, 757 "HWRM link config failure rc: %x\n", rc); 758 goto err_free; 759 } 760 } 761 bnxt_print_link_info(bp->eth_dev); 762 763 bp->mark_table = rte_zmalloc("bnxt_mark_table", BNXT_MARK_TABLE_SZ, 0); 764 if (!bp->mark_table) 765 PMD_DRV_LOG(ERR, "Allocation of mark table failed\n"); 766 767 return 0; 768 769 err_free: 770 rte_free(intr_handle->intr_vec); 771 err_disable: 772 rte_intr_efd_disable(intr_handle); 773 err_out: 774 /* Some of the error status returned by FW may not be from errno.h */ 775 if (rc > 0) 776 rc = -EIO; 777 778 return rc; 779 } 780 781 static int bnxt_shutdown_nic(struct bnxt *bp) 782 { 783 bnxt_free_all_hwrm_resources(bp); 784 bnxt_free_all_filters(bp); 785 bnxt_free_all_vnics(bp); 786 return 0; 787 } 788 789 /* 790 * Device configuration and status function 791 */ 792 793 uint32_t bnxt_get_speed_capabilities(struct bnxt *bp) 794 { 795 uint32_t link_speed = bp->link_info->support_speeds; 796 uint32_t speed_capa = 0; 797 798 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB) 799 speed_capa |= ETH_LINK_SPEED_100M; 800 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD) 801 speed_capa |= ETH_LINK_SPEED_100M_HD; 802 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) 803 speed_capa |= ETH_LINK_SPEED_1G; 804 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) 805 speed_capa |= ETH_LINK_SPEED_2_5G; 806 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 807 speed_capa |= ETH_LINK_SPEED_10G; 808 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB) 809 speed_capa |= ETH_LINK_SPEED_20G; 810 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) 811 speed_capa |= ETH_LINK_SPEED_25G; 812 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 813 speed_capa |= ETH_LINK_SPEED_40G; 814 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) 815 speed_capa |= ETH_LINK_SPEED_50G; 816 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 817 speed_capa |= ETH_LINK_SPEED_100G; 818 if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_200GB) 819 speed_capa |= ETH_LINK_SPEED_200G; 820 821 if (bp->link_info->auto_mode == 822 HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE) 823 speed_capa |= ETH_LINK_SPEED_FIXED; 824 else 825 speed_capa |= ETH_LINK_SPEED_AUTONEG; 826 827 return speed_capa; 828 } 829 830 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, 831 struct rte_eth_dev_info *dev_info) 832 { 833 struct rte_pci_device *pdev = RTE_DEV_TO_PCI(eth_dev->device); 834 struct bnxt *bp = eth_dev->data->dev_private; 835 uint16_t max_vnics, i, j, vpool, vrxq; 836 unsigned int max_rx_rings; 837 int rc; 838 839 rc = is_bnxt_in_error(bp); 840 if (rc) 841 return rc; 842 843 /* MAC Specifics */ 844 dev_info->max_mac_addrs = bp->max_l2_ctx; 845 dev_info->max_hash_mac_addrs = 0; 846 847 /* PF/VF specifics */ 848 if (BNXT_PF(bp)) 849 dev_info->max_vfs = pdev->max_vfs; 850 851 max_rx_rings = BNXT_MAX_RINGS(bp); 852 /* For the sake of symmetry, max_rx_queues = max_tx_queues */ 853 dev_info->max_rx_queues = max_rx_rings; 854 dev_info->max_tx_queues = max_rx_rings; 855 dev_info->reta_size = bnxt_rss_hash_tbl_size(bp); 856 dev_info->hash_key_size = 40; 857 max_vnics = bp->max_vnics; 858 859 /* MTU specifics */ 860 dev_info->min_mtu = RTE_ETHER_MIN_MTU; 861 dev_info->max_mtu = BNXT_MAX_MTU; 862 863 /* Fast path specifics */ 864 dev_info->min_rx_bufsize = 1; 865 dev_info->max_rx_pktlen = BNXT_MAX_PKT_LEN; 866 867 dev_info->rx_offload_capa = BNXT_DEV_RX_OFFLOAD_SUPPORT; 868 if (bp->flags & BNXT_FLAG_PTP_SUPPORTED) 869 dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TIMESTAMP; 870 dev_info->tx_offload_capa = BNXT_DEV_TX_OFFLOAD_SUPPORT; 871 dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; 872 873 dev_info->speed_capa = bnxt_get_speed_capabilities(bp); 874 875 /* *INDENT-OFF* */ 876 dev_info->default_rxconf = (struct rte_eth_rxconf) { 877 .rx_thresh = { 878 .pthresh = 8, 879 .hthresh = 8, 880 .wthresh = 0, 881 }, 882 .rx_free_thresh = 32, 883 /* If no descriptors available, pkts are dropped by default */ 884 .rx_drop_en = 1, 885 }; 886 887 dev_info->default_txconf = (struct rte_eth_txconf) { 888 .tx_thresh = { 889 .pthresh = 32, 890 .hthresh = 0, 891 .wthresh = 0, 892 }, 893 .tx_free_thresh = 32, 894 .tx_rs_thresh = 32, 895 }; 896 eth_dev->data->dev_conf.intr_conf.lsc = 1; 897 898 eth_dev->data->dev_conf.intr_conf.rxq = 1; 899 dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC; 900 dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC; 901 dev_info->tx_desc_lim.nb_min = BNXT_MIN_RING_DESC; 902 dev_info->tx_desc_lim.nb_max = BNXT_MAX_TX_RING_DESC; 903 904 /* *INDENT-ON* */ 905 906 /* 907 * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim 908 * need further investigation. 909 */ 910 911 /* VMDq resources */ 912 vpool = 64; /* ETH_64_POOLS */ 913 vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */ 914 for (i = 0; i < 4; vpool >>= 1, i++) { 915 if (max_vnics > vpool) { 916 for (j = 0; j < 5; vrxq >>= 1, j++) { 917 if (dev_info->max_rx_queues > vrxq) { 918 if (vpool > vrxq) 919 vpool = vrxq; 920 goto found; 921 } 922 } 923 /* Not enough resources to support VMDq */ 924 break; 925 } 926 } 927 /* Not enough resources to support VMDq */ 928 vpool = 0; 929 vrxq = 0; 930 found: 931 dev_info->max_vmdq_pools = vpool; 932 dev_info->vmdq_queue_num = vrxq; 933 934 dev_info->vmdq_pool_base = 0; 935 dev_info->vmdq_queue_base = 0; 936 937 return 0; 938 } 939 940 /* Configure the device based on the configuration provided */ 941 static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) 942 { 943 struct bnxt *bp = eth_dev->data->dev_private; 944 uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 945 int rc; 946 947 bp->rx_queues = (void *)eth_dev->data->rx_queues; 948 bp->tx_queues = (void *)eth_dev->data->tx_queues; 949 bp->tx_nr_rings = eth_dev->data->nb_tx_queues; 950 bp->rx_nr_rings = eth_dev->data->nb_rx_queues; 951 952 rc = is_bnxt_in_error(bp); 953 if (rc) 954 return rc; 955 956 if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) { 957 rc = bnxt_hwrm_check_vf_rings(bp); 958 if (rc) { 959 PMD_DRV_LOG(ERR, "HWRM insufficient resources\n"); 960 return -ENOSPC; 961 } 962 963 /* If a resource has already been allocated - in this case 964 * it is the async completion ring, free it. Reallocate it after 965 * resource reservation. This will ensure the resource counts 966 * are calculated correctly. 967 */ 968 969 pthread_mutex_lock(&bp->def_cp_lock); 970 971 if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { 972 bnxt_disable_int(bp); 973 bnxt_free_cp_ring(bp, bp->async_cp_ring); 974 } 975 976 rc = bnxt_hwrm_func_reserve_vf_resc(bp, false); 977 if (rc) { 978 PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc); 979 pthread_mutex_unlock(&bp->def_cp_lock); 980 return -ENOSPC; 981 } 982 983 if (!BNXT_HAS_NQ(bp) && bp->async_cp_ring) { 984 rc = bnxt_alloc_async_cp_ring(bp); 985 if (rc) { 986 pthread_mutex_unlock(&bp->def_cp_lock); 987 return rc; 988 } 989 bnxt_enable_int(bp); 990 } 991 992 pthread_mutex_unlock(&bp->def_cp_lock); 993 } else { 994 /* legacy driver needs to get updated values */ 995 rc = bnxt_hwrm_func_qcaps(bp); 996 if (rc) { 997 PMD_DRV_LOG(ERR, "hwrm func qcaps fail:%d\n", rc); 998 return rc; 999 } 1000 } 1001 1002 /* Inherit new configurations */ 1003 if (eth_dev->data->nb_rx_queues > bp->max_rx_rings || 1004 eth_dev->data->nb_tx_queues > bp->max_tx_rings || 1005 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues 1006 + BNXT_NUM_ASYNC_CPR(bp) > bp->max_cp_rings || 1007 eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues > 1008 bp->max_stat_ctx) 1009 goto resource_error; 1010 1011 if (BNXT_HAS_RING_GRPS(bp) && 1012 (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps) 1013 goto resource_error; 1014 1015 if (!(eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) && 1016 bp->max_vnics < eth_dev->data->nb_rx_queues) 1017 goto resource_error; 1018 1019 bp->rx_cp_nr_rings = bp->rx_nr_rings; 1020 bp->tx_cp_nr_rings = bp->tx_nr_rings; 1021 1022 if (eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) 1023 rx_offloads |= DEV_RX_OFFLOAD_RSS_HASH; 1024 eth_dev->data->dev_conf.rxmode.offloads = rx_offloads; 1025 1026 if (rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { 1027 eth_dev->data->mtu = 1028 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - 1029 RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN - VLAN_TAG_SIZE * 1030 BNXT_NUM_VLANS; 1031 bnxt_mtu_set_op(eth_dev, eth_dev->data->mtu); 1032 } 1033 return 0; 1034 1035 resource_error: 1036 PMD_DRV_LOG(ERR, 1037 "Insufficient resources to support requested config\n"); 1038 PMD_DRV_LOG(ERR, 1039 "Num Queues Requested: Tx %d, Rx %d\n", 1040 eth_dev->data->nb_tx_queues, 1041 eth_dev->data->nb_rx_queues); 1042 PMD_DRV_LOG(ERR, 1043 "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d\n", 1044 bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings, 1045 bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics); 1046 return -ENOSPC; 1047 } 1048 1049 static void bnxt_print_link_info(struct rte_eth_dev *eth_dev) 1050 { 1051 struct rte_eth_link *link = ð_dev->data->dev_link; 1052 1053 if (link->link_status) 1054 PMD_DRV_LOG(INFO, "Port %d Link Up - speed %u Mbps - %s\n", 1055 eth_dev->data->port_id, 1056 (uint32_t)link->link_speed, 1057 (link->link_duplex == ETH_LINK_FULL_DUPLEX) ? 1058 ("full-duplex") : ("half-duplex\n")); 1059 else 1060 PMD_DRV_LOG(INFO, "Port %d Link Down\n", 1061 eth_dev->data->port_id); 1062 } 1063 1064 /* 1065 * Determine whether the current configuration requires support for scattered 1066 * receive; return 1 if scattered receive is required and 0 if not. 1067 */ 1068 static int bnxt_scattered_rx(struct rte_eth_dev *eth_dev) 1069 { 1070 uint16_t buf_size; 1071 int i; 1072 1073 if (eth_dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) 1074 return 1; 1075 1076 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { 1077 struct bnxt_rx_queue *rxq = eth_dev->data->rx_queues[i]; 1078 1079 buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) - 1080 RTE_PKTMBUF_HEADROOM); 1081 if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len > buf_size) 1082 return 1; 1083 } 1084 return 0; 1085 } 1086 1087 static eth_rx_burst_t 1088 bnxt_receive_function(struct rte_eth_dev *eth_dev) 1089 { 1090 struct bnxt *bp = eth_dev->data->dev_private; 1091 1092 #ifdef RTE_ARCH_X86 1093 #ifndef RTE_LIBRTE_IEEE1588 1094 /* 1095 * Vector mode receive can be enabled only if scatter rx is not 1096 * in use and rx offloads are limited to VLAN stripping and 1097 * CRC stripping. 1098 */ 1099 if (!eth_dev->data->scattered_rx && 1100 !(eth_dev->data->dev_conf.rxmode.offloads & 1101 ~(DEV_RX_OFFLOAD_VLAN_STRIP | 1102 DEV_RX_OFFLOAD_KEEP_CRC | 1103 DEV_RX_OFFLOAD_JUMBO_FRAME | 1104 DEV_RX_OFFLOAD_IPV4_CKSUM | 1105 DEV_RX_OFFLOAD_UDP_CKSUM | 1106 DEV_RX_OFFLOAD_TCP_CKSUM | 1107 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 1108 DEV_RX_OFFLOAD_RSS_HASH | 1109 DEV_RX_OFFLOAD_VLAN_FILTER)) && 1110 !BNXT_TRUFLOW_EN(bp)) { 1111 PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n", 1112 eth_dev->data->port_id); 1113 bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE; 1114 return bnxt_recv_pkts_vec; 1115 } 1116 PMD_DRV_LOG(INFO, "Vector mode receive disabled for port %d\n", 1117 eth_dev->data->port_id); 1118 PMD_DRV_LOG(INFO, 1119 "Port %d scatter: %d rx offload: %" PRIX64 "\n", 1120 eth_dev->data->port_id, 1121 eth_dev->data->scattered_rx, 1122 eth_dev->data->dev_conf.rxmode.offloads); 1123 #endif 1124 #endif 1125 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 1126 return bnxt_recv_pkts; 1127 } 1128 1129 static eth_tx_burst_t 1130 bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev) 1131 { 1132 #ifdef RTE_ARCH_X86 1133 #ifndef RTE_LIBRTE_IEEE1588 1134 /* 1135 * Vector mode transmit can be enabled only if not using scatter rx 1136 * or tx offloads. 1137 */ 1138 if (!eth_dev->data->scattered_rx && 1139 !eth_dev->data->dev_conf.txmode.offloads) { 1140 PMD_DRV_LOG(INFO, "Using vector mode transmit for port %d\n", 1141 eth_dev->data->port_id); 1142 return bnxt_xmit_pkts_vec; 1143 } 1144 PMD_DRV_LOG(INFO, "Vector mode transmit disabled for port %d\n", 1145 eth_dev->data->port_id); 1146 PMD_DRV_LOG(INFO, 1147 "Port %d scatter: %d tx offload: %" PRIX64 "\n", 1148 eth_dev->data->port_id, 1149 eth_dev->data->scattered_rx, 1150 eth_dev->data->dev_conf.txmode.offloads); 1151 #endif 1152 #endif 1153 return bnxt_xmit_pkts; 1154 } 1155 1156 static int bnxt_handle_if_change_status(struct bnxt *bp) 1157 { 1158 int rc; 1159 1160 /* Since fw has undergone a reset and lost all contexts, 1161 * set fatal flag to not issue hwrm during cleanup 1162 */ 1163 bp->flags |= BNXT_FLAG_FATAL_ERROR; 1164 bnxt_uninit_resources(bp, true); 1165 1166 /* clear fatal flag so that re-init happens */ 1167 bp->flags &= ~BNXT_FLAG_FATAL_ERROR; 1168 rc = bnxt_init_resources(bp, true); 1169 1170 bp->flags &= ~BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE; 1171 1172 return rc; 1173 } 1174 1175 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) 1176 { 1177 struct bnxt *bp = eth_dev->data->dev_private; 1178 uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; 1179 int vlan_mask = 0; 1180 int rc, retry_cnt = BNXT_IF_CHANGE_RETRY_COUNT; 1181 1182 if (!eth_dev->data->nb_tx_queues || !eth_dev->data->nb_rx_queues) { 1183 PMD_DRV_LOG(ERR, "Queues are not configured yet!\n"); 1184 return -EINVAL; 1185 } 1186 1187 if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS) { 1188 PMD_DRV_LOG(ERR, 1189 "RxQ cnt %d > CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS %d\n", 1190 bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS); 1191 } 1192 1193 do { 1194 rc = bnxt_hwrm_if_change(bp, true); 1195 if (rc == 0 || rc != -EAGAIN) 1196 break; 1197 1198 rte_delay_ms(BNXT_IF_CHANGE_RETRY_INTERVAL); 1199 } while (retry_cnt--); 1200 1201 if (rc) 1202 return rc; 1203 1204 if (bp->flags & BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE) { 1205 rc = bnxt_handle_if_change_status(bp); 1206 if (rc) 1207 return rc; 1208 } 1209 1210 bnxt_enable_int(bp); 1211 1212 rc = bnxt_init_chip(bp); 1213 if (rc) 1214 goto error; 1215 1216 eth_dev->data->scattered_rx = bnxt_scattered_rx(eth_dev); 1217 eth_dev->data->dev_started = 1; 1218 1219 bnxt_link_update(eth_dev, 1, ETH_LINK_UP); 1220 1221 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 1222 vlan_mask |= ETH_VLAN_FILTER_MASK; 1223 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 1224 vlan_mask |= ETH_VLAN_STRIP_MASK; 1225 rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask); 1226 if (rc) 1227 goto error; 1228 1229 eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev); 1230 eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev); 1231 1232 pthread_mutex_lock(&bp->def_cp_lock); 1233 bnxt_schedule_fw_health_check(bp); 1234 pthread_mutex_unlock(&bp->def_cp_lock); 1235 1236 if (BNXT_TRUFLOW_EN(bp)) 1237 bnxt_ulp_init(bp); 1238 1239 return 0; 1240 1241 error: 1242 bnxt_shutdown_nic(bp); 1243 bnxt_free_tx_mbufs(bp); 1244 bnxt_free_rx_mbufs(bp); 1245 bnxt_hwrm_if_change(bp, false); 1246 eth_dev->data->dev_started = 0; 1247 return rc; 1248 } 1249 1250 static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev) 1251 { 1252 struct bnxt *bp = eth_dev->data->dev_private; 1253 int rc = 0; 1254 1255 if (!bp->link_info->link_up) 1256 rc = bnxt_set_hwrm_link_config(bp, true); 1257 if (!rc) 1258 eth_dev->data->dev_link.link_status = 1; 1259 1260 bnxt_print_link_info(eth_dev); 1261 return rc; 1262 } 1263 1264 static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev) 1265 { 1266 struct bnxt *bp = eth_dev->data->dev_private; 1267 1268 eth_dev->data->dev_link.link_status = 0; 1269 bnxt_set_hwrm_link_config(bp, false); 1270 bp->link_info->link_up = 0; 1271 1272 return 0; 1273 } 1274 1275 /* Unload the driver, release resources */ 1276 static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) 1277 { 1278 struct bnxt *bp = eth_dev->data->dev_private; 1279 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 1280 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 1281 1282 if (BNXT_TRUFLOW_EN(bp)) 1283 bnxt_ulp_deinit(bp); 1284 1285 eth_dev->data->dev_started = 0; 1286 /* Prevent crashes when queues are still in use */ 1287 eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts; 1288 eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts; 1289 1290 bnxt_disable_int(bp); 1291 1292 /* disable uio/vfio intr/eventfd mapping */ 1293 rte_intr_disable(intr_handle); 1294 1295 bnxt_cancel_fw_health_check(bp); 1296 1297 bnxt_dev_set_link_down_op(eth_dev); 1298 1299 /* Wait for link to be reset and the async notification to process. 1300 * During reset recovery, there is no need to wait and 1301 * VF/NPAR functions do not have privilege to change PHY config. 1302 */ 1303 if (!is_bnxt_in_error(bp) && BNXT_SINGLE_PF(bp)) 1304 bnxt_link_update(eth_dev, 1, ETH_LINK_DOWN); 1305 1306 /* Clean queue intr-vector mapping */ 1307 rte_intr_efd_disable(intr_handle); 1308 if (intr_handle->intr_vec != NULL) { 1309 rte_free(intr_handle->intr_vec); 1310 intr_handle->intr_vec = NULL; 1311 } 1312 1313 bnxt_hwrm_port_clr_stats(bp); 1314 bnxt_free_tx_mbufs(bp); 1315 bnxt_free_rx_mbufs(bp); 1316 /* Process any remaining notifications in default completion queue */ 1317 bnxt_int_handler(eth_dev); 1318 bnxt_shutdown_nic(bp); 1319 bnxt_hwrm_if_change(bp, false); 1320 1321 rte_free(bp->mark_table); 1322 bp->mark_table = NULL; 1323 1324 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 1325 bp->rx_cosq_cnt = 0; 1326 /* All filters are deleted on a port stop. */ 1327 if (BNXT_FLOW_XSTATS_EN(bp)) 1328 bp->flow_stat->flow_count = 0; 1329 } 1330 1331 static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev) 1332 { 1333 struct bnxt *bp = eth_dev->data->dev_private; 1334 1335 /* cancel the recovery handler before remove dev */ 1336 rte_eal_alarm_cancel(bnxt_dev_reset_and_resume, (void *)bp); 1337 rte_eal_alarm_cancel(bnxt_dev_recover, (void *)bp); 1338 bnxt_cancel_fc_thread(bp); 1339 1340 if (eth_dev->data->dev_started) 1341 bnxt_dev_stop_op(eth_dev); 1342 1343 bnxt_uninit_resources(bp, false); 1344 1345 bnxt_free_leds_info(bp); 1346 bnxt_free_cos_queues(bp); 1347 bnxt_free_link_info(bp); 1348 bnxt_free_pf_info(bp); 1349 1350 eth_dev->dev_ops = NULL; 1351 eth_dev->rx_pkt_burst = NULL; 1352 eth_dev->tx_pkt_burst = NULL; 1353 1354 rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone); 1355 bp->tx_mem_zone = NULL; 1356 rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone); 1357 bp->rx_mem_zone = NULL; 1358 1359 rte_free(bp->pf->vf_info); 1360 bp->pf->vf_info = NULL; 1361 1362 rte_free(bp->grp_info); 1363 bp->grp_info = NULL; 1364 } 1365 1366 static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, 1367 uint32_t index) 1368 { 1369 struct bnxt *bp = eth_dev->data->dev_private; 1370 uint64_t pool_mask = eth_dev->data->mac_pool_sel[index]; 1371 struct bnxt_vnic_info *vnic; 1372 struct bnxt_filter_info *filter, *temp_filter; 1373 uint32_t i; 1374 1375 if (is_bnxt_in_error(bp)) 1376 return; 1377 1378 /* 1379 * Loop through all VNICs from the specified filter flow pools to 1380 * remove the corresponding MAC addr filter 1381 */ 1382 for (i = 0; i < bp->nr_vnics; i++) { 1383 if (!(pool_mask & (1ULL << i))) 1384 continue; 1385 1386 vnic = &bp->vnic_info[i]; 1387 filter = STAILQ_FIRST(&vnic->filter); 1388 while (filter) { 1389 temp_filter = STAILQ_NEXT(filter, next); 1390 if (filter->mac_index == index) { 1391 STAILQ_REMOVE(&vnic->filter, filter, 1392 bnxt_filter_info, next); 1393 bnxt_hwrm_clear_l2_filter(bp, filter); 1394 bnxt_free_filter(bp, filter); 1395 } 1396 filter = temp_filter; 1397 } 1398 } 1399 } 1400 1401 static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic, 1402 struct rte_ether_addr *mac_addr, uint32_t index, 1403 uint32_t pool) 1404 { 1405 struct bnxt_filter_info *filter; 1406 int rc = 0; 1407 1408 /* Attach requested MAC address to the new l2_filter */ 1409 STAILQ_FOREACH(filter, &vnic->filter, next) { 1410 if (filter->mac_index == index) { 1411 PMD_DRV_LOG(DEBUG, 1412 "MAC addr already existed for pool %d\n", 1413 pool); 1414 return 0; 1415 } 1416 } 1417 1418 filter = bnxt_alloc_filter(bp); 1419 if (!filter) { 1420 PMD_DRV_LOG(ERR, "L2 filter alloc failed\n"); 1421 return -ENODEV; 1422 } 1423 1424 /* bnxt_alloc_filter copies default MAC to filter->l2_addr. So, 1425 * if the MAC that's been programmed now is a different one, then, 1426 * copy that addr to filter->l2_addr 1427 */ 1428 if (mac_addr) 1429 memcpy(filter->l2_addr, mac_addr, RTE_ETHER_ADDR_LEN); 1430 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 1431 1432 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 1433 if (!rc) { 1434 filter->mac_index = index; 1435 if (filter->mac_index == 0) 1436 STAILQ_INSERT_HEAD(&vnic->filter, filter, next); 1437 else 1438 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 1439 } else { 1440 bnxt_free_filter(bp, filter); 1441 } 1442 1443 return rc; 1444 } 1445 1446 static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, 1447 struct rte_ether_addr *mac_addr, 1448 uint32_t index, uint32_t pool) 1449 { 1450 struct bnxt *bp = eth_dev->data->dev_private; 1451 struct bnxt_vnic_info *vnic = &bp->vnic_info[pool]; 1452 int rc = 0; 1453 1454 rc = is_bnxt_in_error(bp); 1455 if (rc) 1456 return rc; 1457 1458 if (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp)) { 1459 PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n"); 1460 return -ENOTSUP; 1461 } 1462 1463 if (!vnic) { 1464 PMD_DRV_LOG(ERR, "VNIC not found for pool %d!\n", pool); 1465 return -EINVAL; 1466 } 1467 1468 /* Filter settings will get applied when port is started */ 1469 if (!eth_dev->data->dev_started) 1470 return 0; 1471 1472 rc = bnxt_add_mac_filter(bp, vnic, mac_addr, index, pool); 1473 1474 return rc; 1475 } 1476 1477 int bnxt_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete, 1478 bool exp_link_status) 1479 { 1480 int rc = 0; 1481 struct bnxt *bp = eth_dev->data->dev_private; 1482 struct rte_eth_link new; 1483 int cnt = exp_link_status ? BNXT_LINK_UP_WAIT_CNT : 1484 BNXT_LINK_DOWN_WAIT_CNT; 1485 1486 rc = is_bnxt_in_error(bp); 1487 if (rc) 1488 return rc; 1489 1490 memset(&new, 0, sizeof(new)); 1491 do { 1492 /* Retrieve link info from hardware */ 1493 rc = bnxt_get_hwrm_link_config(bp, &new); 1494 if (rc) { 1495 new.link_speed = ETH_LINK_SPEED_100M; 1496 new.link_duplex = ETH_LINK_FULL_DUPLEX; 1497 PMD_DRV_LOG(ERR, 1498 "Failed to retrieve link rc = 0x%x!\n", rc); 1499 goto out; 1500 } 1501 1502 if (!wait_to_complete || new.link_status == exp_link_status) 1503 break; 1504 1505 rte_delay_ms(BNXT_LINK_WAIT_INTERVAL); 1506 } while (cnt--); 1507 1508 out: 1509 /* Timed out or success */ 1510 if (new.link_status != eth_dev->data->dev_link.link_status || 1511 new.link_speed != eth_dev->data->dev_link.link_speed) { 1512 rte_eth_linkstatus_set(eth_dev, &new); 1513 1514 _rte_eth_dev_callback_process(eth_dev, 1515 RTE_ETH_EVENT_INTR_LSC, 1516 NULL); 1517 1518 bnxt_print_link_info(eth_dev); 1519 } 1520 1521 return rc; 1522 } 1523 1524 static int bnxt_link_update_op(struct rte_eth_dev *eth_dev, 1525 int wait_to_complete) 1526 { 1527 return bnxt_link_update(eth_dev, wait_to_complete, ETH_LINK_UP); 1528 } 1529 1530 static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) 1531 { 1532 struct bnxt *bp = eth_dev->data->dev_private; 1533 struct bnxt_vnic_info *vnic; 1534 uint32_t old_flags; 1535 int rc; 1536 1537 rc = is_bnxt_in_error(bp); 1538 if (rc) 1539 return rc; 1540 1541 /* Filter settings will get applied when port is started */ 1542 if (!eth_dev->data->dev_started) 1543 return 0; 1544 1545 if (bp->vnic_info == NULL) 1546 return 0; 1547 1548 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1549 1550 old_flags = vnic->flags; 1551 vnic->flags |= BNXT_VNIC_INFO_PROMISC; 1552 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1553 if (rc != 0) 1554 vnic->flags = old_flags; 1555 1556 return rc; 1557 } 1558 1559 static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) 1560 { 1561 struct bnxt *bp = eth_dev->data->dev_private; 1562 struct bnxt_vnic_info *vnic; 1563 uint32_t old_flags; 1564 int rc; 1565 1566 rc = is_bnxt_in_error(bp); 1567 if (rc) 1568 return rc; 1569 1570 /* Filter settings will get applied when port is started */ 1571 if (!eth_dev->data->dev_started) 1572 return 0; 1573 1574 if (bp->vnic_info == NULL) 1575 return 0; 1576 1577 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1578 1579 old_flags = vnic->flags; 1580 vnic->flags &= ~BNXT_VNIC_INFO_PROMISC; 1581 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1582 if (rc != 0) 1583 vnic->flags = old_flags; 1584 1585 return rc; 1586 } 1587 1588 static int bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) 1589 { 1590 struct bnxt *bp = eth_dev->data->dev_private; 1591 struct bnxt_vnic_info *vnic; 1592 uint32_t old_flags; 1593 int rc; 1594 1595 rc = is_bnxt_in_error(bp); 1596 if (rc) 1597 return rc; 1598 1599 /* Filter settings will get applied when port is started */ 1600 if (!eth_dev->data->dev_started) 1601 return 0; 1602 1603 if (bp->vnic_info == NULL) 1604 return 0; 1605 1606 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1607 1608 old_flags = vnic->flags; 1609 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 1610 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1611 if (rc != 0) 1612 vnic->flags = old_flags; 1613 1614 return rc; 1615 } 1616 1617 static int bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) 1618 { 1619 struct bnxt *bp = eth_dev->data->dev_private; 1620 struct bnxt_vnic_info *vnic; 1621 uint32_t old_flags; 1622 int rc; 1623 1624 rc = is_bnxt_in_error(bp); 1625 if (rc) 1626 return rc; 1627 1628 /* Filter settings will get applied when port is started */ 1629 if (!eth_dev->data->dev_started) 1630 return 0; 1631 1632 if (bp->vnic_info == NULL) 1633 return 0; 1634 1635 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1636 1637 old_flags = vnic->flags; 1638 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 1639 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 1640 if (rc != 0) 1641 vnic->flags = old_flags; 1642 1643 return rc; 1644 } 1645 1646 /* Return bnxt_rx_queue pointer corresponding to a given rxq. */ 1647 static struct bnxt_rx_queue *bnxt_qid_to_rxq(struct bnxt *bp, uint16_t qid) 1648 { 1649 if (qid >= bp->rx_nr_rings) 1650 return NULL; 1651 1652 return bp->eth_dev->data->rx_queues[qid]; 1653 } 1654 1655 /* Return rxq corresponding to a given rss table ring/group ID. */ 1656 static uint16_t bnxt_rss_to_qid(struct bnxt *bp, uint16_t fwr) 1657 { 1658 struct bnxt_rx_queue *rxq; 1659 unsigned int i; 1660 1661 if (!BNXT_HAS_RING_GRPS(bp)) { 1662 for (i = 0; i < bp->rx_nr_rings; i++) { 1663 rxq = bp->eth_dev->data->rx_queues[i]; 1664 if (rxq->rx_ring->rx_ring_struct->fw_ring_id == fwr) 1665 return rxq->index; 1666 } 1667 } else { 1668 for (i = 0; i < bp->rx_nr_rings; i++) { 1669 if (bp->grp_info[i].fw_grp_id == fwr) 1670 return i; 1671 } 1672 } 1673 1674 return INVALID_HW_RING_ID; 1675 } 1676 1677 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, 1678 struct rte_eth_rss_reta_entry64 *reta_conf, 1679 uint16_t reta_size) 1680 { 1681 struct bnxt *bp = eth_dev->data->dev_private; 1682 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 1683 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1684 uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); 1685 uint16_t idx, sft; 1686 int i, rc; 1687 1688 rc = is_bnxt_in_error(bp); 1689 if (rc) 1690 return rc; 1691 1692 if (!vnic->rss_table) 1693 return -EINVAL; 1694 1695 if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)) 1696 return -EINVAL; 1697 1698 if (reta_size != tbl_size) { 1699 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 1700 "(%d) must equal the size supported by the hardware " 1701 "(%d)\n", reta_size, tbl_size); 1702 return -EINVAL; 1703 } 1704 1705 for (i = 0; i < reta_size; i++) { 1706 struct bnxt_rx_queue *rxq; 1707 1708 idx = i / RTE_RETA_GROUP_SIZE; 1709 sft = i % RTE_RETA_GROUP_SIZE; 1710 1711 if (!(reta_conf[idx].mask & (1ULL << sft))) 1712 continue; 1713 1714 rxq = bnxt_qid_to_rxq(bp, reta_conf[idx].reta[sft]); 1715 if (!rxq) { 1716 PMD_DRV_LOG(ERR, "Invalid ring in reta_conf.\n"); 1717 return -EINVAL; 1718 } 1719 1720 if (BNXT_CHIP_THOR(bp)) { 1721 vnic->rss_table[i * 2] = 1722 rxq->rx_ring->rx_ring_struct->fw_ring_id; 1723 vnic->rss_table[i * 2 + 1] = 1724 rxq->cp_ring->cp_ring_struct->fw_ring_id; 1725 } else { 1726 vnic->rss_table[i] = 1727 vnic->fw_grp_ids[reta_conf[idx].reta[sft]]; 1728 } 1729 } 1730 1731 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 1732 return 0; 1733 } 1734 1735 static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, 1736 struct rte_eth_rss_reta_entry64 *reta_conf, 1737 uint16_t reta_size) 1738 { 1739 struct bnxt *bp = eth_dev->data->dev_private; 1740 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1741 uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); 1742 uint16_t idx, sft, i; 1743 int rc; 1744 1745 rc = is_bnxt_in_error(bp); 1746 if (rc) 1747 return rc; 1748 1749 /* Retrieve from the default VNIC */ 1750 if (!vnic) 1751 return -EINVAL; 1752 if (!vnic->rss_table) 1753 return -EINVAL; 1754 1755 if (reta_size != tbl_size) { 1756 PMD_DRV_LOG(ERR, "The configured hash table lookup size " 1757 "(%d) must equal the size supported by the hardware " 1758 "(%d)\n", reta_size, tbl_size); 1759 return -EINVAL; 1760 } 1761 1762 for (idx = 0, i = 0; i < reta_size; i++) { 1763 idx = i / RTE_RETA_GROUP_SIZE; 1764 sft = i % RTE_RETA_GROUP_SIZE; 1765 1766 if (reta_conf[idx].mask & (1ULL << sft)) { 1767 uint16_t qid; 1768 1769 if (BNXT_CHIP_THOR(bp)) 1770 qid = bnxt_rss_to_qid(bp, 1771 vnic->rss_table[i * 2]); 1772 else 1773 qid = bnxt_rss_to_qid(bp, vnic->rss_table[i]); 1774 1775 if (qid == INVALID_HW_RING_ID) { 1776 PMD_DRV_LOG(ERR, "Inv. entry in rss table.\n"); 1777 return -EINVAL; 1778 } 1779 reta_conf[idx].reta[sft] = qid; 1780 } 1781 } 1782 1783 return 0; 1784 } 1785 1786 static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, 1787 struct rte_eth_rss_conf *rss_conf) 1788 { 1789 struct bnxt *bp = eth_dev->data->dev_private; 1790 struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; 1791 struct bnxt_vnic_info *vnic; 1792 int rc; 1793 1794 rc = is_bnxt_in_error(bp); 1795 if (rc) 1796 return rc; 1797 1798 /* 1799 * If RSS enablement were different than dev_configure, 1800 * then return -EINVAL 1801 */ 1802 if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { 1803 if (!rss_conf->rss_hf) 1804 PMD_DRV_LOG(ERR, "Hash type NONE\n"); 1805 } else { 1806 if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT) 1807 return -EINVAL; 1808 } 1809 1810 bp->flags |= BNXT_FLAG_UPDATE_HASH; 1811 memcpy(ð_dev->data->dev_conf.rx_adv_conf.rss_conf, 1812 rss_conf, 1813 sizeof(*rss_conf)); 1814 1815 /* Update the default RSS VNIC(s) */ 1816 vnic = BNXT_GET_DEFAULT_VNIC(bp); 1817 vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf); 1818 1819 /* 1820 * If hashkey is not specified, use the previously configured 1821 * hashkey 1822 */ 1823 if (!rss_conf->rss_key) 1824 goto rss_config; 1825 1826 if (rss_conf->rss_key_len != HW_HASH_KEY_SIZE) { 1827 PMD_DRV_LOG(ERR, 1828 "Invalid hashkey length, should be 16 bytes\n"); 1829 return -EINVAL; 1830 } 1831 memcpy(vnic->rss_hash_key, rss_conf->rss_key, rss_conf->rss_key_len); 1832 1833 rss_config: 1834 bnxt_hwrm_vnic_rss_cfg(bp, vnic); 1835 return 0; 1836 } 1837 1838 static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, 1839 struct rte_eth_rss_conf *rss_conf) 1840 { 1841 struct bnxt *bp = eth_dev->data->dev_private; 1842 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 1843 int len, rc; 1844 uint32_t hash_types; 1845 1846 rc = is_bnxt_in_error(bp); 1847 if (rc) 1848 return rc; 1849 1850 /* RSS configuration is the same for all VNICs */ 1851 if (vnic && vnic->rss_hash_key) { 1852 if (rss_conf->rss_key) { 1853 len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ? 1854 rss_conf->rss_key_len : HW_HASH_KEY_SIZE; 1855 memcpy(rss_conf->rss_key, vnic->rss_hash_key, len); 1856 } 1857 1858 hash_types = vnic->hash_type; 1859 rss_conf->rss_hf = 0; 1860 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) { 1861 rss_conf->rss_hf |= ETH_RSS_IPV4; 1862 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; 1863 } 1864 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) { 1865 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 1866 hash_types &= 1867 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; 1868 } 1869 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) { 1870 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 1871 hash_types &= 1872 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; 1873 } 1874 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) { 1875 rss_conf->rss_hf |= ETH_RSS_IPV6; 1876 hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; 1877 } 1878 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) { 1879 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 1880 hash_types &= 1881 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; 1882 } 1883 if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) { 1884 rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 1885 hash_types &= 1886 ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 1887 } 1888 if (hash_types) { 1889 PMD_DRV_LOG(ERR, 1890 "Unknown RSS config from firmware (%08x), RSS disabled", 1891 vnic->hash_type); 1892 return -ENOTSUP; 1893 } 1894 } else { 1895 rss_conf->rss_hf = 0; 1896 } 1897 return 0; 1898 } 1899 1900 static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev, 1901 struct rte_eth_fc_conf *fc_conf) 1902 { 1903 struct bnxt *bp = dev->data->dev_private; 1904 struct rte_eth_link link_info; 1905 int rc; 1906 1907 rc = is_bnxt_in_error(bp); 1908 if (rc) 1909 return rc; 1910 1911 rc = bnxt_get_hwrm_link_config(bp, &link_info); 1912 if (rc) 1913 return rc; 1914 1915 memset(fc_conf, 0, sizeof(*fc_conf)); 1916 if (bp->link_info->auto_pause) 1917 fc_conf->autoneg = 1; 1918 switch (bp->link_info->pause) { 1919 case 0: 1920 fc_conf->mode = RTE_FC_NONE; 1921 break; 1922 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX: 1923 fc_conf->mode = RTE_FC_TX_PAUSE; 1924 break; 1925 case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX: 1926 fc_conf->mode = RTE_FC_RX_PAUSE; 1927 break; 1928 case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1929 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX): 1930 fc_conf->mode = RTE_FC_FULL; 1931 break; 1932 } 1933 return 0; 1934 } 1935 1936 static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, 1937 struct rte_eth_fc_conf *fc_conf) 1938 { 1939 struct bnxt *bp = dev->data->dev_private; 1940 int rc; 1941 1942 rc = is_bnxt_in_error(bp); 1943 if (rc) 1944 return rc; 1945 1946 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 1947 PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n"); 1948 return -ENOTSUP; 1949 } 1950 1951 switch (fc_conf->mode) { 1952 case RTE_FC_NONE: 1953 bp->link_info->auto_pause = 0; 1954 bp->link_info->force_pause = 0; 1955 break; 1956 case RTE_FC_RX_PAUSE: 1957 if (fc_conf->autoneg) { 1958 bp->link_info->auto_pause = 1959 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 1960 bp->link_info->force_pause = 0; 1961 } else { 1962 bp->link_info->auto_pause = 0; 1963 bp->link_info->force_pause = 1964 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 1965 } 1966 break; 1967 case RTE_FC_TX_PAUSE: 1968 if (fc_conf->autoneg) { 1969 bp->link_info->auto_pause = 1970 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; 1971 bp->link_info->force_pause = 0; 1972 } else { 1973 bp->link_info->auto_pause = 0; 1974 bp->link_info->force_pause = 1975 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; 1976 } 1977 break; 1978 case RTE_FC_FULL: 1979 if (fc_conf->autoneg) { 1980 bp->link_info->auto_pause = 1981 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX | 1982 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 1983 bp->link_info->force_pause = 0; 1984 } else { 1985 bp->link_info->auto_pause = 0; 1986 bp->link_info->force_pause = 1987 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX | 1988 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 1989 } 1990 break; 1991 } 1992 return bnxt_set_hwrm_link_config(bp, true); 1993 } 1994 1995 /* Add UDP tunneling port */ 1996 static int 1997 bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, 1998 struct rte_eth_udp_tunnel *udp_tunnel) 1999 { 2000 struct bnxt *bp = eth_dev->data->dev_private; 2001 uint16_t tunnel_type = 0; 2002 int rc = 0; 2003 2004 rc = is_bnxt_in_error(bp); 2005 if (rc) 2006 return rc; 2007 2008 switch (udp_tunnel->prot_type) { 2009 case RTE_TUNNEL_TYPE_VXLAN: 2010 if (bp->vxlan_port_cnt) { 2011 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 2012 udp_tunnel->udp_port); 2013 if (bp->vxlan_port != udp_tunnel->udp_port) { 2014 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 2015 return -ENOSPC; 2016 } 2017 bp->vxlan_port_cnt++; 2018 return 0; 2019 } 2020 tunnel_type = 2021 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN; 2022 bp->vxlan_port_cnt++; 2023 break; 2024 case RTE_TUNNEL_TYPE_GENEVE: 2025 if (bp->geneve_port_cnt) { 2026 PMD_DRV_LOG(ERR, "Tunnel Port %d already programmed\n", 2027 udp_tunnel->udp_port); 2028 if (bp->geneve_port != udp_tunnel->udp_port) { 2029 PMD_DRV_LOG(ERR, "Only one port allowed\n"); 2030 return -ENOSPC; 2031 } 2032 bp->geneve_port_cnt++; 2033 return 0; 2034 } 2035 tunnel_type = 2036 HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE; 2037 bp->geneve_port_cnt++; 2038 break; 2039 default: 2040 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 2041 return -ENOTSUP; 2042 } 2043 rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port, 2044 tunnel_type); 2045 return rc; 2046 } 2047 2048 static int 2049 bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev, 2050 struct rte_eth_udp_tunnel *udp_tunnel) 2051 { 2052 struct bnxt *bp = eth_dev->data->dev_private; 2053 uint16_t tunnel_type = 0; 2054 uint16_t port = 0; 2055 int rc = 0; 2056 2057 rc = is_bnxt_in_error(bp); 2058 if (rc) 2059 return rc; 2060 2061 switch (udp_tunnel->prot_type) { 2062 case RTE_TUNNEL_TYPE_VXLAN: 2063 if (!bp->vxlan_port_cnt) { 2064 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 2065 return -EINVAL; 2066 } 2067 if (bp->vxlan_port != udp_tunnel->udp_port) { 2068 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 2069 udp_tunnel->udp_port, bp->vxlan_port); 2070 return -EINVAL; 2071 } 2072 if (--bp->vxlan_port_cnt) 2073 return 0; 2074 2075 tunnel_type = 2076 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN; 2077 port = bp->vxlan_fw_dst_port_id; 2078 break; 2079 case RTE_TUNNEL_TYPE_GENEVE: 2080 if (!bp->geneve_port_cnt) { 2081 PMD_DRV_LOG(ERR, "No Tunnel port configured yet\n"); 2082 return -EINVAL; 2083 } 2084 if (bp->geneve_port != udp_tunnel->udp_port) { 2085 PMD_DRV_LOG(ERR, "Req Port: %d. Configured port: %d\n", 2086 udp_tunnel->udp_port, bp->geneve_port); 2087 return -EINVAL; 2088 } 2089 if (--bp->geneve_port_cnt) 2090 return 0; 2091 2092 tunnel_type = 2093 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE; 2094 port = bp->geneve_fw_dst_port_id; 2095 break; 2096 default: 2097 PMD_DRV_LOG(ERR, "Tunnel type is not supported\n"); 2098 return -ENOTSUP; 2099 } 2100 2101 rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type); 2102 if (!rc) { 2103 if (tunnel_type == 2104 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN) 2105 bp->vxlan_port = 0; 2106 if (tunnel_type == 2107 HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE) 2108 bp->geneve_port = 0; 2109 } 2110 return rc; 2111 } 2112 2113 static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 2114 { 2115 struct bnxt_filter_info *filter; 2116 struct bnxt_vnic_info *vnic; 2117 int rc = 0; 2118 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN; 2119 2120 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2121 filter = STAILQ_FIRST(&vnic->filter); 2122 while (filter) { 2123 /* Search for this matching MAC+VLAN filter */ 2124 if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id)) { 2125 /* Delete the filter */ 2126 rc = bnxt_hwrm_clear_l2_filter(bp, filter); 2127 if (rc) 2128 return rc; 2129 STAILQ_REMOVE(&vnic->filter, filter, 2130 bnxt_filter_info, next); 2131 bnxt_free_filter(bp, filter); 2132 PMD_DRV_LOG(INFO, 2133 "Deleted vlan filter for %d\n", 2134 vlan_id); 2135 return 0; 2136 } 2137 filter = STAILQ_NEXT(filter, next); 2138 } 2139 return -ENOENT; 2140 } 2141 2142 static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id) 2143 { 2144 struct bnxt_filter_info *filter; 2145 struct bnxt_vnic_info *vnic; 2146 int rc = 0; 2147 uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN | 2148 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK; 2149 uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN; 2150 2151 /* Implementation notes on the use of VNIC in this command: 2152 * 2153 * By default, these filters belong to default vnic for the function. 2154 * Once these filters are set up, only destination VNIC can be modified. 2155 * If the destination VNIC is not specified in this command, 2156 * then the HWRM shall only create an l2 context id. 2157 */ 2158 2159 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2160 filter = STAILQ_FIRST(&vnic->filter); 2161 /* Check if the VLAN has already been added */ 2162 while (filter) { 2163 if (bnxt_vlan_filter_exists(bp, filter, chk, vlan_id)) 2164 return -EEXIST; 2165 2166 filter = STAILQ_NEXT(filter, next); 2167 } 2168 2169 /* No match found. Alloc a fresh filter and issue the L2_FILTER_ALLOC 2170 * command to create MAC+VLAN filter with the right flags, enables set. 2171 */ 2172 filter = bnxt_alloc_filter(bp); 2173 if (!filter) { 2174 PMD_DRV_LOG(ERR, 2175 "MAC/VLAN filter alloc failed\n"); 2176 return -ENOMEM; 2177 } 2178 /* MAC + VLAN ID filter */ 2179 /* If l2_ivlan == 0 and l2_ivlan_mask != 0, only 2180 * untagged packets are received 2181 * 2182 * If l2_ivlan != 0 and l2_ivlan_mask != 0, untagged 2183 * packets and only the programmed vlan's packets are received 2184 */ 2185 filter->l2_ivlan = vlan_id; 2186 filter->l2_ivlan_mask = 0x0FFF; 2187 filter->enables |= en; 2188 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST; 2189 2190 rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter); 2191 if (rc) { 2192 /* Free the newly allocated filter as we were 2193 * not able to create the filter in hardware. 2194 */ 2195 bnxt_free_filter(bp, filter); 2196 return rc; 2197 } 2198 2199 filter->mac_index = 0; 2200 /* Add this new filter to the list */ 2201 if (vlan_id == 0) 2202 STAILQ_INSERT_HEAD(&vnic->filter, filter, next); 2203 else 2204 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 2205 2206 PMD_DRV_LOG(INFO, 2207 "Added Vlan filter for %d\n", vlan_id); 2208 return rc; 2209 } 2210 2211 static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, 2212 uint16_t vlan_id, int on) 2213 { 2214 struct bnxt *bp = eth_dev->data->dev_private; 2215 int rc; 2216 2217 rc = is_bnxt_in_error(bp); 2218 if (rc) 2219 return rc; 2220 2221 if (!eth_dev->data->dev_started) { 2222 PMD_DRV_LOG(ERR, "port must be started before setting vlan\n"); 2223 return -EINVAL; 2224 } 2225 2226 /* These operations apply to ALL existing MAC/VLAN filters */ 2227 if (on) 2228 return bnxt_add_vlan_filter(bp, vlan_id); 2229 else 2230 return bnxt_del_vlan_filter(bp, vlan_id); 2231 } 2232 2233 static int bnxt_del_dflt_mac_filter(struct bnxt *bp, 2234 struct bnxt_vnic_info *vnic) 2235 { 2236 struct bnxt_filter_info *filter; 2237 int rc; 2238 2239 filter = STAILQ_FIRST(&vnic->filter); 2240 while (filter) { 2241 if (filter->mac_index == 0 && 2242 !memcmp(filter->l2_addr, bp->mac_addr, 2243 RTE_ETHER_ADDR_LEN)) { 2244 rc = bnxt_hwrm_clear_l2_filter(bp, filter); 2245 if (!rc) { 2246 STAILQ_REMOVE(&vnic->filter, filter, 2247 bnxt_filter_info, next); 2248 bnxt_free_filter(bp, filter); 2249 } 2250 return rc; 2251 } 2252 filter = STAILQ_NEXT(filter, next); 2253 } 2254 return 0; 2255 } 2256 2257 static int 2258 bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads) 2259 { 2260 struct bnxt_vnic_info *vnic; 2261 unsigned int i; 2262 int rc; 2263 2264 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2265 if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) { 2266 /* Remove any VLAN filters programmed */ 2267 for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++) 2268 bnxt_del_vlan_filter(bp, i); 2269 2270 rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0); 2271 if (rc) 2272 return rc; 2273 } else { 2274 /* Default filter will allow packets that match the 2275 * dest mac. So, it has to be deleted, otherwise, we 2276 * will endup receiving vlan packets for which the 2277 * filter is not programmed, when hw-vlan-filter 2278 * configuration is ON 2279 */ 2280 bnxt_del_dflt_mac_filter(bp, vnic); 2281 /* This filter will allow only untagged packets */ 2282 bnxt_add_vlan_filter(bp, 0); 2283 } 2284 PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n", 2285 !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)); 2286 2287 return 0; 2288 } 2289 2290 static int bnxt_free_one_vnic(struct bnxt *bp, uint16_t vnic_id) 2291 { 2292 struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id]; 2293 unsigned int i; 2294 int rc; 2295 2296 /* Destroy vnic filters and vnic */ 2297 if (bp->eth_dev->data->dev_conf.rxmode.offloads & 2298 DEV_RX_OFFLOAD_VLAN_FILTER) { 2299 for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++) 2300 bnxt_del_vlan_filter(bp, i); 2301 } 2302 bnxt_del_dflt_mac_filter(bp, vnic); 2303 2304 rc = bnxt_hwrm_vnic_free(bp, vnic); 2305 if (rc) 2306 return rc; 2307 2308 rte_free(vnic->fw_grp_ids); 2309 vnic->fw_grp_ids = NULL; 2310 2311 vnic->rx_queue_cnt = 0; 2312 2313 return 0; 2314 } 2315 2316 static int 2317 bnxt_config_vlan_hw_stripping(struct bnxt *bp, uint64_t rx_offloads) 2318 { 2319 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 2320 int rc; 2321 2322 /* Destroy, recreate and reconfigure the default vnic */ 2323 rc = bnxt_free_one_vnic(bp, 0); 2324 if (rc) 2325 return rc; 2326 2327 /* default vnic 0 */ 2328 rc = bnxt_setup_one_vnic(bp, 0); 2329 if (rc) 2330 return rc; 2331 2332 if (bp->eth_dev->data->dev_conf.rxmode.offloads & 2333 DEV_RX_OFFLOAD_VLAN_FILTER) { 2334 rc = bnxt_add_vlan_filter(bp, 0); 2335 if (rc) 2336 return rc; 2337 rc = bnxt_restore_vlan_filters(bp); 2338 if (rc) 2339 return rc; 2340 } else { 2341 rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0); 2342 if (rc) 2343 return rc; 2344 } 2345 2346 rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 2347 if (rc) 2348 return rc; 2349 2350 PMD_DRV_LOG(DEBUG, "VLAN Strip Offload: %d\n", 2351 !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)); 2352 2353 return rc; 2354 } 2355 2356 static int 2357 bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) 2358 { 2359 uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads; 2360 struct bnxt *bp = dev->data->dev_private; 2361 int rc; 2362 2363 rc = is_bnxt_in_error(bp); 2364 if (rc) 2365 return rc; 2366 2367 /* Filter settings will get applied when port is started */ 2368 if (!dev->data->dev_started) 2369 return 0; 2370 2371 if (mask & ETH_VLAN_FILTER_MASK) { 2372 /* Enable or disable VLAN filtering */ 2373 rc = bnxt_config_vlan_hw_filter(bp, rx_offloads); 2374 if (rc) 2375 return rc; 2376 } 2377 2378 if (mask & ETH_VLAN_STRIP_MASK) { 2379 /* Enable or disable VLAN stripping */ 2380 rc = bnxt_config_vlan_hw_stripping(bp, rx_offloads); 2381 if (rc) 2382 return rc; 2383 } 2384 2385 if (mask & ETH_VLAN_EXTEND_MASK) { 2386 if (rx_offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) 2387 PMD_DRV_LOG(DEBUG, "Extend VLAN supported\n"); 2388 else 2389 PMD_DRV_LOG(INFO, "Extend VLAN unsupported\n"); 2390 } 2391 2392 return 0; 2393 } 2394 2395 static int 2396 bnxt_vlan_tpid_set_op(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type, 2397 uint16_t tpid) 2398 { 2399 struct bnxt *bp = dev->data->dev_private; 2400 int qinq = dev->data->dev_conf.rxmode.offloads & 2401 DEV_RX_OFFLOAD_VLAN_EXTEND; 2402 2403 if (vlan_type != ETH_VLAN_TYPE_INNER && 2404 vlan_type != ETH_VLAN_TYPE_OUTER) { 2405 PMD_DRV_LOG(ERR, 2406 "Unsupported vlan type."); 2407 return -EINVAL; 2408 } 2409 if (!qinq) { 2410 PMD_DRV_LOG(ERR, 2411 "QinQ not enabled. Needs to be ON as we can " 2412 "accelerate only outer vlan\n"); 2413 return -EINVAL; 2414 } 2415 2416 if (vlan_type == ETH_VLAN_TYPE_OUTER) { 2417 switch (tpid) { 2418 case RTE_ETHER_TYPE_QINQ: 2419 bp->outer_tpid_bd = 2420 TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8; 2421 break; 2422 case RTE_ETHER_TYPE_VLAN: 2423 bp->outer_tpid_bd = 2424 TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100; 2425 break; 2426 case 0x9100: 2427 bp->outer_tpid_bd = 2428 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100; 2429 break; 2430 case 0x9200: 2431 bp->outer_tpid_bd = 2432 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200; 2433 break; 2434 case 0x9300: 2435 bp->outer_tpid_bd = 2436 TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300; 2437 break; 2438 default: 2439 PMD_DRV_LOG(ERR, "Invalid TPID: %x\n", tpid); 2440 return -EINVAL; 2441 } 2442 bp->outer_tpid_bd |= tpid; 2443 PMD_DRV_LOG(INFO, "outer_tpid_bd = %x\n", bp->outer_tpid_bd); 2444 } else if (vlan_type == ETH_VLAN_TYPE_INNER) { 2445 PMD_DRV_LOG(ERR, 2446 "Can accelerate only outer vlan in QinQ\n"); 2447 return -EINVAL; 2448 } 2449 2450 return 0; 2451 } 2452 2453 static int 2454 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, 2455 struct rte_ether_addr *addr) 2456 { 2457 struct bnxt *bp = dev->data->dev_private; 2458 /* Default Filter is tied to VNIC 0 */ 2459 struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp); 2460 int rc; 2461 2462 rc = is_bnxt_in_error(bp); 2463 if (rc) 2464 return rc; 2465 2466 if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) 2467 return -EPERM; 2468 2469 if (rte_is_zero_ether_addr(addr)) 2470 return -EINVAL; 2471 2472 /* Filter settings will get applied when port is started */ 2473 if (!dev->data->dev_started) 2474 return 0; 2475 2476 /* Check if the requested MAC is already added */ 2477 if (memcmp(addr, bp->mac_addr, RTE_ETHER_ADDR_LEN) == 0) 2478 return 0; 2479 2480 /* Destroy filter and re-create it */ 2481 bnxt_del_dflt_mac_filter(bp, vnic); 2482 2483 memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN); 2484 if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_FILTER) { 2485 /* This filter will allow only untagged packets */ 2486 rc = bnxt_add_vlan_filter(bp, 0); 2487 } else { 2488 rc = bnxt_add_mac_filter(bp, vnic, addr, 0, 0); 2489 } 2490 2491 PMD_DRV_LOG(DEBUG, "Set MAC addr\n"); 2492 return rc; 2493 } 2494 2495 static int 2496 bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, 2497 struct rte_ether_addr *mc_addr_set, 2498 uint32_t nb_mc_addr) 2499 { 2500 struct bnxt *bp = eth_dev->data->dev_private; 2501 char *mc_addr_list = (char *)mc_addr_set; 2502 struct bnxt_vnic_info *vnic; 2503 uint32_t off = 0, i = 0; 2504 int rc; 2505 2506 rc = is_bnxt_in_error(bp); 2507 if (rc) 2508 return rc; 2509 2510 vnic = BNXT_GET_DEFAULT_VNIC(bp); 2511 2512 if (nb_mc_addr > BNXT_MAX_MC_ADDRS) { 2513 vnic->flags |= BNXT_VNIC_INFO_ALLMULTI; 2514 goto allmulti; 2515 } 2516 2517 /* TODO Check for Duplicate mcast addresses */ 2518 vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI; 2519 for (i = 0; i < nb_mc_addr; i++) { 2520 memcpy(vnic->mc_list + off, &mc_addr_list[i], 2521 RTE_ETHER_ADDR_LEN); 2522 off += RTE_ETHER_ADDR_LEN; 2523 } 2524 2525 vnic->mc_addr_cnt = i; 2526 if (vnic->mc_addr_cnt) 2527 vnic->flags |= BNXT_VNIC_INFO_MCAST; 2528 else 2529 vnic->flags &= ~BNXT_VNIC_INFO_MCAST; 2530 2531 allmulti: 2532 return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); 2533 } 2534 2535 static int 2536 bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) 2537 { 2538 struct bnxt *bp = dev->data->dev_private; 2539 uint8_t fw_major = (bp->fw_ver >> 24) & 0xff; 2540 uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff; 2541 uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff; 2542 uint8_t fw_rsvd = bp->fw_ver & 0xff; 2543 int ret; 2544 2545 ret = snprintf(fw_version, fw_size, "%d.%d.%d.%d", 2546 fw_major, fw_minor, fw_updt, fw_rsvd); 2547 2548 ret += 1; /* add the size of '\0' */ 2549 if (fw_size < (uint32_t)ret) 2550 return ret; 2551 else 2552 return 0; 2553 } 2554 2555 static void 2556 bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 2557 struct rte_eth_rxq_info *qinfo) 2558 { 2559 struct bnxt *bp = dev->data->dev_private; 2560 struct bnxt_rx_queue *rxq; 2561 2562 if (is_bnxt_in_error(bp)) 2563 return; 2564 2565 rxq = dev->data->rx_queues[queue_id]; 2566 2567 qinfo->mp = rxq->mb_pool; 2568 qinfo->scattered_rx = dev->data->scattered_rx; 2569 qinfo->nb_desc = rxq->nb_rx_desc; 2570 2571 qinfo->conf.rx_free_thresh = rxq->rx_free_thresh; 2572 qinfo->conf.rx_drop_en = 0; 2573 qinfo->conf.rx_deferred_start = rxq->rx_deferred_start; 2574 } 2575 2576 static void 2577 bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id, 2578 struct rte_eth_txq_info *qinfo) 2579 { 2580 struct bnxt *bp = dev->data->dev_private; 2581 struct bnxt_tx_queue *txq; 2582 2583 if (is_bnxt_in_error(bp)) 2584 return; 2585 2586 txq = dev->data->tx_queues[queue_id]; 2587 2588 qinfo->nb_desc = txq->nb_tx_desc; 2589 2590 qinfo->conf.tx_thresh.pthresh = txq->pthresh; 2591 qinfo->conf.tx_thresh.hthresh = txq->hthresh; 2592 qinfo->conf.tx_thresh.wthresh = txq->wthresh; 2593 2594 qinfo->conf.tx_free_thresh = txq->tx_free_thresh; 2595 qinfo->conf.tx_rs_thresh = 0; 2596 qinfo->conf.tx_deferred_start = txq->tx_deferred_start; 2597 } 2598 2599 int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) 2600 { 2601 struct bnxt *bp = eth_dev->data->dev_private; 2602 uint32_t new_pkt_size; 2603 uint32_t rc = 0; 2604 uint32_t i; 2605 2606 rc = is_bnxt_in_error(bp); 2607 if (rc) 2608 return rc; 2609 2610 /* Exit if receive queues are not configured yet */ 2611 if (!eth_dev->data->nb_rx_queues) 2612 return rc; 2613 2614 new_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + 2615 VLAN_TAG_SIZE * BNXT_NUM_VLANS; 2616 2617 #ifdef RTE_ARCH_X86 2618 /* 2619 * If vector-mode tx/rx is active, disallow any MTU change that would 2620 * require scattered receive support. 2621 */ 2622 if (eth_dev->data->dev_started && 2623 (eth_dev->rx_pkt_burst == bnxt_recv_pkts_vec || 2624 eth_dev->tx_pkt_burst == bnxt_xmit_pkts_vec) && 2625 (new_pkt_size > 2626 eth_dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)) { 2627 PMD_DRV_LOG(ERR, 2628 "MTU change would require scattered rx support. "); 2629 PMD_DRV_LOG(ERR, "Stop port before changing MTU.\n"); 2630 return -EINVAL; 2631 } 2632 #endif 2633 2634 if (new_mtu > RTE_ETHER_MTU) { 2635 bp->flags |= BNXT_FLAG_JUMBO; 2636 bp->eth_dev->data->dev_conf.rxmode.offloads |= 2637 DEV_RX_OFFLOAD_JUMBO_FRAME; 2638 } else { 2639 bp->eth_dev->data->dev_conf.rxmode.offloads &= 2640 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 2641 bp->flags &= ~BNXT_FLAG_JUMBO; 2642 } 2643 2644 /* Is there a change in mtu setting? */ 2645 if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len == new_pkt_size) 2646 return rc; 2647 2648 for (i = 0; i < bp->nr_vnics; i++) { 2649 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 2650 uint16_t size = 0; 2651 2652 vnic->mru = BNXT_VNIC_MRU(new_mtu); 2653 rc = bnxt_hwrm_vnic_cfg(bp, vnic); 2654 if (rc) 2655 break; 2656 2657 size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool); 2658 size -= RTE_PKTMBUF_HEADROOM; 2659 2660 if (size < new_mtu) { 2661 rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic); 2662 if (rc) 2663 return rc; 2664 } 2665 } 2666 2667 if (!rc) 2668 eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = new_pkt_size; 2669 2670 PMD_DRV_LOG(INFO, "New MTU is %d\n", new_mtu); 2671 2672 return rc; 2673 } 2674 2675 static int 2676 bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on) 2677 { 2678 struct bnxt *bp = dev->data->dev_private; 2679 uint16_t vlan = bp->vlan; 2680 int rc; 2681 2682 rc = is_bnxt_in_error(bp); 2683 if (rc) 2684 return rc; 2685 2686 if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { 2687 PMD_DRV_LOG(ERR, 2688 "PVID cannot be modified for this function\n"); 2689 return -ENOTSUP; 2690 } 2691 bp->vlan = on ? pvid : 0; 2692 2693 rc = bnxt_hwrm_set_default_vlan(bp, 0, 0); 2694 if (rc) 2695 bp->vlan = vlan; 2696 return rc; 2697 } 2698 2699 static int 2700 bnxt_dev_led_on_op(struct rte_eth_dev *dev) 2701 { 2702 struct bnxt *bp = dev->data->dev_private; 2703 int rc; 2704 2705 rc = is_bnxt_in_error(bp); 2706 if (rc) 2707 return rc; 2708 2709 return bnxt_hwrm_port_led_cfg(bp, true); 2710 } 2711 2712 static int 2713 bnxt_dev_led_off_op(struct rte_eth_dev *dev) 2714 { 2715 struct bnxt *bp = dev->data->dev_private; 2716 int rc; 2717 2718 rc = is_bnxt_in_error(bp); 2719 if (rc) 2720 return rc; 2721 2722 return bnxt_hwrm_port_led_cfg(bp, false); 2723 } 2724 2725 static uint32_t 2726 bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) 2727 { 2728 struct bnxt *bp = (struct bnxt *)dev->data->dev_private; 2729 uint32_t desc = 0, raw_cons = 0, cons; 2730 struct bnxt_cp_ring_info *cpr; 2731 struct bnxt_rx_queue *rxq; 2732 struct rx_pkt_cmpl *rxcmp; 2733 int rc; 2734 2735 rc = is_bnxt_in_error(bp); 2736 if (rc) 2737 return rc; 2738 2739 rxq = dev->data->rx_queues[rx_queue_id]; 2740 cpr = rxq->cp_ring; 2741 raw_cons = cpr->cp_raw_cons; 2742 2743 while (1) { 2744 cons = RING_CMP(cpr->cp_ring_struct, raw_cons); 2745 rte_prefetch0(&cpr->cp_desc_ring[cons]); 2746 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2747 2748 if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct)) { 2749 break; 2750 } else { 2751 raw_cons++; 2752 desc++; 2753 } 2754 } 2755 2756 return desc; 2757 } 2758 2759 static int 2760 bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset) 2761 { 2762 struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue; 2763 struct bnxt_rx_ring_info *rxr; 2764 struct bnxt_cp_ring_info *cpr; 2765 struct bnxt_sw_rx_bd *rx_buf; 2766 struct rx_pkt_cmpl *rxcmp; 2767 uint32_t cons, cp_cons; 2768 int rc; 2769 2770 if (!rxq) 2771 return -EINVAL; 2772 2773 rc = is_bnxt_in_error(rxq->bp); 2774 if (rc) 2775 return rc; 2776 2777 cpr = rxq->cp_ring; 2778 rxr = rxq->rx_ring; 2779 2780 if (offset >= rxq->nb_rx_desc) 2781 return -EINVAL; 2782 2783 cons = RING_CMP(cpr->cp_ring_struct, offset); 2784 cp_cons = cpr->cp_raw_cons; 2785 rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2786 2787 if (cons > cp_cons) { 2788 if (CMPL_VALID(rxcmp, cpr->valid)) 2789 return RTE_ETH_RX_DESC_DONE; 2790 } else { 2791 if (CMPL_VALID(rxcmp, !cpr->valid)) 2792 return RTE_ETH_RX_DESC_DONE; 2793 } 2794 rx_buf = &rxr->rx_buf_ring[cons]; 2795 if (rx_buf->mbuf == NULL) 2796 return RTE_ETH_RX_DESC_UNAVAIL; 2797 2798 2799 return RTE_ETH_RX_DESC_AVAIL; 2800 } 2801 2802 static int 2803 bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset) 2804 { 2805 struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; 2806 struct bnxt_tx_ring_info *txr; 2807 struct bnxt_cp_ring_info *cpr; 2808 struct bnxt_sw_tx_bd *tx_buf; 2809 struct tx_pkt_cmpl *txcmp; 2810 uint32_t cons, cp_cons; 2811 int rc; 2812 2813 if (!txq) 2814 return -EINVAL; 2815 2816 rc = is_bnxt_in_error(txq->bp); 2817 if (rc) 2818 return rc; 2819 2820 cpr = txq->cp_ring; 2821 txr = txq->tx_ring; 2822 2823 if (offset >= txq->nb_tx_desc) 2824 return -EINVAL; 2825 2826 cons = RING_CMP(cpr->cp_ring_struct, offset); 2827 txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons]; 2828 cp_cons = cpr->cp_raw_cons; 2829 2830 if (cons > cp_cons) { 2831 if (CMPL_VALID(txcmp, cpr->valid)) 2832 return RTE_ETH_TX_DESC_UNAVAIL; 2833 } else { 2834 if (CMPL_VALID(txcmp, !cpr->valid)) 2835 return RTE_ETH_TX_DESC_UNAVAIL; 2836 } 2837 tx_buf = &txr->tx_buf_ring[cons]; 2838 if (tx_buf->mbuf == NULL) 2839 return RTE_ETH_TX_DESC_DONE; 2840 2841 return RTE_ETH_TX_DESC_FULL; 2842 } 2843 2844 static struct bnxt_filter_info * 2845 bnxt_match_and_validate_ether_filter(struct bnxt *bp, 2846 struct rte_eth_ethertype_filter *efilter, 2847 struct bnxt_vnic_info *vnic0, 2848 struct bnxt_vnic_info *vnic, 2849 int *ret) 2850 { 2851 struct bnxt_filter_info *mfilter = NULL; 2852 int match = 0; 2853 *ret = 0; 2854 2855 if (efilter->ether_type == RTE_ETHER_TYPE_IPV4 || 2856 efilter->ether_type == RTE_ETHER_TYPE_IPV6) { 2857 PMD_DRV_LOG(ERR, "invalid ether_type(0x%04x) in" 2858 " ethertype filter.", efilter->ether_type); 2859 *ret = -EINVAL; 2860 goto exit; 2861 } 2862 if (efilter->queue >= bp->rx_nr_rings) { 2863 PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue); 2864 *ret = -EINVAL; 2865 goto exit; 2866 } 2867 2868 vnic0 = BNXT_GET_DEFAULT_VNIC(bp); 2869 vnic = &bp->vnic_info[efilter->queue]; 2870 if (vnic == NULL) { 2871 PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue); 2872 *ret = -EINVAL; 2873 goto exit; 2874 } 2875 2876 if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) { 2877 STAILQ_FOREACH(mfilter, &vnic0->filter, next) { 2878 if ((!memcmp(efilter->mac_addr.addr_bytes, 2879 mfilter->l2_addr, RTE_ETHER_ADDR_LEN) && 2880 mfilter->flags == 2881 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP && 2882 mfilter->ethertype == efilter->ether_type)) { 2883 match = 1; 2884 break; 2885 } 2886 } 2887 } else { 2888 STAILQ_FOREACH(mfilter, &vnic->filter, next) 2889 if ((!memcmp(efilter->mac_addr.addr_bytes, 2890 mfilter->l2_addr, RTE_ETHER_ADDR_LEN) && 2891 mfilter->ethertype == efilter->ether_type && 2892 mfilter->flags == 2893 HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX)) { 2894 match = 1; 2895 break; 2896 } 2897 } 2898 2899 if (match) 2900 *ret = -EEXIST; 2901 2902 exit: 2903 return mfilter; 2904 } 2905 2906 static int 2907 bnxt_ethertype_filter(struct rte_eth_dev *dev, 2908 enum rte_filter_op filter_op, 2909 void *arg) 2910 { 2911 struct bnxt *bp = dev->data->dev_private; 2912 struct rte_eth_ethertype_filter *efilter = 2913 (struct rte_eth_ethertype_filter *)arg; 2914 struct bnxt_filter_info *bfilter, *filter1; 2915 struct bnxt_vnic_info *vnic, *vnic0; 2916 int ret; 2917 2918 if (filter_op == RTE_ETH_FILTER_NOP) 2919 return 0; 2920 2921 if (arg == NULL) { 2922 PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.", 2923 filter_op); 2924 return -EINVAL; 2925 } 2926 2927 vnic0 = BNXT_GET_DEFAULT_VNIC(bp); 2928 vnic = &bp->vnic_info[efilter->queue]; 2929 2930 switch (filter_op) { 2931 case RTE_ETH_FILTER_ADD: 2932 bnxt_match_and_validate_ether_filter(bp, efilter, 2933 vnic0, vnic, &ret); 2934 if (ret < 0) 2935 return ret; 2936 2937 bfilter = bnxt_get_unused_filter(bp); 2938 if (bfilter == NULL) { 2939 PMD_DRV_LOG(ERR, 2940 "Not enough resources for a new filter.\n"); 2941 return -ENOMEM; 2942 } 2943 bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER; 2944 memcpy(bfilter->l2_addr, efilter->mac_addr.addr_bytes, 2945 RTE_ETHER_ADDR_LEN); 2946 memcpy(bfilter->dst_macaddr, efilter->mac_addr.addr_bytes, 2947 RTE_ETHER_ADDR_LEN); 2948 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR; 2949 bfilter->ethertype = efilter->ether_type; 2950 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 2951 2952 filter1 = bnxt_get_l2_filter(bp, bfilter, vnic0); 2953 if (filter1 == NULL) { 2954 ret = -EINVAL; 2955 goto cleanup; 2956 } 2957 bfilter->enables |= 2958 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 2959 bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id; 2960 2961 bfilter->dst_id = vnic->fw_vnic_id; 2962 2963 if (efilter->flags & RTE_ETHTYPE_FLAGS_DROP) { 2964 bfilter->flags = 2965 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP; 2966 } 2967 2968 ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter); 2969 if (ret) 2970 goto cleanup; 2971 STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next); 2972 break; 2973 case RTE_ETH_FILTER_DELETE: 2974 filter1 = bnxt_match_and_validate_ether_filter(bp, efilter, 2975 vnic0, vnic, &ret); 2976 if (ret == -EEXIST) { 2977 ret = bnxt_hwrm_clear_ntuple_filter(bp, filter1); 2978 2979 STAILQ_REMOVE(&vnic->filter, filter1, bnxt_filter_info, 2980 next); 2981 bnxt_free_filter(bp, filter1); 2982 } else if (ret == 0) { 2983 PMD_DRV_LOG(ERR, "No matching filter found\n"); 2984 } 2985 break; 2986 default: 2987 PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op); 2988 ret = -EINVAL; 2989 goto error; 2990 } 2991 return ret; 2992 cleanup: 2993 bnxt_free_filter(bp, bfilter); 2994 error: 2995 return ret; 2996 } 2997 2998 static inline int 2999 parse_ntuple_filter(struct bnxt *bp, 3000 struct rte_eth_ntuple_filter *nfilter, 3001 struct bnxt_filter_info *bfilter) 3002 { 3003 uint32_t en = 0; 3004 3005 if (nfilter->queue >= bp->rx_nr_rings) { 3006 PMD_DRV_LOG(ERR, "Invalid queue %d\n", nfilter->queue); 3007 return -EINVAL; 3008 } 3009 3010 switch (nfilter->dst_port_mask) { 3011 case UINT16_MAX: 3012 bfilter->dst_port_mask = -1; 3013 bfilter->dst_port = nfilter->dst_port; 3014 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT | 3015 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 3016 break; 3017 default: 3018 PMD_DRV_LOG(ERR, "invalid dst_port mask."); 3019 return -EINVAL; 3020 } 3021 3022 bfilter->ip_addr_type = NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 3023 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3024 3025 switch (nfilter->proto_mask) { 3026 case UINT8_MAX: 3027 if (nfilter->proto == 17) /* IPPROTO_UDP */ 3028 bfilter->ip_protocol = 17; 3029 else if (nfilter->proto == 6) /* IPPROTO_TCP */ 3030 bfilter->ip_protocol = 6; 3031 else 3032 return -EINVAL; 3033 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3034 break; 3035 default: 3036 PMD_DRV_LOG(ERR, "invalid protocol mask."); 3037 return -EINVAL; 3038 } 3039 3040 switch (nfilter->dst_ip_mask) { 3041 case UINT32_MAX: 3042 bfilter->dst_ipaddr_mask[0] = -1; 3043 bfilter->dst_ipaddr[0] = nfilter->dst_ip; 3044 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR | 3045 NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3046 break; 3047 default: 3048 PMD_DRV_LOG(ERR, "invalid dst_ip mask."); 3049 return -EINVAL; 3050 } 3051 3052 switch (nfilter->src_ip_mask) { 3053 case UINT32_MAX: 3054 bfilter->src_ipaddr_mask[0] = -1; 3055 bfilter->src_ipaddr[0] = nfilter->src_ip; 3056 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR | 3057 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3058 break; 3059 default: 3060 PMD_DRV_LOG(ERR, "invalid src_ip mask."); 3061 return -EINVAL; 3062 } 3063 3064 switch (nfilter->src_port_mask) { 3065 case UINT16_MAX: 3066 bfilter->src_port_mask = -1; 3067 bfilter->src_port = nfilter->src_port; 3068 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT | 3069 NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 3070 break; 3071 default: 3072 PMD_DRV_LOG(ERR, "invalid src_port mask."); 3073 return -EINVAL; 3074 } 3075 3076 bfilter->enables = en; 3077 return 0; 3078 } 3079 3080 static struct bnxt_filter_info* 3081 bnxt_match_ntuple_filter(struct bnxt *bp, 3082 struct bnxt_filter_info *bfilter, 3083 struct bnxt_vnic_info **mvnic) 3084 { 3085 struct bnxt_filter_info *mfilter = NULL; 3086 int i; 3087 3088 for (i = bp->nr_vnics - 1; i >= 0; i--) { 3089 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 3090 STAILQ_FOREACH(mfilter, &vnic->filter, next) { 3091 if (bfilter->src_ipaddr[0] == mfilter->src_ipaddr[0] && 3092 bfilter->src_ipaddr_mask[0] == 3093 mfilter->src_ipaddr_mask[0] && 3094 bfilter->src_port == mfilter->src_port && 3095 bfilter->src_port_mask == mfilter->src_port_mask && 3096 bfilter->dst_ipaddr[0] == mfilter->dst_ipaddr[0] && 3097 bfilter->dst_ipaddr_mask[0] == 3098 mfilter->dst_ipaddr_mask[0] && 3099 bfilter->dst_port == mfilter->dst_port && 3100 bfilter->dst_port_mask == mfilter->dst_port_mask && 3101 bfilter->flags == mfilter->flags && 3102 bfilter->enables == mfilter->enables) { 3103 if (mvnic) 3104 *mvnic = vnic; 3105 return mfilter; 3106 } 3107 } 3108 } 3109 return NULL; 3110 } 3111 3112 static int 3113 bnxt_cfg_ntuple_filter(struct bnxt *bp, 3114 struct rte_eth_ntuple_filter *nfilter, 3115 enum rte_filter_op filter_op) 3116 { 3117 struct bnxt_filter_info *bfilter, *mfilter, *filter1; 3118 struct bnxt_vnic_info *vnic, *vnic0, *mvnic; 3119 int ret; 3120 3121 if (nfilter->flags != RTE_5TUPLE_FLAGS) { 3122 PMD_DRV_LOG(ERR, "only 5tuple is supported."); 3123 return -EINVAL; 3124 } 3125 3126 if (nfilter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) { 3127 PMD_DRV_LOG(ERR, "Ntuple filter: TCP flags not supported\n"); 3128 return -EINVAL; 3129 } 3130 3131 bfilter = bnxt_get_unused_filter(bp); 3132 if (bfilter == NULL) { 3133 PMD_DRV_LOG(ERR, 3134 "Not enough resources for a new filter.\n"); 3135 return -ENOMEM; 3136 } 3137 ret = parse_ntuple_filter(bp, nfilter, bfilter); 3138 if (ret < 0) 3139 goto free_filter; 3140 3141 vnic = &bp->vnic_info[nfilter->queue]; 3142 vnic0 = BNXT_GET_DEFAULT_VNIC(bp); 3143 filter1 = STAILQ_FIRST(&vnic0->filter); 3144 if (filter1 == NULL) { 3145 ret = -EINVAL; 3146 goto free_filter; 3147 } 3148 3149 bfilter->dst_id = vnic->fw_vnic_id; 3150 bfilter->fw_l2_filter_id = filter1->fw_l2_filter_id; 3151 bfilter->enables |= 3152 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 3153 bfilter->ethertype = 0x800; 3154 bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3155 3156 mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic); 3157 3158 if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD && 3159 bfilter->dst_id == mfilter->dst_id) { 3160 PMD_DRV_LOG(ERR, "filter exists.\n"); 3161 ret = -EEXIST; 3162 goto free_filter; 3163 } else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD && 3164 bfilter->dst_id != mfilter->dst_id) { 3165 mfilter->dst_id = vnic->fw_vnic_id; 3166 ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter); 3167 STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next); 3168 STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next); 3169 PMD_DRV_LOG(ERR, "filter with matching pattern exists.\n"); 3170 PMD_DRV_LOG(ERR, " Updated it to the new destination queue\n"); 3171 goto free_filter; 3172 } 3173 if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) { 3174 PMD_DRV_LOG(ERR, "filter doesn't exist."); 3175 ret = -ENOENT; 3176 goto free_filter; 3177 } 3178 3179 if (filter_op == RTE_ETH_FILTER_ADD) { 3180 bfilter->filter_type = HWRM_CFA_NTUPLE_FILTER; 3181 ret = bnxt_hwrm_set_ntuple_filter(bp, bfilter->dst_id, bfilter); 3182 if (ret) 3183 goto free_filter; 3184 STAILQ_INSERT_TAIL(&vnic->filter, bfilter, next); 3185 } else { 3186 if (mfilter == NULL) { 3187 /* This should not happen. But for Coverity! */ 3188 ret = -ENOENT; 3189 goto free_filter; 3190 } 3191 ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter); 3192 3193 STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next); 3194 bnxt_free_filter(bp, mfilter); 3195 bnxt_free_filter(bp, bfilter); 3196 } 3197 3198 return 0; 3199 free_filter: 3200 bnxt_free_filter(bp, bfilter); 3201 return ret; 3202 } 3203 3204 static int 3205 bnxt_ntuple_filter(struct rte_eth_dev *dev, 3206 enum rte_filter_op filter_op, 3207 void *arg) 3208 { 3209 struct bnxt *bp = dev->data->dev_private; 3210 int ret; 3211 3212 if (filter_op == RTE_ETH_FILTER_NOP) 3213 return 0; 3214 3215 if (arg == NULL) { 3216 PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.", 3217 filter_op); 3218 return -EINVAL; 3219 } 3220 3221 switch (filter_op) { 3222 case RTE_ETH_FILTER_ADD: 3223 ret = bnxt_cfg_ntuple_filter(bp, 3224 (struct rte_eth_ntuple_filter *)arg, 3225 filter_op); 3226 break; 3227 case RTE_ETH_FILTER_DELETE: 3228 ret = bnxt_cfg_ntuple_filter(bp, 3229 (struct rte_eth_ntuple_filter *)arg, 3230 filter_op); 3231 break; 3232 default: 3233 PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op); 3234 ret = -EINVAL; 3235 break; 3236 } 3237 return ret; 3238 } 3239 3240 static int 3241 bnxt_parse_fdir_filter(struct bnxt *bp, 3242 struct rte_eth_fdir_filter *fdir, 3243 struct bnxt_filter_info *filter) 3244 { 3245 enum rte_fdir_mode fdir_mode = 3246 bp->eth_dev->data->dev_conf.fdir_conf.mode; 3247 struct bnxt_vnic_info *vnic0, *vnic; 3248 struct bnxt_filter_info *filter1; 3249 uint32_t en = 0; 3250 int i; 3251 3252 if (fdir_mode == RTE_FDIR_MODE_PERFECT_TUNNEL) 3253 return -EINVAL; 3254 3255 filter->l2_ovlan = fdir->input.flow_ext.vlan_tci; 3256 en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID; 3257 3258 switch (fdir->input.flow_type) { 3259 case RTE_ETH_FLOW_IPV4: 3260 case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: 3261 /* FALLTHROUGH */ 3262 filter->src_ipaddr[0] = fdir->input.flow.ip4_flow.src_ip; 3263 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3264 filter->dst_ipaddr[0] = fdir->input.flow.ip4_flow.dst_ip; 3265 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3266 filter->ip_protocol = fdir->input.flow.ip4_flow.proto; 3267 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3268 filter->ip_addr_type = 3269 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 3270 filter->src_ipaddr_mask[0] = 0xffffffff; 3271 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3272 filter->dst_ipaddr_mask[0] = 0xffffffff; 3273 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3274 filter->ethertype = 0x800; 3275 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3276 break; 3277 case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: 3278 filter->src_port = fdir->input.flow.tcp4_flow.src_port; 3279 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 3280 filter->dst_port = fdir->input.flow.tcp4_flow.dst_port; 3281 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 3282 filter->dst_port_mask = 0xffff; 3283 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 3284 filter->src_port_mask = 0xffff; 3285 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 3286 filter->src_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.src_ip; 3287 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3288 filter->dst_ipaddr[0] = fdir->input.flow.tcp4_flow.ip.dst_ip; 3289 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3290 filter->ip_protocol = 6; 3291 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3292 filter->ip_addr_type = 3293 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 3294 filter->src_ipaddr_mask[0] = 0xffffffff; 3295 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3296 filter->dst_ipaddr_mask[0] = 0xffffffff; 3297 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3298 filter->ethertype = 0x800; 3299 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3300 break; 3301 case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: 3302 filter->src_port = fdir->input.flow.udp4_flow.src_port; 3303 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 3304 filter->dst_port = fdir->input.flow.udp4_flow.dst_port; 3305 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 3306 filter->dst_port_mask = 0xffff; 3307 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 3308 filter->src_port_mask = 0xffff; 3309 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 3310 filter->src_ipaddr[0] = fdir->input.flow.udp4_flow.ip.src_ip; 3311 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3312 filter->dst_ipaddr[0] = fdir->input.flow.udp4_flow.ip.dst_ip; 3313 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3314 filter->ip_protocol = 17; 3315 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3316 filter->ip_addr_type = 3317 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV4; 3318 filter->src_ipaddr_mask[0] = 0xffffffff; 3319 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3320 filter->dst_ipaddr_mask[0] = 0xffffffff; 3321 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3322 filter->ethertype = 0x800; 3323 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3324 break; 3325 case RTE_ETH_FLOW_IPV6: 3326 case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: 3327 /* FALLTHROUGH */ 3328 filter->ip_addr_type = 3329 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 3330 filter->ip_protocol = fdir->input.flow.ipv6_flow.proto; 3331 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3332 rte_memcpy(filter->src_ipaddr, 3333 fdir->input.flow.ipv6_flow.src_ip, 16); 3334 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3335 rte_memcpy(filter->dst_ipaddr, 3336 fdir->input.flow.ipv6_flow.dst_ip, 16); 3337 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3338 memset(filter->dst_ipaddr_mask, 0xff, 16); 3339 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3340 memset(filter->src_ipaddr_mask, 0xff, 16); 3341 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3342 filter->ethertype = 0x86dd; 3343 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3344 break; 3345 case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: 3346 filter->src_port = fdir->input.flow.tcp6_flow.src_port; 3347 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 3348 filter->dst_port = fdir->input.flow.tcp6_flow.dst_port; 3349 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 3350 filter->dst_port_mask = 0xffff; 3351 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 3352 filter->src_port_mask = 0xffff; 3353 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 3354 filter->ip_addr_type = 3355 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 3356 filter->ip_protocol = fdir->input.flow.tcp6_flow.ip.proto; 3357 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3358 rte_memcpy(filter->src_ipaddr, 3359 fdir->input.flow.tcp6_flow.ip.src_ip, 16); 3360 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3361 rte_memcpy(filter->dst_ipaddr, 3362 fdir->input.flow.tcp6_flow.ip.dst_ip, 16); 3363 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3364 memset(filter->dst_ipaddr_mask, 0xff, 16); 3365 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3366 memset(filter->src_ipaddr_mask, 0xff, 16); 3367 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3368 filter->ethertype = 0x86dd; 3369 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3370 break; 3371 case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: 3372 filter->src_port = fdir->input.flow.udp6_flow.src_port; 3373 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT; 3374 filter->dst_port = fdir->input.flow.udp6_flow.dst_port; 3375 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT; 3376 filter->dst_port_mask = 0xffff; 3377 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK; 3378 filter->src_port_mask = 0xffff; 3379 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK; 3380 filter->ip_addr_type = 3381 NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6; 3382 filter->ip_protocol = fdir->input.flow.udp6_flow.ip.proto; 3383 en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO; 3384 rte_memcpy(filter->src_ipaddr, 3385 fdir->input.flow.udp6_flow.ip.src_ip, 16); 3386 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR; 3387 rte_memcpy(filter->dst_ipaddr, 3388 fdir->input.flow.udp6_flow.ip.dst_ip, 16); 3389 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR; 3390 memset(filter->dst_ipaddr_mask, 0xff, 16); 3391 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK; 3392 memset(filter->src_ipaddr_mask, 0xff, 16); 3393 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK; 3394 filter->ethertype = 0x86dd; 3395 filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3396 break; 3397 case RTE_ETH_FLOW_L2_PAYLOAD: 3398 filter->ethertype = fdir->input.flow.l2_flow.ether_type; 3399 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE; 3400 break; 3401 case RTE_ETH_FLOW_VXLAN: 3402 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 3403 return -EINVAL; 3404 filter->vni = fdir->input.flow.tunnel_flow.tunnel_id; 3405 filter->tunnel_type = 3406 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN; 3407 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE; 3408 break; 3409 case RTE_ETH_FLOW_NVGRE: 3410 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 3411 return -EINVAL; 3412 filter->vni = fdir->input.flow.tunnel_flow.tunnel_id; 3413 filter->tunnel_type = 3414 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE; 3415 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE; 3416 break; 3417 case RTE_ETH_FLOW_UNKNOWN: 3418 case RTE_ETH_FLOW_RAW: 3419 case RTE_ETH_FLOW_FRAG_IPV4: 3420 case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: 3421 case RTE_ETH_FLOW_FRAG_IPV6: 3422 case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: 3423 case RTE_ETH_FLOW_IPV6_EX: 3424 case RTE_ETH_FLOW_IPV6_TCP_EX: 3425 case RTE_ETH_FLOW_IPV6_UDP_EX: 3426 case RTE_ETH_FLOW_GENEVE: 3427 /* FALLTHROUGH */ 3428 default: 3429 return -EINVAL; 3430 } 3431 3432 vnic0 = BNXT_GET_DEFAULT_VNIC(bp); 3433 vnic = &bp->vnic_info[fdir->action.rx_queue]; 3434 if (vnic == NULL) { 3435 PMD_DRV_LOG(ERR, "Invalid queue %d\n", fdir->action.rx_queue); 3436 return -EINVAL; 3437 } 3438 3439 if (fdir_mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN) { 3440 rte_memcpy(filter->dst_macaddr, 3441 fdir->input.flow.mac_vlan_flow.mac_addr.addr_bytes, 6); 3442 en |= NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR; 3443 } 3444 3445 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) { 3446 filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP; 3447 filter1 = STAILQ_FIRST(&vnic0->filter); 3448 //filter1 = bnxt_get_l2_filter(bp, filter, vnic0); 3449 } else { 3450 filter->dst_id = vnic->fw_vnic_id; 3451 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) 3452 if (filter->dst_macaddr[i] == 0x00) 3453 filter1 = STAILQ_FIRST(&vnic0->filter); 3454 else 3455 filter1 = bnxt_get_l2_filter(bp, filter, vnic); 3456 } 3457 3458 if (filter1 == NULL) 3459 return -EINVAL; 3460 3461 en |= HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID; 3462 filter->fw_l2_filter_id = filter1->fw_l2_filter_id; 3463 3464 filter->enables = en; 3465 3466 return 0; 3467 } 3468 3469 static struct bnxt_filter_info * 3470 bnxt_match_fdir(struct bnxt *bp, struct bnxt_filter_info *nf, 3471 struct bnxt_vnic_info **mvnic) 3472 { 3473 struct bnxt_filter_info *mf = NULL; 3474 int i; 3475 3476 for (i = bp->nr_vnics - 1; i >= 0; i--) { 3477 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 3478 3479 STAILQ_FOREACH(mf, &vnic->filter, next) { 3480 if (mf->filter_type == nf->filter_type && 3481 mf->flags == nf->flags && 3482 mf->src_port == nf->src_port && 3483 mf->src_port_mask == nf->src_port_mask && 3484 mf->dst_port == nf->dst_port && 3485 mf->dst_port_mask == nf->dst_port_mask && 3486 mf->ip_protocol == nf->ip_protocol && 3487 mf->ip_addr_type == nf->ip_addr_type && 3488 mf->ethertype == nf->ethertype && 3489 mf->vni == nf->vni && 3490 mf->tunnel_type == nf->tunnel_type && 3491 mf->l2_ovlan == nf->l2_ovlan && 3492 mf->l2_ovlan_mask == nf->l2_ovlan_mask && 3493 mf->l2_ivlan == nf->l2_ivlan && 3494 mf->l2_ivlan_mask == nf->l2_ivlan_mask && 3495 !memcmp(mf->l2_addr, nf->l2_addr, 3496 RTE_ETHER_ADDR_LEN) && 3497 !memcmp(mf->l2_addr_mask, nf->l2_addr_mask, 3498 RTE_ETHER_ADDR_LEN) && 3499 !memcmp(mf->src_macaddr, nf->src_macaddr, 3500 RTE_ETHER_ADDR_LEN) && 3501 !memcmp(mf->dst_macaddr, nf->dst_macaddr, 3502 RTE_ETHER_ADDR_LEN) && 3503 !memcmp(mf->src_ipaddr, nf->src_ipaddr, 3504 sizeof(nf->src_ipaddr)) && 3505 !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask, 3506 sizeof(nf->src_ipaddr_mask)) && 3507 !memcmp(mf->dst_ipaddr, nf->dst_ipaddr, 3508 sizeof(nf->dst_ipaddr)) && 3509 !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask, 3510 sizeof(nf->dst_ipaddr_mask))) { 3511 if (mvnic) 3512 *mvnic = vnic; 3513 return mf; 3514 } 3515 } 3516 } 3517 return NULL; 3518 } 3519 3520 static int 3521 bnxt_fdir_filter(struct rte_eth_dev *dev, 3522 enum rte_filter_op filter_op, 3523 void *arg) 3524 { 3525 struct bnxt *bp = dev->data->dev_private; 3526 struct rte_eth_fdir_filter *fdir = (struct rte_eth_fdir_filter *)arg; 3527 struct bnxt_filter_info *filter, *match; 3528 struct bnxt_vnic_info *vnic, *mvnic; 3529 int ret = 0, i; 3530 3531 if (filter_op == RTE_ETH_FILTER_NOP) 3532 return 0; 3533 3534 if (arg == NULL && filter_op != RTE_ETH_FILTER_FLUSH) 3535 return -EINVAL; 3536 3537 switch (filter_op) { 3538 case RTE_ETH_FILTER_ADD: 3539 case RTE_ETH_FILTER_DELETE: 3540 /* FALLTHROUGH */ 3541 filter = bnxt_get_unused_filter(bp); 3542 if (filter == NULL) { 3543 PMD_DRV_LOG(ERR, 3544 "Not enough resources for a new flow.\n"); 3545 return -ENOMEM; 3546 } 3547 3548 ret = bnxt_parse_fdir_filter(bp, fdir, filter); 3549 if (ret != 0) 3550 goto free_filter; 3551 filter->filter_type = HWRM_CFA_NTUPLE_FILTER; 3552 3553 if (fdir->action.behavior == RTE_ETH_FDIR_REJECT) 3554 vnic = &bp->vnic_info[0]; 3555 else 3556 vnic = &bp->vnic_info[fdir->action.rx_queue]; 3557 3558 match = bnxt_match_fdir(bp, filter, &mvnic); 3559 if (match != NULL && filter_op == RTE_ETH_FILTER_ADD) { 3560 if (match->dst_id == vnic->fw_vnic_id) { 3561 PMD_DRV_LOG(ERR, "Flow already exists.\n"); 3562 ret = -EEXIST; 3563 goto free_filter; 3564 } else { 3565 match->dst_id = vnic->fw_vnic_id; 3566 ret = bnxt_hwrm_set_ntuple_filter(bp, 3567 match->dst_id, 3568 match); 3569 STAILQ_REMOVE(&mvnic->filter, match, 3570 bnxt_filter_info, next); 3571 STAILQ_INSERT_TAIL(&vnic->filter, match, next); 3572 PMD_DRV_LOG(ERR, 3573 "Filter with matching pattern exist\n"); 3574 PMD_DRV_LOG(ERR, 3575 "Updated it to new destination q\n"); 3576 goto free_filter; 3577 } 3578 } 3579 if (match == NULL && filter_op == RTE_ETH_FILTER_DELETE) { 3580 PMD_DRV_LOG(ERR, "Flow does not exist.\n"); 3581 ret = -ENOENT; 3582 goto free_filter; 3583 } 3584 3585 if (filter_op == RTE_ETH_FILTER_ADD) { 3586 ret = bnxt_hwrm_set_ntuple_filter(bp, 3587 filter->dst_id, 3588 filter); 3589 if (ret) 3590 goto free_filter; 3591 STAILQ_INSERT_TAIL(&vnic->filter, filter, next); 3592 } else { 3593 ret = bnxt_hwrm_clear_ntuple_filter(bp, match); 3594 STAILQ_REMOVE(&vnic->filter, match, 3595 bnxt_filter_info, next); 3596 bnxt_free_filter(bp, match); 3597 bnxt_free_filter(bp, filter); 3598 } 3599 break; 3600 case RTE_ETH_FILTER_FLUSH: 3601 for (i = bp->nr_vnics - 1; i >= 0; i--) { 3602 struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; 3603 3604 STAILQ_FOREACH(filter, &vnic->filter, next) { 3605 if (filter->filter_type == 3606 HWRM_CFA_NTUPLE_FILTER) { 3607 ret = 3608 bnxt_hwrm_clear_ntuple_filter(bp, 3609 filter); 3610 STAILQ_REMOVE(&vnic->filter, filter, 3611 bnxt_filter_info, next); 3612 } 3613 } 3614 } 3615 return ret; 3616 case RTE_ETH_FILTER_UPDATE: 3617 case RTE_ETH_FILTER_STATS: 3618 case RTE_ETH_FILTER_INFO: 3619 PMD_DRV_LOG(ERR, "operation %u not implemented", filter_op); 3620 break; 3621 default: 3622 PMD_DRV_LOG(ERR, "unknown operation %u", filter_op); 3623 ret = -EINVAL; 3624 break; 3625 } 3626 return ret; 3627 3628 free_filter: 3629 bnxt_free_filter(bp, filter); 3630 return ret; 3631 } 3632 3633 static int 3634 bnxt_filter_ctrl_op(struct rte_eth_dev *dev, 3635 enum rte_filter_type filter_type, 3636 enum rte_filter_op filter_op, void *arg) 3637 { 3638 struct bnxt *bp = dev->data->dev_private; 3639 int ret = 0; 3640 3641 ret = is_bnxt_in_error(dev->data->dev_private); 3642 if (ret) 3643 return ret; 3644 3645 switch (filter_type) { 3646 case RTE_ETH_FILTER_TUNNEL: 3647 PMD_DRV_LOG(ERR, 3648 "filter type: %d: To be implemented\n", filter_type); 3649 break; 3650 case RTE_ETH_FILTER_FDIR: 3651 ret = bnxt_fdir_filter(dev, filter_op, arg); 3652 break; 3653 case RTE_ETH_FILTER_NTUPLE: 3654 ret = bnxt_ntuple_filter(dev, filter_op, arg); 3655 break; 3656 case RTE_ETH_FILTER_ETHERTYPE: 3657 ret = bnxt_ethertype_filter(dev, filter_op, arg); 3658 break; 3659 case RTE_ETH_FILTER_GENERIC: 3660 if (filter_op != RTE_ETH_FILTER_GET) 3661 return -EINVAL; 3662 if (BNXT_TRUFLOW_EN(bp)) 3663 *(const void **)arg = &bnxt_ulp_rte_flow_ops; 3664 else 3665 *(const void **)arg = &bnxt_flow_ops; 3666 break; 3667 default: 3668 PMD_DRV_LOG(ERR, 3669 "Filter type (%d) not supported", filter_type); 3670 ret = -EINVAL; 3671 break; 3672 } 3673 return ret; 3674 } 3675 3676 static const uint32_t * 3677 bnxt_dev_supported_ptypes_get_op(struct rte_eth_dev *dev) 3678 { 3679 static const uint32_t ptypes[] = { 3680 RTE_PTYPE_L2_ETHER_VLAN, 3681 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 3682 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 3683 RTE_PTYPE_L4_ICMP, 3684 RTE_PTYPE_L4_TCP, 3685 RTE_PTYPE_L4_UDP, 3686 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 3687 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 3688 RTE_PTYPE_INNER_L4_ICMP, 3689 RTE_PTYPE_INNER_L4_TCP, 3690 RTE_PTYPE_INNER_L4_UDP, 3691 RTE_PTYPE_UNKNOWN 3692 }; 3693 3694 if (!dev->rx_pkt_burst) 3695 return NULL; 3696 3697 return ptypes; 3698 } 3699 3700 static int bnxt_map_regs(struct bnxt *bp, uint32_t *reg_arr, int count, 3701 int reg_win) 3702 { 3703 uint32_t reg_base = *reg_arr & 0xfffff000; 3704 uint32_t win_off; 3705 int i; 3706 3707 for (i = 0; i < count; i++) { 3708 if ((reg_arr[i] & 0xfffff000) != reg_base) 3709 return -ERANGE; 3710 } 3711 win_off = BNXT_GRCPF_REG_WINDOW_BASE_OUT + (reg_win - 1) * 4; 3712 rte_write32(reg_base, (uint8_t *)bp->bar0 + win_off); 3713 return 0; 3714 } 3715 3716 static int bnxt_map_ptp_regs(struct bnxt *bp) 3717 { 3718 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3719 uint32_t *reg_arr; 3720 int rc, i; 3721 3722 reg_arr = ptp->rx_regs; 3723 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_RX_REGS, 5); 3724 if (rc) 3725 return rc; 3726 3727 reg_arr = ptp->tx_regs; 3728 rc = bnxt_map_regs(bp, reg_arr, BNXT_PTP_TX_REGS, 6); 3729 if (rc) 3730 return rc; 3731 3732 for (i = 0; i < BNXT_PTP_RX_REGS; i++) 3733 ptp->rx_mapped_regs[i] = 0x5000 + (ptp->rx_regs[i] & 0xfff); 3734 3735 for (i = 0; i < BNXT_PTP_TX_REGS; i++) 3736 ptp->tx_mapped_regs[i] = 0x6000 + (ptp->tx_regs[i] & 0xfff); 3737 3738 return 0; 3739 } 3740 3741 static void bnxt_unmap_ptp_regs(struct bnxt *bp) 3742 { 3743 rte_write32(0, (uint8_t *)bp->bar0 + 3744 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 16); 3745 rte_write32(0, (uint8_t *)bp->bar0 + 3746 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 20); 3747 } 3748 3749 static uint64_t bnxt_cc_read(struct bnxt *bp) 3750 { 3751 uint64_t ns; 3752 3753 ns = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3754 BNXT_GRCPF_REG_SYNC_TIME)); 3755 ns |= (uint64_t)(rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3756 BNXT_GRCPF_REG_SYNC_TIME + 4))) << 32; 3757 return ns; 3758 } 3759 3760 static int bnxt_get_tx_ts(struct bnxt *bp, uint64_t *ts) 3761 { 3762 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3763 uint32_t fifo; 3764 3765 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3766 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 3767 if (fifo & BNXT_PTP_TX_FIFO_EMPTY) 3768 return -EAGAIN; 3769 3770 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3771 ptp->tx_mapped_regs[BNXT_PTP_TX_FIFO])); 3772 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3773 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_L])); 3774 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3775 ptp->tx_mapped_regs[BNXT_PTP_TX_TS_H])) << 32; 3776 3777 return 0; 3778 } 3779 3780 static int bnxt_get_rx_ts(struct bnxt *bp, uint64_t *ts) 3781 { 3782 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3783 struct bnxt_pf_info *pf = bp->pf; 3784 uint16_t port_id; 3785 uint32_t fifo; 3786 3787 if (!ptp) 3788 return -ENODEV; 3789 3790 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3791 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 3792 if (!(fifo & BNXT_PTP_RX_FIFO_PENDING)) 3793 return -EAGAIN; 3794 3795 port_id = pf->port_id; 3796 rte_write32(1 << port_id, (uint8_t *)bp->bar0 + 3797 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO_ADV]); 3798 3799 fifo = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3800 ptp->rx_mapped_regs[BNXT_PTP_RX_FIFO])); 3801 if (fifo & BNXT_PTP_RX_FIFO_PENDING) { 3802 /* bnxt_clr_rx_ts(bp); TBD */ 3803 return -EBUSY; 3804 } 3805 3806 *ts = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3807 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_L])); 3808 *ts |= (uint64_t)rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 3809 ptp->rx_mapped_regs[BNXT_PTP_RX_TS_H])) << 32; 3810 3811 return 0; 3812 } 3813 3814 static int 3815 bnxt_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) 3816 { 3817 uint64_t ns; 3818 struct bnxt *bp = dev->data->dev_private; 3819 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3820 3821 if (!ptp) 3822 return 0; 3823 3824 ns = rte_timespec_to_ns(ts); 3825 /* Set the timecounters to a new value. */ 3826 ptp->tc.nsec = ns; 3827 3828 return 0; 3829 } 3830 3831 static int 3832 bnxt_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) 3833 { 3834 struct bnxt *bp = dev->data->dev_private; 3835 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3836 uint64_t ns, systime_cycles = 0; 3837 int rc = 0; 3838 3839 if (!ptp) 3840 return 0; 3841 3842 if (BNXT_CHIP_THOR(bp)) 3843 rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME, 3844 &systime_cycles); 3845 else 3846 systime_cycles = bnxt_cc_read(bp); 3847 3848 ns = rte_timecounter_update(&ptp->tc, systime_cycles); 3849 *ts = rte_ns_to_timespec(ns); 3850 3851 return rc; 3852 } 3853 static int 3854 bnxt_timesync_enable(struct rte_eth_dev *dev) 3855 { 3856 struct bnxt *bp = dev->data->dev_private; 3857 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3858 uint32_t shift = 0; 3859 int rc; 3860 3861 if (!ptp) 3862 return 0; 3863 3864 ptp->rx_filter = 1; 3865 ptp->tx_tstamp_en = 1; 3866 ptp->rxctl = BNXT_PTP_MSG_EVENTS; 3867 3868 rc = bnxt_hwrm_ptp_cfg(bp); 3869 if (rc) 3870 return rc; 3871 3872 memset(&ptp->tc, 0, sizeof(struct rte_timecounter)); 3873 memset(&ptp->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 3874 memset(&ptp->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 3875 3876 ptp->tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3877 ptp->tc.cc_shift = shift; 3878 ptp->tc.nsec_mask = (1ULL << shift) - 1; 3879 3880 ptp->rx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3881 ptp->rx_tstamp_tc.cc_shift = shift; 3882 ptp->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 3883 3884 ptp->tx_tstamp_tc.cc_mask = BNXT_CYCLECOUNTER_MASK; 3885 ptp->tx_tstamp_tc.cc_shift = shift; 3886 ptp->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1; 3887 3888 if (!BNXT_CHIP_THOR(bp)) 3889 bnxt_map_ptp_regs(bp); 3890 3891 return 0; 3892 } 3893 3894 static int 3895 bnxt_timesync_disable(struct rte_eth_dev *dev) 3896 { 3897 struct bnxt *bp = dev->data->dev_private; 3898 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3899 3900 if (!ptp) 3901 return 0; 3902 3903 ptp->rx_filter = 0; 3904 ptp->tx_tstamp_en = 0; 3905 ptp->rxctl = 0; 3906 3907 bnxt_hwrm_ptp_cfg(bp); 3908 3909 if (!BNXT_CHIP_THOR(bp)) 3910 bnxt_unmap_ptp_regs(bp); 3911 3912 return 0; 3913 } 3914 3915 static int 3916 bnxt_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 3917 struct timespec *timestamp, 3918 uint32_t flags __rte_unused) 3919 { 3920 struct bnxt *bp = dev->data->dev_private; 3921 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3922 uint64_t rx_tstamp_cycles = 0; 3923 uint64_t ns; 3924 3925 if (!ptp) 3926 return 0; 3927 3928 if (BNXT_CHIP_THOR(bp)) 3929 rx_tstamp_cycles = ptp->rx_timestamp; 3930 else 3931 bnxt_get_rx_ts(bp, &rx_tstamp_cycles); 3932 3933 ns = rte_timecounter_update(&ptp->rx_tstamp_tc, rx_tstamp_cycles); 3934 *timestamp = rte_ns_to_timespec(ns); 3935 return 0; 3936 } 3937 3938 static int 3939 bnxt_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 3940 struct timespec *timestamp) 3941 { 3942 struct bnxt *bp = dev->data->dev_private; 3943 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3944 uint64_t tx_tstamp_cycles = 0; 3945 uint64_t ns; 3946 int rc = 0; 3947 3948 if (!ptp) 3949 return 0; 3950 3951 if (BNXT_CHIP_THOR(bp)) 3952 rc = bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_PATH_TX, 3953 &tx_tstamp_cycles); 3954 else 3955 rc = bnxt_get_tx_ts(bp, &tx_tstamp_cycles); 3956 3957 ns = rte_timecounter_update(&ptp->tx_tstamp_tc, tx_tstamp_cycles); 3958 *timestamp = rte_ns_to_timespec(ns); 3959 3960 return rc; 3961 } 3962 3963 static int 3964 bnxt_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 3965 { 3966 struct bnxt *bp = dev->data->dev_private; 3967 struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; 3968 3969 if (!ptp) 3970 return 0; 3971 3972 ptp->tc.nsec += delta; 3973 3974 return 0; 3975 } 3976 3977 static int 3978 bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) 3979 { 3980 struct bnxt *bp = dev->data->dev_private; 3981 int rc; 3982 uint32_t dir_entries; 3983 uint32_t entry_length; 3984 3985 rc = is_bnxt_in_error(bp); 3986 if (rc) 3987 return rc; 3988 3989 PMD_DRV_LOG(INFO, PCI_PRI_FMT "\n", 3990 bp->pdev->addr.domain, bp->pdev->addr.bus, 3991 bp->pdev->addr.devid, bp->pdev->addr.function); 3992 3993 rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length); 3994 if (rc != 0) 3995 return rc; 3996 3997 return dir_entries * entry_length; 3998 } 3999 4000 static int 4001 bnxt_get_eeprom_op(struct rte_eth_dev *dev, 4002 struct rte_dev_eeprom_info *in_eeprom) 4003 { 4004 struct bnxt *bp = dev->data->dev_private; 4005 uint32_t index; 4006 uint32_t offset; 4007 int rc; 4008 4009 rc = is_bnxt_in_error(bp); 4010 if (rc) 4011 return rc; 4012 4013 PMD_DRV_LOG(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d\n", 4014 bp->pdev->addr.domain, bp->pdev->addr.bus, 4015 bp->pdev->addr.devid, bp->pdev->addr.function, 4016 in_eeprom->offset, in_eeprom->length); 4017 4018 if (in_eeprom->offset == 0) /* special offset value to get directory */ 4019 return bnxt_get_nvram_directory(bp, in_eeprom->length, 4020 in_eeprom->data); 4021 4022 index = in_eeprom->offset >> 24; 4023 offset = in_eeprom->offset & 0xffffff; 4024 4025 if (index != 0) 4026 return bnxt_hwrm_get_nvram_item(bp, index - 1, offset, 4027 in_eeprom->length, in_eeprom->data); 4028 4029 return 0; 4030 } 4031 4032 static bool bnxt_dir_type_is_ape_bin_format(uint16_t dir_type) 4033 { 4034 switch (dir_type) { 4035 case BNX_DIR_TYPE_CHIMP_PATCH: 4036 case BNX_DIR_TYPE_BOOTCODE: 4037 case BNX_DIR_TYPE_BOOTCODE_2: 4038 case BNX_DIR_TYPE_APE_FW: 4039 case BNX_DIR_TYPE_APE_PATCH: 4040 case BNX_DIR_TYPE_KONG_FW: 4041 case BNX_DIR_TYPE_KONG_PATCH: 4042 case BNX_DIR_TYPE_BONO_FW: 4043 case BNX_DIR_TYPE_BONO_PATCH: 4044 /* FALLTHROUGH */ 4045 return true; 4046 } 4047 4048 return false; 4049 } 4050 4051 static bool bnxt_dir_type_is_other_exec_format(uint16_t dir_type) 4052 { 4053 switch (dir_type) { 4054 case BNX_DIR_TYPE_AVS: 4055 case BNX_DIR_TYPE_EXP_ROM_MBA: 4056 case BNX_DIR_TYPE_PCIE: 4057 case BNX_DIR_TYPE_TSCF_UCODE: 4058 case BNX_DIR_TYPE_EXT_PHY: 4059 case BNX_DIR_TYPE_CCM: 4060 case BNX_DIR_TYPE_ISCSI_BOOT: 4061 case BNX_DIR_TYPE_ISCSI_BOOT_IPV6: 4062 case BNX_DIR_TYPE_ISCSI_BOOT_IPV4N6: 4063 /* FALLTHROUGH */ 4064 return true; 4065 } 4066 4067 return false; 4068 } 4069 4070 static bool bnxt_dir_type_is_executable(uint16_t dir_type) 4071 { 4072 return bnxt_dir_type_is_ape_bin_format(dir_type) || 4073 bnxt_dir_type_is_other_exec_format(dir_type); 4074 } 4075 4076 static int 4077 bnxt_set_eeprom_op(struct rte_eth_dev *dev, 4078 struct rte_dev_eeprom_info *in_eeprom) 4079 { 4080 struct bnxt *bp = dev->data->dev_private; 4081 uint8_t index, dir_op; 4082 uint16_t type, ext, ordinal, attr; 4083 int rc; 4084 4085 rc = is_bnxt_in_error(bp); 4086 if (rc) 4087 return rc; 4088 4089 PMD_DRV_LOG(INFO, PCI_PRI_FMT " in_eeprom->offset = %d len = %d\n", 4090 bp->pdev->addr.domain, bp->pdev->addr.bus, 4091 bp->pdev->addr.devid, bp->pdev->addr.function, 4092 in_eeprom->offset, in_eeprom->length); 4093 4094 if (!BNXT_PF(bp)) { 4095 PMD_DRV_LOG(ERR, "NVM write not supported from a VF\n"); 4096 return -EINVAL; 4097 } 4098 4099 type = in_eeprom->magic >> 16; 4100 4101 if (type == 0xffff) { /* special value for directory operations */ 4102 index = in_eeprom->magic & 0xff; 4103 dir_op = in_eeprom->magic >> 8; 4104 if (index == 0) 4105 return -EINVAL; 4106 switch (dir_op) { 4107 case 0x0e: /* erase */ 4108 if (in_eeprom->offset != ~in_eeprom->magic) 4109 return -EINVAL; 4110 return bnxt_hwrm_erase_nvram_directory(bp, index - 1); 4111 default: 4112 return -EINVAL; 4113 } 4114 } 4115 4116 /* Create or re-write an NVM item: */ 4117 if (bnxt_dir_type_is_executable(type) == true) 4118 return -EOPNOTSUPP; 4119 ext = in_eeprom->magic & 0xffff; 4120 ordinal = in_eeprom->offset >> 16; 4121 attr = in_eeprom->offset & 0xffff; 4122 4123 return bnxt_hwrm_flash_nvram(bp, type, ordinal, ext, attr, 4124 in_eeprom->data, in_eeprom->length); 4125 } 4126 4127 /* 4128 * Initialization 4129 */ 4130 4131 static const struct eth_dev_ops bnxt_dev_ops = { 4132 .dev_infos_get = bnxt_dev_info_get_op, 4133 .dev_close = bnxt_dev_close_op, 4134 .dev_configure = bnxt_dev_configure_op, 4135 .dev_start = bnxt_dev_start_op, 4136 .dev_stop = bnxt_dev_stop_op, 4137 .dev_set_link_up = bnxt_dev_set_link_up_op, 4138 .dev_set_link_down = bnxt_dev_set_link_down_op, 4139 .stats_get = bnxt_stats_get_op, 4140 .stats_reset = bnxt_stats_reset_op, 4141 .rx_queue_setup = bnxt_rx_queue_setup_op, 4142 .rx_queue_release = bnxt_rx_queue_release_op, 4143 .tx_queue_setup = bnxt_tx_queue_setup_op, 4144 .tx_queue_release = bnxt_tx_queue_release_op, 4145 .rx_queue_intr_enable = bnxt_rx_queue_intr_enable_op, 4146 .rx_queue_intr_disable = bnxt_rx_queue_intr_disable_op, 4147 .reta_update = bnxt_reta_update_op, 4148 .reta_query = bnxt_reta_query_op, 4149 .rss_hash_update = bnxt_rss_hash_update_op, 4150 .rss_hash_conf_get = bnxt_rss_hash_conf_get_op, 4151 .link_update = bnxt_link_update_op, 4152 .promiscuous_enable = bnxt_promiscuous_enable_op, 4153 .promiscuous_disable = bnxt_promiscuous_disable_op, 4154 .allmulticast_enable = bnxt_allmulticast_enable_op, 4155 .allmulticast_disable = bnxt_allmulticast_disable_op, 4156 .mac_addr_add = bnxt_mac_addr_add_op, 4157 .mac_addr_remove = bnxt_mac_addr_remove_op, 4158 .flow_ctrl_get = bnxt_flow_ctrl_get_op, 4159 .flow_ctrl_set = bnxt_flow_ctrl_set_op, 4160 .udp_tunnel_port_add = bnxt_udp_tunnel_port_add_op, 4161 .udp_tunnel_port_del = bnxt_udp_tunnel_port_del_op, 4162 .vlan_filter_set = bnxt_vlan_filter_set_op, 4163 .vlan_offload_set = bnxt_vlan_offload_set_op, 4164 .vlan_tpid_set = bnxt_vlan_tpid_set_op, 4165 .vlan_pvid_set = bnxt_vlan_pvid_set_op, 4166 .mtu_set = bnxt_mtu_set_op, 4167 .mac_addr_set = bnxt_set_default_mac_addr_op, 4168 .xstats_get = bnxt_dev_xstats_get_op, 4169 .xstats_get_names = bnxt_dev_xstats_get_names_op, 4170 .xstats_reset = bnxt_dev_xstats_reset_op, 4171 .fw_version_get = bnxt_fw_version_get, 4172 .set_mc_addr_list = bnxt_dev_set_mc_addr_list_op, 4173 .rxq_info_get = bnxt_rxq_info_get_op, 4174 .txq_info_get = bnxt_txq_info_get_op, 4175 .dev_led_on = bnxt_dev_led_on_op, 4176 .dev_led_off = bnxt_dev_led_off_op, 4177 .xstats_get_by_id = bnxt_dev_xstats_get_by_id_op, 4178 .xstats_get_names_by_id = bnxt_dev_xstats_get_names_by_id_op, 4179 .rx_queue_count = bnxt_rx_queue_count_op, 4180 .rx_descriptor_status = bnxt_rx_descriptor_status_op, 4181 .tx_descriptor_status = bnxt_tx_descriptor_status_op, 4182 .rx_queue_start = bnxt_rx_queue_start, 4183 .rx_queue_stop = bnxt_rx_queue_stop, 4184 .tx_queue_start = bnxt_tx_queue_start, 4185 .tx_queue_stop = bnxt_tx_queue_stop, 4186 .filter_ctrl = bnxt_filter_ctrl_op, 4187 .dev_supported_ptypes_get = bnxt_dev_supported_ptypes_get_op, 4188 .get_eeprom_length = bnxt_get_eeprom_length_op, 4189 .get_eeprom = bnxt_get_eeprom_op, 4190 .set_eeprom = bnxt_set_eeprom_op, 4191 .timesync_enable = bnxt_timesync_enable, 4192 .timesync_disable = bnxt_timesync_disable, 4193 .timesync_read_time = bnxt_timesync_read_time, 4194 .timesync_write_time = bnxt_timesync_write_time, 4195 .timesync_adjust_time = bnxt_timesync_adjust_time, 4196 .timesync_read_rx_timestamp = bnxt_timesync_read_rx_timestamp, 4197 .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, 4198 }; 4199 4200 static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg) 4201 { 4202 uint32_t offset; 4203 4204 /* Only pre-map the reset GRC registers using window 3 */ 4205 rte_write32(reg & 0xfffff000, (uint8_t *)bp->bar0 + 4206 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 8); 4207 4208 offset = BNXT_GRCP_WINDOW_3_BASE + (reg & 0xffc); 4209 4210 return offset; 4211 } 4212 4213 int bnxt_map_fw_health_status_regs(struct bnxt *bp) 4214 { 4215 struct bnxt_error_recovery_info *info = bp->recovery_info; 4216 uint32_t reg_base = 0xffffffff; 4217 int i; 4218 4219 /* Only pre-map the monitoring GRC registers using window 2 */ 4220 for (i = 0; i < BNXT_FW_STATUS_REG_CNT; i++) { 4221 uint32_t reg = info->status_regs[i]; 4222 4223 if (BNXT_FW_STATUS_REG_TYPE(reg) != BNXT_FW_STATUS_REG_TYPE_GRC) 4224 continue; 4225 4226 if (reg_base == 0xffffffff) 4227 reg_base = reg & 0xfffff000; 4228 if ((reg & 0xfffff000) != reg_base) 4229 return -ERANGE; 4230 4231 /* Use mask 0xffc as the Lower 2 bits indicates 4232 * address space location 4233 */ 4234 info->mapped_status_regs[i] = BNXT_GRCP_WINDOW_2_BASE + 4235 (reg & 0xffc); 4236 } 4237 4238 if (reg_base == 0xffffffff) 4239 return 0; 4240 4241 rte_write32(reg_base, (uint8_t *)bp->bar0 + 4242 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 4243 4244 return 0; 4245 } 4246 4247 static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) 4248 { 4249 struct bnxt_error_recovery_info *info = bp->recovery_info; 4250 uint32_t delay = info->delay_after_reset[index]; 4251 uint32_t val = info->reset_reg_val[index]; 4252 uint32_t reg = info->reset_reg[index]; 4253 uint32_t type, offset; 4254 4255 type = BNXT_FW_STATUS_REG_TYPE(reg); 4256 offset = BNXT_FW_STATUS_REG_OFF(reg); 4257 4258 switch (type) { 4259 case BNXT_FW_STATUS_REG_TYPE_CFG: 4260 rte_pci_write_config(bp->pdev, &val, sizeof(val), offset); 4261 break; 4262 case BNXT_FW_STATUS_REG_TYPE_GRC: 4263 offset = bnxt_map_reset_regs(bp, offset); 4264 rte_write32(val, (uint8_t *)bp->bar0 + offset); 4265 break; 4266 case BNXT_FW_STATUS_REG_TYPE_BAR0: 4267 rte_write32(val, (uint8_t *)bp->bar0 + offset); 4268 break; 4269 } 4270 /* wait on a specific interval of time until core reset is complete */ 4271 if (delay) 4272 rte_delay_ms(delay); 4273 } 4274 4275 static void bnxt_dev_cleanup(struct bnxt *bp) 4276 { 4277 bnxt_set_hwrm_link_config(bp, false); 4278 bp->link_info->link_up = 0; 4279 if (bp->eth_dev->data->dev_started) 4280 bnxt_dev_stop_op(bp->eth_dev); 4281 4282 bnxt_uninit_resources(bp, true); 4283 } 4284 4285 static int bnxt_restore_vlan_filters(struct bnxt *bp) 4286 { 4287 struct rte_eth_dev *dev = bp->eth_dev; 4288 struct rte_vlan_filter_conf *vfc; 4289 int vidx, vbit, rc; 4290 uint16_t vlan_id; 4291 4292 for (vlan_id = 1; vlan_id <= RTE_ETHER_MAX_VLAN_ID; vlan_id++) { 4293 vfc = &dev->data->vlan_filter_conf; 4294 vidx = vlan_id / 64; 4295 vbit = vlan_id % 64; 4296 4297 /* Each bit corresponds to a VLAN id */ 4298 if (vfc->ids[vidx] & (UINT64_C(1) << vbit)) { 4299 rc = bnxt_add_vlan_filter(bp, vlan_id); 4300 if (rc) 4301 return rc; 4302 } 4303 } 4304 4305 return 0; 4306 } 4307 4308 static int bnxt_restore_mac_filters(struct bnxt *bp) 4309 { 4310 struct rte_eth_dev *dev = bp->eth_dev; 4311 struct rte_eth_dev_info dev_info; 4312 struct rte_ether_addr *addr; 4313 uint64_t pool_mask; 4314 uint32_t pool = 0; 4315 uint16_t i; 4316 int rc; 4317 4318 if (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp)) 4319 return 0; 4320 4321 rc = bnxt_dev_info_get_op(dev, &dev_info); 4322 if (rc) 4323 return rc; 4324 4325 /* replay MAC address configuration */ 4326 for (i = 1; i < dev_info.max_mac_addrs; i++) { 4327 addr = &dev->data->mac_addrs[i]; 4328 4329 /* skip zero address */ 4330 if (rte_is_zero_ether_addr(addr)) 4331 continue; 4332 4333 pool = 0; 4334 pool_mask = dev->data->mac_pool_sel[i]; 4335 4336 do { 4337 if (pool_mask & 1ULL) { 4338 rc = bnxt_mac_addr_add_op(dev, addr, i, pool); 4339 if (rc) 4340 return rc; 4341 } 4342 pool_mask >>= 1; 4343 pool++; 4344 } while (pool_mask); 4345 } 4346 4347 return 0; 4348 } 4349 4350 static int bnxt_restore_filters(struct bnxt *bp) 4351 { 4352 struct rte_eth_dev *dev = bp->eth_dev; 4353 int ret = 0; 4354 4355 if (dev->data->all_multicast) { 4356 ret = bnxt_allmulticast_enable_op(dev); 4357 if (ret) 4358 return ret; 4359 } 4360 if (dev->data->promiscuous) { 4361 ret = bnxt_promiscuous_enable_op(dev); 4362 if (ret) 4363 return ret; 4364 } 4365 4366 ret = bnxt_restore_mac_filters(bp); 4367 if (ret) 4368 return ret; 4369 4370 ret = bnxt_restore_vlan_filters(bp); 4371 /* TODO restore other filters as well */ 4372 return ret; 4373 } 4374 4375 static void bnxt_dev_recover(void *arg) 4376 { 4377 struct bnxt *bp = arg; 4378 int timeout = bp->fw_reset_max_msecs; 4379 int rc = 0; 4380 4381 /* Clear Error flag so that device re-init should happen */ 4382 bp->flags &= ~BNXT_FLAG_FATAL_ERROR; 4383 4384 do { 4385 rc = bnxt_hwrm_ver_get(bp, SHORT_HWRM_CMD_TIMEOUT); 4386 if (rc == 0) 4387 break; 4388 rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL); 4389 timeout -= BNXT_FW_READY_WAIT_INTERVAL; 4390 } while (rc && timeout); 4391 4392 if (rc) { 4393 PMD_DRV_LOG(ERR, "FW is not Ready after reset\n"); 4394 goto err; 4395 } 4396 4397 rc = bnxt_init_resources(bp, true); 4398 if (rc) { 4399 PMD_DRV_LOG(ERR, 4400 "Failed to initialize resources after reset\n"); 4401 goto err; 4402 } 4403 /* clear reset flag as the device is initialized now */ 4404 bp->flags &= ~BNXT_FLAG_FW_RESET; 4405 4406 rc = bnxt_dev_start_op(bp->eth_dev); 4407 if (rc) { 4408 PMD_DRV_LOG(ERR, "Failed to start port after reset\n"); 4409 goto err_start; 4410 } 4411 4412 rc = bnxt_restore_filters(bp); 4413 if (rc) 4414 goto err_start; 4415 4416 PMD_DRV_LOG(INFO, "Recovered from FW reset\n"); 4417 return; 4418 err_start: 4419 bnxt_dev_stop_op(bp->eth_dev); 4420 err: 4421 bp->flags |= BNXT_FLAG_FATAL_ERROR; 4422 bnxt_uninit_resources(bp, false); 4423 PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n"); 4424 } 4425 4426 void bnxt_dev_reset_and_resume(void *arg) 4427 { 4428 struct bnxt *bp = arg; 4429 int rc; 4430 4431 bnxt_dev_cleanup(bp); 4432 4433 bnxt_wait_for_device_shutdown(bp); 4434 4435 rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs, 4436 bnxt_dev_recover, (void *)bp); 4437 if (rc) 4438 PMD_DRV_LOG(ERR, "Error setting recovery alarm"); 4439 } 4440 4441 uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) 4442 { 4443 struct bnxt_error_recovery_info *info = bp->recovery_info; 4444 uint32_t reg = info->status_regs[index]; 4445 uint32_t type, offset, val = 0; 4446 4447 type = BNXT_FW_STATUS_REG_TYPE(reg); 4448 offset = BNXT_FW_STATUS_REG_OFF(reg); 4449 4450 switch (type) { 4451 case BNXT_FW_STATUS_REG_TYPE_CFG: 4452 rte_pci_read_config(bp->pdev, &val, sizeof(val), offset); 4453 break; 4454 case BNXT_FW_STATUS_REG_TYPE_GRC: 4455 offset = info->mapped_status_regs[index]; 4456 /* FALLTHROUGH */ 4457 case BNXT_FW_STATUS_REG_TYPE_BAR0: 4458 val = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 4459 offset)); 4460 break; 4461 } 4462 4463 return val; 4464 } 4465 4466 static int bnxt_fw_reset_all(struct bnxt *bp) 4467 { 4468 struct bnxt_error_recovery_info *info = bp->recovery_info; 4469 uint32_t i; 4470 int rc = 0; 4471 4472 if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { 4473 /* Reset through master function driver */ 4474 for (i = 0; i < info->reg_array_cnt; i++) 4475 bnxt_write_fw_reset_reg(bp, i); 4476 /* Wait for time specified by FW after triggering reset */ 4477 rte_delay_ms(info->master_func_wait_period_after_reset); 4478 } else if (info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) { 4479 /* Reset with the help of Kong processor */ 4480 rc = bnxt_hwrm_fw_reset(bp); 4481 if (rc) 4482 PMD_DRV_LOG(ERR, "Failed to reset FW\n"); 4483 } 4484 4485 return rc; 4486 } 4487 4488 static void bnxt_fw_reset_cb(void *arg) 4489 { 4490 struct bnxt *bp = arg; 4491 struct bnxt_error_recovery_info *info = bp->recovery_info; 4492 int rc = 0; 4493 4494 /* Only Master function can do FW reset */ 4495 if (bnxt_is_master_func(bp) && 4496 bnxt_is_recovery_enabled(bp)) { 4497 rc = bnxt_fw_reset_all(bp); 4498 if (rc) { 4499 PMD_DRV_LOG(ERR, "Adapter recovery failed\n"); 4500 return; 4501 } 4502 } 4503 4504 /* if recovery method is ERROR_RECOVERY_CO_CPU, KONG will send 4505 * EXCEPTION_FATAL_ASYNC event to all the functions 4506 * (including MASTER FUNC). After receiving this Async, all the active 4507 * drivers should treat this case as FW initiated recovery 4508 */ 4509 if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { 4510 bp->fw_reset_min_msecs = BNXT_MIN_FW_READY_TIMEOUT; 4511 bp->fw_reset_max_msecs = BNXT_MAX_FW_RESET_TIMEOUT; 4512 4513 /* To recover from error */ 4514 rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, 4515 (void *)bp); 4516 } 4517 } 4518 4519 /* Driver should poll FW heartbeat, reset_counter with the frequency 4520 * advertised by FW in HWRM_ERROR_RECOVERY_QCFG. 4521 * When the driver detects heartbeat stop or change in reset_counter, 4522 * it has to trigger a reset to recover from the error condition. 4523 * A “master PF” is the function who will have the privilege to 4524 * initiate the chimp reset. The master PF will be elected by the 4525 * firmware and will be notified through async message. 4526 */ 4527 static void bnxt_check_fw_health(void *arg) 4528 { 4529 struct bnxt *bp = arg; 4530 struct bnxt_error_recovery_info *info = bp->recovery_info; 4531 uint32_t val = 0, wait_msec; 4532 4533 if (!info || !bnxt_is_recovery_enabled(bp) || 4534 is_bnxt_in_error(bp)) 4535 return; 4536 4537 val = bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG); 4538 if (val == info->last_heart_beat) 4539 goto reset; 4540 4541 info->last_heart_beat = val; 4542 4543 val = bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG); 4544 if (val != info->last_reset_counter) 4545 goto reset; 4546 4547 info->last_reset_counter = val; 4548 4549 rte_eal_alarm_set(US_PER_MS * info->driver_polling_freq, 4550 bnxt_check_fw_health, (void *)bp); 4551 4552 return; 4553 reset: 4554 /* Stop DMA to/from device */ 4555 bp->flags |= BNXT_FLAG_FATAL_ERROR; 4556 bp->flags |= BNXT_FLAG_FW_RESET; 4557 4558 PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); 4559 4560 if (bnxt_is_master_func(bp)) 4561 wait_msec = info->master_func_wait_period; 4562 else 4563 wait_msec = info->normal_func_wait_period; 4564 4565 rte_eal_alarm_set(US_PER_MS * wait_msec, 4566 bnxt_fw_reset_cb, (void *)bp); 4567 } 4568 4569 void bnxt_schedule_fw_health_check(struct bnxt *bp) 4570 { 4571 uint32_t polling_freq; 4572 4573 if (!bnxt_is_recovery_enabled(bp)) 4574 return; 4575 4576 if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED) 4577 return; 4578 4579 polling_freq = bp->recovery_info->driver_polling_freq; 4580 4581 rte_eal_alarm_set(US_PER_MS * polling_freq, 4582 bnxt_check_fw_health, (void *)bp); 4583 bp->flags |= BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; 4584 } 4585 4586 static void bnxt_cancel_fw_health_check(struct bnxt *bp) 4587 { 4588 if (!bnxt_is_recovery_enabled(bp)) 4589 return; 4590 4591 rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp); 4592 bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; 4593 } 4594 4595 static bool bnxt_vf_pciid(uint16_t device_id) 4596 { 4597 switch (device_id) { 4598 case BROADCOM_DEV_ID_57304_VF: 4599 case BROADCOM_DEV_ID_57406_VF: 4600 case BROADCOM_DEV_ID_5731X_VF: 4601 case BROADCOM_DEV_ID_5741X_VF: 4602 case BROADCOM_DEV_ID_57414_VF: 4603 case BROADCOM_DEV_ID_STRATUS_NIC_VF1: 4604 case BROADCOM_DEV_ID_STRATUS_NIC_VF2: 4605 case BROADCOM_DEV_ID_58802_VF: 4606 case BROADCOM_DEV_ID_57500_VF1: 4607 case BROADCOM_DEV_ID_57500_VF2: 4608 /* FALLTHROUGH */ 4609 return true; 4610 default: 4611 return false; 4612 } 4613 } 4614 4615 static bool bnxt_thor_device(uint16_t device_id) 4616 { 4617 switch (device_id) { 4618 case BROADCOM_DEV_ID_57508: 4619 case BROADCOM_DEV_ID_57504: 4620 case BROADCOM_DEV_ID_57502: 4621 case BROADCOM_DEV_ID_57508_MF1: 4622 case BROADCOM_DEV_ID_57504_MF1: 4623 case BROADCOM_DEV_ID_57502_MF1: 4624 case BROADCOM_DEV_ID_57508_MF2: 4625 case BROADCOM_DEV_ID_57504_MF2: 4626 case BROADCOM_DEV_ID_57502_MF2: 4627 case BROADCOM_DEV_ID_57500_VF1: 4628 case BROADCOM_DEV_ID_57500_VF2: 4629 /* FALLTHROUGH */ 4630 return true; 4631 default: 4632 return false; 4633 } 4634 } 4635 4636 bool bnxt_stratus_device(struct bnxt *bp) 4637 { 4638 uint16_t device_id = bp->pdev->id.device_id; 4639 4640 switch (device_id) { 4641 case BROADCOM_DEV_ID_STRATUS_NIC: 4642 case BROADCOM_DEV_ID_STRATUS_NIC_VF1: 4643 case BROADCOM_DEV_ID_STRATUS_NIC_VF2: 4644 /* FALLTHROUGH */ 4645 return true; 4646 default: 4647 return false; 4648 } 4649 } 4650 4651 static int bnxt_init_board(struct rte_eth_dev *eth_dev) 4652 { 4653 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 4654 struct bnxt *bp = eth_dev->data->dev_private; 4655 4656 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 4657 bp->bar0 = (void *)pci_dev->mem_resource[0].addr; 4658 bp->doorbell_base = (void *)pci_dev->mem_resource[2].addr; 4659 if (!bp->bar0 || !bp->doorbell_base) { 4660 PMD_DRV_LOG(ERR, "Unable to access Hardware\n"); 4661 return -ENODEV; 4662 } 4663 4664 bp->eth_dev = eth_dev; 4665 bp->pdev = pci_dev; 4666 4667 return 0; 4668 } 4669 4670 static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp, 4671 struct bnxt_ctx_pg_info *ctx_pg, 4672 uint32_t mem_size, 4673 const char *suffix, 4674 uint16_t idx) 4675 { 4676 struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem; 4677 const struct rte_memzone *mz = NULL; 4678 char mz_name[RTE_MEMZONE_NAMESIZE]; 4679 rte_iova_t mz_phys_addr; 4680 uint64_t valid_bits = 0; 4681 uint32_t sz; 4682 int i; 4683 4684 if (!mem_size) 4685 return 0; 4686 4687 rmem->nr_pages = RTE_ALIGN_MUL_CEIL(mem_size, BNXT_PAGE_SIZE) / 4688 BNXT_PAGE_SIZE; 4689 rmem->page_size = BNXT_PAGE_SIZE; 4690 rmem->pg_arr = ctx_pg->ctx_pg_arr; 4691 rmem->dma_arr = ctx_pg->ctx_dma_arr; 4692 rmem->flags = BNXT_RMEM_VALID_PTE_FLAG; 4693 4694 valid_bits = PTU_PTE_VALID; 4695 4696 if (rmem->nr_pages > 1) { 4697 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4698 "bnxt_ctx_pg_tbl%s_%x_%d", 4699 suffix, idx, bp->eth_dev->data->port_id); 4700 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4701 mz = rte_memzone_lookup(mz_name); 4702 if (!mz) { 4703 mz = rte_memzone_reserve_aligned(mz_name, 4704 rmem->nr_pages * 8, 4705 SOCKET_ID_ANY, 4706 RTE_MEMZONE_2MB | 4707 RTE_MEMZONE_SIZE_HINT_ONLY | 4708 RTE_MEMZONE_IOVA_CONTIG, 4709 BNXT_PAGE_SIZE); 4710 if (mz == NULL) 4711 return -ENOMEM; 4712 } 4713 4714 memset(mz->addr, 0, mz->len); 4715 mz_phys_addr = mz->iova; 4716 4717 rmem->pg_tbl = mz->addr; 4718 rmem->pg_tbl_map = mz_phys_addr; 4719 rmem->pg_tbl_mz = mz; 4720 } 4721 4722 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, "bnxt_ctx_%s_%x_%d", 4723 suffix, idx, bp->eth_dev->data->port_id); 4724 mz = rte_memzone_lookup(mz_name); 4725 if (!mz) { 4726 mz = rte_memzone_reserve_aligned(mz_name, 4727 mem_size, 4728 SOCKET_ID_ANY, 4729 RTE_MEMZONE_1GB | 4730 RTE_MEMZONE_SIZE_HINT_ONLY | 4731 RTE_MEMZONE_IOVA_CONTIG, 4732 BNXT_PAGE_SIZE); 4733 if (mz == NULL) 4734 return -ENOMEM; 4735 } 4736 4737 memset(mz->addr, 0, mz->len); 4738 mz_phys_addr = mz->iova; 4739 4740 for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) { 4741 rmem->pg_arr[i] = ((char *)mz->addr) + sz; 4742 rmem->dma_arr[i] = mz_phys_addr + sz; 4743 4744 if (rmem->nr_pages > 1) { 4745 if (i == rmem->nr_pages - 2 && 4746 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG)) 4747 valid_bits |= PTU_PTE_NEXT_TO_LAST; 4748 else if (i == rmem->nr_pages - 1 && 4749 (rmem->flags & BNXT_RMEM_RING_PTE_FLAG)) 4750 valid_bits |= PTU_PTE_LAST; 4751 4752 rmem->pg_tbl[i] = rte_cpu_to_le_64(rmem->dma_arr[i] | 4753 valid_bits); 4754 } 4755 } 4756 4757 rmem->mz = mz; 4758 if (rmem->vmem_size) 4759 rmem->vmem = (void **)mz->addr; 4760 rmem->dma_arr[0] = mz_phys_addr; 4761 return 0; 4762 } 4763 4764 static void bnxt_free_ctx_mem(struct bnxt *bp) 4765 { 4766 int i; 4767 4768 if (!bp->ctx || !(bp->ctx->flags & BNXT_CTX_FLAG_INITED)) 4769 return; 4770 4771 bp->ctx->flags &= ~BNXT_CTX_FLAG_INITED; 4772 rte_memzone_free(bp->ctx->qp_mem.ring_mem.mz); 4773 rte_memzone_free(bp->ctx->srq_mem.ring_mem.mz); 4774 rte_memzone_free(bp->ctx->cq_mem.ring_mem.mz); 4775 rte_memzone_free(bp->ctx->vnic_mem.ring_mem.mz); 4776 rte_memzone_free(bp->ctx->stat_mem.ring_mem.mz); 4777 rte_memzone_free(bp->ctx->qp_mem.ring_mem.pg_tbl_mz); 4778 rte_memzone_free(bp->ctx->srq_mem.ring_mem.pg_tbl_mz); 4779 rte_memzone_free(bp->ctx->cq_mem.ring_mem.pg_tbl_mz); 4780 rte_memzone_free(bp->ctx->vnic_mem.ring_mem.pg_tbl_mz); 4781 rte_memzone_free(bp->ctx->stat_mem.ring_mem.pg_tbl_mz); 4782 4783 for (i = 0; i < bp->ctx->tqm_fp_rings_count + 1; i++) { 4784 if (bp->ctx->tqm_mem[i]) 4785 rte_memzone_free(bp->ctx->tqm_mem[i]->ring_mem.mz); 4786 } 4787 4788 rte_free(bp->ctx); 4789 bp->ctx = NULL; 4790 } 4791 4792 #define bnxt_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 4793 4794 #define min_t(type, x, y) ({ \ 4795 type __min1 = (x); \ 4796 type __min2 = (y); \ 4797 __min1 < __min2 ? __min1 : __min2; }) 4798 4799 #define max_t(type, x, y) ({ \ 4800 type __max1 = (x); \ 4801 type __max2 = (y); \ 4802 __max1 > __max2 ? __max1 : __max2; }) 4803 4804 #define clamp_t(type, _x, min, max) min_t(type, max_t(type, _x, min), max) 4805 4806 int bnxt_alloc_ctx_mem(struct bnxt *bp) 4807 { 4808 struct bnxt_ctx_pg_info *ctx_pg; 4809 struct bnxt_ctx_mem_info *ctx; 4810 uint32_t mem_size, ena, entries; 4811 uint32_t entries_sp, min; 4812 int i, rc; 4813 4814 rc = bnxt_hwrm_func_backing_store_qcaps(bp); 4815 if (rc) { 4816 PMD_DRV_LOG(ERR, "Query context mem capability failed\n"); 4817 return rc; 4818 } 4819 ctx = bp->ctx; 4820 if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED)) 4821 return 0; 4822 4823 ctx_pg = &ctx->qp_mem; 4824 ctx_pg->entries = ctx->qp_min_qp1_entries + ctx->qp_max_l2_entries; 4825 mem_size = ctx->qp_entry_size * ctx_pg->entries; 4826 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "qp_mem", 0); 4827 if (rc) 4828 return rc; 4829 4830 ctx_pg = &ctx->srq_mem; 4831 ctx_pg->entries = ctx->srq_max_l2_entries; 4832 mem_size = ctx->srq_entry_size * ctx_pg->entries; 4833 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "srq_mem", 0); 4834 if (rc) 4835 return rc; 4836 4837 ctx_pg = &ctx->cq_mem; 4838 ctx_pg->entries = ctx->cq_max_l2_entries; 4839 mem_size = ctx->cq_entry_size * ctx_pg->entries; 4840 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "cq_mem", 0); 4841 if (rc) 4842 return rc; 4843 4844 ctx_pg = &ctx->vnic_mem; 4845 ctx_pg->entries = ctx->vnic_max_vnic_entries + 4846 ctx->vnic_max_ring_table_entries; 4847 mem_size = ctx->vnic_entry_size * ctx_pg->entries; 4848 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "vnic_mem", 0); 4849 if (rc) 4850 return rc; 4851 4852 ctx_pg = &ctx->stat_mem; 4853 ctx_pg->entries = ctx->stat_max_entries; 4854 mem_size = ctx->stat_entry_size * ctx_pg->entries; 4855 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "stat_mem", 0); 4856 if (rc) 4857 return rc; 4858 4859 min = ctx->tqm_min_entries_per_ring; 4860 4861 entries_sp = ctx->qp_max_l2_entries + 4862 ctx->vnic_max_vnic_entries + 4863 2 * ctx->qp_min_qp1_entries + min; 4864 entries_sp = bnxt_roundup(entries_sp, ctx->tqm_entries_multiple); 4865 4866 entries = ctx->qp_max_l2_entries + ctx->qp_min_qp1_entries; 4867 entries = bnxt_roundup(entries, ctx->tqm_entries_multiple); 4868 entries = clamp_t(uint32_t, entries, min, 4869 ctx->tqm_max_entries_per_ring); 4870 for (i = 0, ena = 0; i < ctx->tqm_fp_rings_count + 1; i++) { 4871 ctx_pg = ctx->tqm_mem[i]; 4872 ctx_pg->entries = i ? entries : entries_sp; 4873 mem_size = ctx->tqm_entry_size * ctx_pg->entries; 4874 rc = bnxt_alloc_ctx_mem_blk(bp, ctx_pg, mem_size, "tqm_mem", i); 4875 if (rc) 4876 return rc; 4877 ena |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP << i; 4878 } 4879 4880 ena |= FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES; 4881 rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); 4882 if (rc) 4883 PMD_DRV_LOG(ERR, 4884 "Failed to configure context mem: rc = %d\n", rc); 4885 else 4886 ctx->flags |= BNXT_CTX_FLAG_INITED; 4887 4888 return rc; 4889 } 4890 4891 static int bnxt_alloc_stats_mem(struct bnxt *bp) 4892 { 4893 struct rte_pci_device *pci_dev = bp->pdev; 4894 char mz_name[RTE_MEMZONE_NAMESIZE]; 4895 const struct rte_memzone *mz = NULL; 4896 uint32_t total_alloc_len; 4897 rte_iova_t mz_phys_addr; 4898 4899 if (pci_dev->id.device_id == BROADCOM_DEV_ID_NS2) 4900 return 0; 4901 4902 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4903 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain, 4904 pci_dev->addr.bus, pci_dev->addr.devid, 4905 pci_dev->addr.function, "rx_port_stats"); 4906 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4907 mz = rte_memzone_lookup(mz_name); 4908 total_alloc_len = 4909 RTE_CACHE_LINE_ROUNDUP(sizeof(struct rx_port_stats) + 4910 sizeof(struct rx_port_stats_ext) + 512); 4911 if (!mz) { 4912 mz = rte_memzone_reserve(mz_name, total_alloc_len, 4913 SOCKET_ID_ANY, 4914 RTE_MEMZONE_2MB | 4915 RTE_MEMZONE_SIZE_HINT_ONLY | 4916 RTE_MEMZONE_IOVA_CONTIG); 4917 if (mz == NULL) 4918 return -ENOMEM; 4919 } 4920 memset(mz->addr, 0, mz->len); 4921 mz_phys_addr = mz->iova; 4922 4923 bp->rx_mem_zone = (const void *)mz; 4924 bp->hw_rx_port_stats = mz->addr; 4925 bp->hw_rx_port_stats_map = mz_phys_addr; 4926 4927 snprintf(mz_name, RTE_MEMZONE_NAMESIZE, 4928 "bnxt_" PCI_PRI_FMT "-%s", pci_dev->addr.domain, 4929 pci_dev->addr.bus, pci_dev->addr.devid, 4930 pci_dev->addr.function, "tx_port_stats"); 4931 mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0; 4932 mz = rte_memzone_lookup(mz_name); 4933 total_alloc_len = 4934 RTE_CACHE_LINE_ROUNDUP(sizeof(struct tx_port_stats) + 4935 sizeof(struct tx_port_stats_ext) + 512); 4936 if (!mz) { 4937 mz = rte_memzone_reserve(mz_name, 4938 total_alloc_len, 4939 SOCKET_ID_ANY, 4940 RTE_MEMZONE_2MB | 4941 RTE_MEMZONE_SIZE_HINT_ONLY | 4942 RTE_MEMZONE_IOVA_CONTIG); 4943 if (mz == NULL) 4944 return -ENOMEM; 4945 } 4946 memset(mz->addr, 0, mz->len); 4947 mz_phys_addr = mz->iova; 4948 4949 bp->tx_mem_zone = (const void *)mz; 4950 bp->hw_tx_port_stats = mz->addr; 4951 bp->hw_tx_port_stats_map = mz_phys_addr; 4952 bp->flags |= BNXT_FLAG_PORT_STATS; 4953 4954 /* Display extended statistics if FW supports it */ 4955 if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_8_4 || 4956 bp->hwrm_spec_code == HWRM_SPEC_CODE_1_9_0 || 4957 !(bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED)) 4958 return 0; 4959 4960 bp->hw_rx_port_stats_ext = (void *) 4961 ((uint8_t *)bp->hw_rx_port_stats + 4962 sizeof(struct rx_port_stats)); 4963 bp->hw_rx_port_stats_ext_map = bp->hw_rx_port_stats_map + 4964 sizeof(struct rx_port_stats); 4965 bp->flags |= BNXT_FLAG_EXT_RX_PORT_STATS; 4966 4967 if (bp->hwrm_spec_code < HWRM_SPEC_CODE_1_9_2 || 4968 bp->flags & BNXT_FLAG_EXT_STATS_SUPPORTED) { 4969 bp->hw_tx_port_stats_ext = (void *) 4970 ((uint8_t *)bp->hw_tx_port_stats + 4971 sizeof(struct tx_port_stats)); 4972 bp->hw_tx_port_stats_ext_map = 4973 bp->hw_tx_port_stats_map + 4974 sizeof(struct tx_port_stats); 4975 bp->flags |= BNXT_FLAG_EXT_TX_PORT_STATS; 4976 } 4977 4978 return 0; 4979 } 4980 4981 static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) 4982 { 4983 struct bnxt *bp = eth_dev->data->dev_private; 4984 int rc = 0; 4985 4986 eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl", 4987 RTE_ETHER_ADDR_LEN * 4988 bp->max_l2_ctx, 4989 0); 4990 if (eth_dev->data->mac_addrs == NULL) { 4991 PMD_DRV_LOG(ERR, "Failed to alloc MAC addr tbl\n"); 4992 return -ENOMEM; 4993 } 4994 4995 if (!BNXT_HAS_DFLT_MAC_SET(bp)) { 4996 if (BNXT_PF(bp)) 4997 return -EINVAL; 4998 4999 /* Generate a random MAC address, if none was assigned by PF */ 5000 PMD_DRV_LOG(INFO, "VF MAC address not assigned by Host PF\n"); 5001 bnxt_eth_hw_addr_random(bp->mac_addr); 5002 PMD_DRV_LOG(INFO, 5003 "Assign random MAC:%02X:%02X:%02X:%02X:%02X:%02X\n", 5004 bp->mac_addr[0], bp->mac_addr[1], bp->mac_addr[2], 5005 bp->mac_addr[3], bp->mac_addr[4], bp->mac_addr[5]); 5006 5007 rc = bnxt_hwrm_set_mac(bp); 5008 if (rc) 5009 return rc; 5010 } 5011 5012 /* Copy the permanent MAC from the FUNC_QCAPS response */ 5013 memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, RTE_ETHER_ADDR_LEN); 5014 5015 return rc; 5016 } 5017 5018 static int bnxt_restore_dflt_mac(struct bnxt *bp) 5019 { 5020 int rc = 0; 5021 5022 /* MAC is already configured in FW */ 5023 if (BNXT_HAS_DFLT_MAC_SET(bp)) 5024 return 0; 5025 5026 /* Restore the old MAC configured */ 5027 rc = bnxt_hwrm_set_mac(bp); 5028 if (rc) 5029 PMD_DRV_LOG(ERR, "Failed to restore MAC address\n"); 5030 5031 return rc; 5032 } 5033 5034 static void bnxt_config_vf_req_fwd(struct bnxt *bp) 5035 { 5036 if (!BNXT_PF(bp)) 5037 return; 5038 5039 #define ALLOW_FUNC(x) \ 5040 { \ 5041 uint32_t arg = (x); \ 5042 bp->pf->vf_req_fwd[((arg) >> 5)] &= \ 5043 ~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \ 5044 } 5045 5046 /* Forward all requests if firmware is new enough */ 5047 if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) && 5048 (bp->fw_ver < ((20 << 24) | (7 << 16)))) || 5049 ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) { 5050 memset(bp->pf->vf_req_fwd, 0xff, sizeof(bp->pf->vf_req_fwd)); 5051 } else { 5052 PMD_DRV_LOG(WARNING, 5053 "Firmware too old for VF mailbox functionality\n"); 5054 memset(bp->pf->vf_req_fwd, 0, sizeof(bp->pf->vf_req_fwd)); 5055 } 5056 5057 /* 5058 * The following are used for driver cleanup. If we disallow these, 5059 * VF drivers can't clean up cleanly. 5060 */ 5061 ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR); 5062 ALLOW_FUNC(HWRM_VNIC_FREE); 5063 ALLOW_FUNC(HWRM_RING_FREE); 5064 ALLOW_FUNC(HWRM_RING_GRP_FREE); 5065 ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE); 5066 ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE); 5067 ALLOW_FUNC(HWRM_STAT_CTX_FREE); 5068 ALLOW_FUNC(HWRM_PORT_PHY_QCFG); 5069 ALLOW_FUNC(HWRM_VNIC_TPA_CFG); 5070 } 5071 5072 uint16_t 5073 bnxt_get_svif(uint16_t port_id, bool func_svif) 5074 { 5075 struct rte_eth_dev *eth_dev; 5076 struct bnxt *bp; 5077 5078 eth_dev = &rte_eth_devices[port_id]; 5079 bp = eth_dev->data->dev_private; 5080 5081 return func_svif ? bp->func_svif : bp->port_svif; 5082 } 5083 5084 uint16_t 5085 bnxt_get_vnic_id(uint16_t port) 5086 { 5087 struct rte_eth_dev *eth_dev; 5088 struct bnxt_vnic_info *vnic; 5089 struct bnxt *bp; 5090 5091 eth_dev = &rte_eth_devices[port]; 5092 bp = eth_dev->data->dev_private; 5093 5094 vnic = BNXT_GET_DEFAULT_VNIC(bp); 5095 5096 return vnic->fw_vnic_id; 5097 } 5098 5099 uint16_t 5100 bnxt_get_fw_func_id(uint16_t port) 5101 { 5102 struct rte_eth_dev *eth_dev; 5103 struct bnxt *bp; 5104 5105 eth_dev = &rte_eth_devices[port]; 5106 bp = eth_dev->data->dev_private; 5107 5108 return bp->fw_fid; 5109 } 5110 5111 static void bnxt_alloc_error_recovery_info(struct bnxt *bp) 5112 { 5113 struct bnxt_error_recovery_info *info = bp->recovery_info; 5114 5115 if (info) { 5116 if (!(bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS)) 5117 memset(info, 0, sizeof(*info)); 5118 return; 5119 } 5120 5121 if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) 5122 return; 5123 5124 info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", 5125 sizeof(*info), 0); 5126 if (!info) 5127 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 5128 5129 bp->recovery_info = info; 5130 } 5131 5132 static void bnxt_check_fw_status(struct bnxt *bp) 5133 { 5134 uint32_t fw_status; 5135 5136 if (!(bp->recovery_info && 5137 (bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS))) 5138 return; 5139 5140 fw_status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); 5141 if (fw_status != BNXT_FW_STATUS_HEALTHY) 5142 PMD_DRV_LOG(ERR, "Firmware not responding, status: %#x\n", 5143 fw_status); 5144 } 5145 5146 static int bnxt_map_hcomm_fw_status_reg(struct bnxt *bp) 5147 { 5148 struct bnxt_error_recovery_info *info = bp->recovery_info; 5149 uint32_t status_loc; 5150 uint32_t sig_ver; 5151 5152 rte_write32(HCOMM_STATUS_STRUCT_LOC, (uint8_t *)bp->bar0 + 5153 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 5154 sig_ver = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 5155 BNXT_GRCP_WINDOW_2_BASE + 5156 offsetof(struct hcomm_status, 5157 sig_ver))); 5158 /* If the signature is absent, then FW does not support this feature */ 5159 if ((sig_ver & HCOMM_STATUS_SIGNATURE_MASK) != 5160 HCOMM_STATUS_SIGNATURE_VAL) 5161 return 0; 5162 5163 if (!info) { 5164 info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", 5165 sizeof(*info), 0); 5166 if (!info) 5167 return -ENOMEM; 5168 bp->recovery_info = info; 5169 } else { 5170 memset(info, 0, sizeof(*info)); 5171 } 5172 5173 status_loc = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + 5174 BNXT_GRCP_WINDOW_2_BASE + 5175 offsetof(struct hcomm_status, 5176 fw_status_loc))); 5177 5178 /* Only pre-map the FW health status GRC register */ 5179 if (BNXT_FW_STATUS_REG_TYPE(status_loc) != BNXT_FW_STATUS_REG_TYPE_GRC) 5180 return 0; 5181 5182 info->status_regs[BNXT_FW_STATUS_REG] = status_loc; 5183 info->mapped_status_regs[BNXT_FW_STATUS_REG] = 5184 BNXT_GRCP_WINDOW_2_BASE + (status_loc & BNXT_GRCP_OFFSET_MASK); 5185 5186 rte_write32((status_loc & BNXT_GRCP_BASE_MASK), (uint8_t *)bp->bar0 + 5187 BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); 5188 5189 bp->fw_cap |= BNXT_FW_CAP_HCOMM_FW_STATUS; 5190 5191 return 0; 5192 } 5193 5194 static int bnxt_init_fw(struct bnxt *bp) 5195 { 5196 uint16_t mtu; 5197 int rc = 0; 5198 5199 bp->fw_cap = 0; 5200 5201 rc = bnxt_map_hcomm_fw_status_reg(bp); 5202 if (rc) 5203 return rc; 5204 5205 rc = bnxt_hwrm_ver_get(bp, DFLT_HWRM_CMD_TIMEOUT); 5206 if (rc) { 5207 bnxt_check_fw_status(bp); 5208 return rc; 5209 } 5210 5211 rc = bnxt_hwrm_func_reset(bp); 5212 if (rc) 5213 return -EIO; 5214 5215 rc = bnxt_hwrm_vnic_qcaps(bp); 5216 if (rc) 5217 return rc; 5218 5219 rc = bnxt_hwrm_queue_qportcfg(bp); 5220 if (rc) 5221 return rc; 5222 5223 /* Get the MAX capabilities for this function. 5224 * This function also allocates context memory for TQM rings and 5225 * informs the firmware about this allocated backing store memory. 5226 */ 5227 rc = bnxt_hwrm_func_qcaps(bp); 5228 if (rc) 5229 return rc; 5230 5231 rc = bnxt_hwrm_func_qcfg(bp, &mtu); 5232 if (rc) 5233 return rc; 5234 5235 bnxt_hwrm_port_mac_qcfg(bp); 5236 5237 rc = bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(bp); 5238 if (rc) 5239 return rc; 5240 5241 bnxt_alloc_error_recovery_info(bp); 5242 /* Get the adapter error recovery support info */ 5243 rc = bnxt_hwrm_error_recovery_qcfg(bp); 5244 if (rc) 5245 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 5246 5247 bnxt_hwrm_port_led_qcaps(bp); 5248 5249 return 0; 5250 } 5251 5252 static int 5253 bnxt_init_locks(struct bnxt *bp) 5254 { 5255 int err; 5256 5257 err = pthread_mutex_init(&bp->flow_lock, NULL); 5258 if (err) { 5259 PMD_DRV_LOG(ERR, "Unable to initialize flow_lock\n"); 5260 return err; 5261 } 5262 5263 err = pthread_mutex_init(&bp->def_cp_lock, NULL); 5264 if (err) 5265 PMD_DRV_LOG(ERR, "Unable to initialize def_cp_lock\n"); 5266 return err; 5267 } 5268 5269 static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev) 5270 { 5271 int rc; 5272 5273 rc = bnxt_init_fw(bp); 5274 if (rc) 5275 return rc; 5276 5277 if (!reconfig_dev) { 5278 rc = bnxt_setup_mac_addr(bp->eth_dev); 5279 if (rc) 5280 return rc; 5281 } else { 5282 rc = bnxt_restore_dflt_mac(bp); 5283 if (rc) 5284 return rc; 5285 } 5286 5287 bnxt_config_vf_req_fwd(bp); 5288 5289 rc = bnxt_hwrm_func_driver_register(bp); 5290 if (rc) { 5291 PMD_DRV_LOG(ERR, "Failed to register driver"); 5292 return -EBUSY; 5293 } 5294 5295 if (BNXT_PF(bp)) { 5296 if (bp->pdev->max_vfs) { 5297 rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs); 5298 if (rc) { 5299 PMD_DRV_LOG(ERR, "Failed to allocate VFs\n"); 5300 return rc; 5301 } 5302 } else { 5303 rc = bnxt_hwrm_allocate_pf_only(bp); 5304 if (rc) { 5305 PMD_DRV_LOG(ERR, 5306 "Failed to allocate PF resources"); 5307 return rc; 5308 } 5309 } 5310 } 5311 5312 rc = bnxt_alloc_mem(bp, reconfig_dev); 5313 if (rc) 5314 return rc; 5315 5316 rc = bnxt_setup_int(bp); 5317 if (rc) 5318 return rc; 5319 5320 rc = bnxt_request_int(bp); 5321 if (rc) 5322 return rc; 5323 5324 rc = bnxt_init_ctx_mem(bp); 5325 if (rc) { 5326 PMD_DRV_LOG(ERR, "Failed to init adv_flow_counters\n"); 5327 return rc; 5328 } 5329 5330 rc = bnxt_init_locks(bp); 5331 if (rc) 5332 return rc; 5333 5334 return 0; 5335 } 5336 5337 static int 5338 bnxt_parse_devarg_truflow(__rte_unused const char *key, 5339 const char *value, void *opaque_arg) 5340 { 5341 struct bnxt *bp = opaque_arg; 5342 unsigned long truflow; 5343 char *end = NULL; 5344 5345 if (!value || !opaque_arg) { 5346 PMD_DRV_LOG(ERR, 5347 "Invalid parameter passed to truflow devargs.\n"); 5348 return -EINVAL; 5349 } 5350 5351 truflow = strtoul(value, &end, 10); 5352 if (end == NULL || *end != '\0' || 5353 (truflow == ULONG_MAX && errno == ERANGE)) { 5354 PMD_DRV_LOG(ERR, 5355 "Invalid parameter passed to truflow devargs.\n"); 5356 return -EINVAL; 5357 } 5358 5359 if (BNXT_DEVARG_TRUFLOW_INVALID(truflow)) { 5360 PMD_DRV_LOG(ERR, 5361 "Invalid value passed to truflow devargs.\n"); 5362 return -EINVAL; 5363 } 5364 5365 bp->flags |= BNXT_FLAG_TRUFLOW_EN; 5366 if (BNXT_TRUFLOW_EN(bp)) 5367 PMD_DRV_LOG(INFO, "Host-based truflow feature enabled.\n"); 5368 5369 return 0; 5370 } 5371 5372 static int 5373 bnxt_parse_devarg_flow_xstat(__rte_unused const char *key, 5374 const char *value, void *opaque_arg) 5375 { 5376 struct bnxt *bp = opaque_arg; 5377 unsigned long flow_xstat; 5378 char *end = NULL; 5379 5380 if (!value || !opaque_arg) { 5381 PMD_DRV_LOG(ERR, 5382 "Invalid parameter passed to flow_xstat devarg.\n"); 5383 return -EINVAL; 5384 } 5385 5386 flow_xstat = strtoul(value, &end, 10); 5387 if (end == NULL || *end != '\0' || 5388 (flow_xstat == ULONG_MAX && errno == ERANGE)) { 5389 PMD_DRV_LOG(ERR, 5390 "Invalid parameter passed to flow_xstat devarg.\n"); 5391 return -EINVAL; 5392 } 5393 5394 if (BNXT_DEVARG_FLOW_XSTAT_INVALID(flow_xstat)) { 5395 PMD_DRV_LOG(ERR, 5396 "Invalid value passed to flow_xstat devarg.\n"); 5397 return -EINVAL; 5398 } 5399 5400 bp->flags |= BNXT_FLAG_FLOW_XSTATS_EN; 5401 if (BNXT_FLOW_XSTATS_EN(bp)) 5402 PMD_DRV_LOG(INFO, "flow_xstat feature enabled.\n"); 5403 5404 return 0; 5405 } 5406 5407 static int 5408 bnxt_parse_devarg_max_num_kflows(__rte_unused const char *key, 5409 const char *value, void *opaque_arg) 5410 { 5411 struct bnxt *bp = opaque_arg; 5412 unsigned long max_num_kflows; 5413 char *end = NULL; 5414 5415 if (!value || !opaque_arg) { 5416 PMD_DRV_LOG(ERR, 5417 "Invalid parameter passed to max_num_kflows devarg.\n"); 5418 return -EINVAL; 5419 } 5420 5421 max_num_kflows = strtoul(value, &end, 10); 5422 if (end == NULL || *end != '\0' || 5423 (max_num_kflows == ULONG_MAX && errno == ERANGE)) { 5424 PMD_DRV_LOG(ERR, 5425 "Invalid parameter passed to max_num_kflows devarg.\n"); 5426 return -EINVAL; 5427 } 5428 5429 if (bnxt_devarg_max_num_kflow_invalid(max_num_kflows)) { 5430 PMD_DRV_LOG(ERR, 5431 "Invalid value passed to max_num_kflows devarg.\n"); 5432 return -EINVAL; 5433 } 5434 5435 bp->max_num_kflows = max_num_kflows; 5436 if (bp->max_num_kflows) 5437 PMD_DRV_LOG(INFO, "max_num_kflows set as %ldK.\n", 5438 max_num_kflows); 5439 5440 return 0; 5441 } 5442 5443 static void 5444 bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs) 5445 { 5446 struct rte_kvargs *kvlist; 5447 5448 if (devargs == NULL) 5449 return; 5450 5451 kvlist = rte_kvargs_parse(devargs->args, bnxt_dev_args); 5452 if (kvlist == NULL) 5453 return; 5454 5455 /* 5456 * Handler for "truflow" devarg. 5457 * Invoked as for ex: "-w 0000:00:0d.0,host-based-truflow=1" 5458 */ 5459 rte_kvargs_process(kvlist, BNXT_DEVARG_TRUFLOW, 5460 bnxt_parse_devarg_truflow, bp); 5461 5462 /* 5463 * Handler for "flow_xstat" devarg. 5464 * Invoked as for ex: "-w 0000:00:0d.0,flow_xstat=1" 5465 */ 5466 rte_kvargs_process(kvlist, BNXT_DEVARG_FLOW_XSTAT, 5467 bnxt_parse_devarg_flow_xstat, bp); 5468 5469 /* 5470 * Handler for "max_num_kflows" devarg. 5471 * Invoked as for ex: "-w 000:00:0d.0,max_num_kflows=32" 5472 */ 5473 rte_kvargs_process(kvlist, BNXT_DEVARG_MAX_NUM_KFLOWS, 5474 bnxt_parse_devarg_max_num_kflows, bp); 5475 5476 rte_kvargs_free(kvlist); 5477 } 5478 5479 static int 5480 bnxt_dev_init(struct rte_eth_dev *eth_dev) 5481 { 5482 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 5483 static int version_printed; 5484 struct bnxt *bp; 5485 int rc; 5486 5487 if (version_printed++ == 0) 5488 PMD_DRV_LOG(INFO, "%s\n", bnxt_version); 5489 5490 eth_dev->dev_ops = &bnxt_dev_ops; 5491 eth_dev->rx_pkt_burst = &bnxt_recv_pkts; 5492 eth_dev->tx_pkt_burst = &bnxt_xmit_pkts; 5493 5494 /* 5495 * For secondary processes, we don't initialise any further 5496 * as primary has already done this work. 5497 */ 5498 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 5499 return 0; 5500 5501 rte_eth_copy_pci_info(eth_dev, pci_dev); 5502 5503 bp = eth_dev->data->dev_private; 5504 5505 /* Parse dev arguments passed on when starting the DPDK application. */ 5506 bnxt_parse_dev_args(bp, pci_dev->device.devargs); 5507 5508 bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE; 5509 5510 if (bnxt_vf_pciid(pci_dev->id.device_id)) 5511 bp->flags |= BNXT_FLAG_VF; 5512 5513 if (bnxt_thor_device(pci_dev->id.device_id)) 5514 bp->flags |= BNXT_FLAG_THOR_CHIP; 5515 5516 if (pci_dev->id.device_id == BROADCOM_DEV_ID_58802 || 5517 pci_dev->id.device_id == BROADCOM_DEV_ID_58804 || 5518 pci_dev->id.device_id == BROADCOM_DEV_ID_58808 || 5519 pci_dev->id.device_id == BROADCOM_DEV_ID_58802_VF) 5520 bp->flags |= BNXT_FLAG_STINGRAY; 5521 5522 rc = bnxt_init_board(eth_dev); 5523 if (rc) { 5524 PMD_DRV_LOG(ERR, 5525 "Failed to initialize board rc: %x\n", rc); 5526 return rc; 5527 } 5528 5529 rc = bnxt_alloc_pf_info(bp); 5530 if (rc) 5531 goto error_free; 5532 5533 rc = bnxt_alloc_link_info(bp); 5534 if (rc) 5535 goto error_free; 5536 5537 rc = bnxt_alloc_hwrm_resources(bp); 5538 if (rc) { 5539 PMD_DRV_LOG(ERR, 5540 "Failed to allocate hwrm resource rc: %x\n", rc); 5541 goto error_free; 5542 } 5543 rc = bnxt_alloc_leds_info(bp); 5544 if (rc) 5545 goto error_free; 5546 5547 rc = bnxt_alloc_cos_queues(bp); 5548 if (rc) 5549 goto error_free; 5550 5551 rc = bnxt_init_resources(bp, false); 5552 if (rc) 5553 goto error_free; 5554 5555 rc = bnxt_alloc_stats_mem(bp); 5556 if (rc) 5557 goto error_free; 5558 5559 /* Pass the information to the rte_eth_dev_close() that it should also 5560 * release the private port resources. 5561 */ 5562 eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; 5563 5564 PMD_DRV_LOG(INFO, 5565 DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n", 5566 pci_dev->mem_resource[0].phys_addr, 5567 pci_dev->mem_resource[0].addr); 5568 5569 return 0; 5570 5571 error_free: 5572 bnxt_dev_uninit(eth_dev); 5573 return rc; 5574 } 5575 5576 5577 static void bnxt_free_ctx_mem_buf(struct bnxt_ctx_mem_buf_info *ctx) 5578 { 5579 if (!ctx) 5580 return; 5581 5582 if (ctx->va) 5583 rte_free(ctx->va); 5584 5585 ctx->va = NULL; 5586 ctx->dma = RTE_BAD_IOVA; 5587 ctx->ctx_id = BNXT_CTX_VAL_INVAL; 5588 } 5589 5590 static void bnxt_unregister_fc_ctx_mem(struct bnxt *bp) 5591 { 5592 bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_RX, 5593 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 5594 bp->flow_stat->rx_fc_out_tbl.ctx_id, 5595 bp->flow_stat->max_fc, 5596 false); 5597 5598 bnxt_hwrm_cfa_counter_cfg(bp, BNXT_DIR_TX, 5599 CFA_COUNTER_CFG_IN_COUNTER_TYPE_FC, 5600 bp->flow_stat->tx_fc_out_tbl.ctx_id, 5601 bp->flow_stat->max_fc, 5602 false); 5603 5604 if (bp->flow_stat->rx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5605 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_in_tbl.ctx_id); 5606 bp->flow_stat->rx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5607 5608 if (bp->flow_stat->rx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5609 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->rx_fc_out_tbl.ctx_id); 5610 bp->flow_stat->rx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5611 5612 if (bp->flow_stat->tx_fc_in_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5613 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_in_tbl.ctx_id); 5614 bp->flow_stat->tx_fc_in_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5615 5616 if (bp->flow_stat->tx_fc_out_tbl.ctx_id != BNXT_CTX_VAL_INVAL) 5617 bnxt_hwrm_ctx_unrgtr(bp, bp->flow_stat->tx_fc_out_tbl.ctx_id); 5618 bp->flow_stat->tx_fc_out_tbl.ctx_id = BNXT_CTX_VAL_INVAL; 5619 } 5620 5621 static void bnxt_uninit_fc_ctx_mem(struct bnxt *bp) 5622 { 5623 bnxt_unregister_fc_ctx_mem(bp); 5624 5625 bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_in_tbl); 5626 bnxt_free_ctx_mem_buf(&bp->flow_stat->rx_fc_out_tbl); 5627 bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_in_tbl); 5628 bnxt_free_ctx_mem_buf(&bp->flow_stat->tx_fc_out_tbl); 5629 } 5630 5631 static void bnxt_uninit_ctx_mem(struct bnxt *bp) 5632 { 5633 if (BNXT_FLOW_XSTATS_EN(bp)) 5634 bnxt_uninit_fc_ctx_mem(bp); 5635 } 5636 5637 static void 5638 bnxt_free_error_recovery_info(struct bnxt *bp) 5639 { 5640 rte_free(bp->recovery_info); 5641 bp->recovery_info = NULL; 5642 bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; 5643 } 5644 5645 static void 5646 bnxt_uninit_locks(struct bnxt *bp) 5647 { 5648 pthread_mutex_destroy(&bp->flow_lock); 5649 pthread_mutex_destroy(&bp->def_cp_lock); 5650 } 5651 5652 static int 5653 bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) 5654 { 5655 int rc; 5656 5657 bnxt_free_int(bp); 5658 bnxt_free_mem(bp, reconfig_dev); 5659 bnxt_hwrm_func_buf_unrgtr(bp); 5660 rc = bnxt_hwrm_func_driver_unregister(bp, 0); 5661 bp->flags &= ~BNXT_FLAG_REGISTERED; 5662 bnxt_free_ctx_mem(bp); 5663 if (!reconfig_dev) { 5664 bnxt_free_hwrm_resources(bp); 5665 bnxt_free_error_recovery_info(bp); 5666 } 5667 5668 bnxt_uninit_ctx_mem(bp); 5669 5670 bnxt_uninit_locks(bp); 5671 bnxt_free_flow_stats_info(bp); 5672 rte_free(bp->ptp_cfg); 5673 bp->ptp_cfg = NULL; 5674 return rc; 5675 } 5676 5677 static int 5678 bnxt_dev_uninit(struct rte_eth_dev *eth_dev) 5679 { 5680 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 5681 return -EPERM; 5682 5683 PMD_DRV_LOG(DEBUG, "Calling Device uninit\n"); 5684 5685 if (eth_dev->state != RTE_ETH_DEV_UNUSED) 5686 bnxt_dev_close_op(eth_dev); 5687 5688 return 0; 5689 } 5690 5691 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 5692 struct rte_pci_device *pci_dev) 5693 { 5694 return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct bnxt), 5695 bnxt_dev_init); 5696 } 5697 5698 static int bnxt_pci_remove(struct rte_pci_device *pci_dev) 5699 { 5700 if (rte_eal_process_type() == RTE_PROC_PRIMARY) 5701 return rte_eth_dev_pci_generic_remove(pci_dev, 5702 bnxt_dev_uninit); 5703 else 5704 return rte_eth_dev_pci_generic_remove(pci_dev, NULL); 5705 } 5706 5707 static struct rte_pci_driver bnxt_rte_pmd = { 5708 .id_table = bnxt_pci_id_map, 5709 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 5710 .probe = bnxt_pci_probe, 5711 .remove = bnxt_pci_remove, 5712 }; 5713 5714 static bool 5715 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv) 5716 { 5717 if (strcmp(dev->device->driver->name, drv->driver.name)) 5718 return false; 5719 5720 return true; 5721 } 5722 5723 bool is_bnxt_supported(struct rte_eth_dev *dev) 5724 { 5725 return is_device_supported(dev, &bnxt_rte_pmd); 5726 } 5727 5728 RTE_LOG_REGISTER(bnxt_logtype_driver, pmd.net.bnxt.driver, NOTICE); 5729 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd); 5730 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map); 5731 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio-pci"); 5732