if_bnxt.c revision 309377
1/*- 2 * Broadcom NetXtreme-C/E network driver. 3 * 4 * Copyright (c) 2016 Broadcom, All Rights Reserved. 5 * The term Broadcom refers to Broadcom Limited and/or its subsidiaries 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: stable/11/sys/dev/bnxt/if_bnxt.c 309377 2016-12-01 23:37:17Z shurd $"); 31 32#include <sys/param.h> 33#include <sys/socket.h> 34#include <sys/kernel.h> 35#include <sys/bus.h> 36#include <sys/module.h> 37#include <sys/rman.h> 38#include <sys/endian.h> 39#include <sys/sockio.h> 40#include <sys/priv.h> 41 42#include <machine/bus.h> 43#include <machine/resource.h> 44 45#include <dev/pci/pcireg.h> 46#include <dev/pci/pcivar.h> 47 48#include <net/if.h> 49#include <net/if_media.h> 50#include <net/if_var.h> 51#include <net/ethernet.h> 52#include <net/iflib.h> 53 54#include "opt_inet.h" 55#include "opt_inet6.h" 56#include "opt_rss.h" 57 58#include "ifdi_if.h" 59 60#include "bnxt.h" 61#include "bnxt_hwrm.h" 62#include "bnxt_ioctl.h" 63#include "bnxt_sysctl.h" 64#include "hsi_struct_def.h" 65 66/* 67 * PCI Device ID Table 68 */ 69 70static pci_vendor_info_t bnxt_vendor_info_array[] = 71{ 72 PVID(BROADCOM_VENDOR_ID, BCM57301, 73 "Broadcom BCM57301 NetXtreme-C 10Gb Ethernet Controller"), 74 PVID(BROADCOM_VENDOR_ID, BCM57302, 75 "Broadcom BCM57302 NetXtreme-C 10Gb/25Gb Ethernet Controller"), 76 PVID(BROADCOM_VENDOR_ID, BCM57304, 77 "Broadcom BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller"), 78 PVID(BROADCOM_VENDOR_ID, BCM57311, 79 "Broadcom BCM57311 NetXtreme-C 10Gb Ethernet"), 80 PVID(BROADCOM_VENDOR_ID, BCM57312, 81 "Broadcom BCM57312 NetXtreme-C 10Gb/25Gb Ethernet"), 82 PVID(BROADCOM_VENDOR_ID, BCM57314, 83 "Broadcom BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet"), 84 PVID(BROADCOM_VENDOR_ID, BCM57402, 85 "Broadcom BCM57402 NetXtreme-E 10Gb Ethernet Controller"), 86 PVID(BROADCOM_VENDOR_ID, BCM57402_NPAR, 87 "Broadcom BCM57402 NetXtreme-E Partition"), 88 PVID(BROADCOM_VENDOR_ID, BCM57404, 89 "Broadcom BCM57404 NetXtreme-E 10Gb/25Gb Ethernet Controller"), 90 PVID(BROADCOM_VENDOR_ID, BCM57404_NPAR, 91 "Broadcom BCM57404 NetXtreme-E Partition"), 92 PVID(BROADCOM_VENDOR_ID, BCM57406, 93 "Broadcom BCM57406 NetXtreme-E 10GBase-T Ethernet Controller"), 94 PVID(BROADCOM_VENDOR_ID, BCM57406_NPAR, 95 "Broadcom BCM57406 NetXtreme-E Partition"), 96 PVID(BROADCOM_VENDOR_ID, BCM57407, 97 "Broadcom BCM57407 NetXtreme-E 10GBase-T Ethernet Controller"), 98 PVID(BROADCOM_VENDOR_ID, BCM57407_NPAR, 99 "Broadcom BCM57407 NetXtreme-E Ethernet Partition"), 100 PVID(BROADCOM_VENDOR_ID, BCM57407_SFP, 101 "Broadcom BCM57407 NetXtreme-E 25Gb Ethernet Controller"), 102 PVID(BROADCOM_VENDOR_ID, BCM57412, 103 "Broadcom BCM57412 NetXtreme-E 10Gb Ethernet"), 104 PVID(BROADCOM_VENDOR_ID, BCM57412_NPAR1, 105 "Broadcom BCM57412 NetXtreme-E Ethernet Partition"), 106 PVID(BROADCOM_VENDOR_ID, BCM57412_NPAR2, 107 "Broadcom BCM57412 NetXtreme-E Ethernet Partition"), 108 PVID(BROADCOM_VENDOR_ID, BCM57414, 109 "Broadcom BCM57414 NetXtreme-E 10Gb/25Gb Ethernet"), 110 PVID(BROADCOM_VENDOR_ID, BCM57414_NPAR1, 111 "Broadcom BCM57414 NetXtreme-E Ethernet Partition"), 112 PVID(BROADCOM_VENDOR_ID, BCM57414_NPAR2, 113 "Broadcom BCM57414 NetXtreme-E Ethernet Partition"), 114 PVID(BROADCOM_VENDOR_ID, BCM57416, 115 "Broadcom BCM57416 NetXtreme-E 10GBase-T Ethernet"), 116 PVID(BROADCOM_VENDOR_ID, BCM57416_NPAR1, 117 "Broadcom BCM57416 NetXtreme-E Ethernet Partition"), 118 PVID(BROADCOM_VENDOR_ID, BCM57416_NPAR2, 119 "Broadcom BCM57416 NetXtreme-E Ethernet Partition"), 120 PVID(BROADCOM_VENDOR_ID, BCM57416_SFP, 121 "Broadcom BCM57416 NetXtreme-E 10Gb Ethernet"), 122 PVID(BROADCOM_VENDOR_ID, BCM57417, 123 "Broadcom BCM57417 NetXtreme-E 10GBase-T Ethernet"), 124 PVID(BROADCOM_VENDOR_ID, BCM57417_NPAR1, 125 "Broadcom BCM57417 NetXtreme-E Ethernet Partition"), 126 PVID(BROADCOM_VENDOR_ID, BCM57417_NPAR2, 127 "Broadcom BCM57417 NetXtreme-E Ethernet Partition"), 128 PVID(BROADCOM_VENDOR_ID, BCM57417_SFP, 129 "Broadcom BCM57417 NetXtreme-E 10Gb/25Gb Ethernet"), 130 PVID(BROADCOM_VENDOR_ID, BCM58700, 131 "Broadcom BCM58700 Nitro 1Gb/2.5Gb/10Gb Ethernet"), 132 PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF1, 133 "Broadcom NetXtreme-C Ethernet Virtual Function"), 134 PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF2, 135 "Broadcom NetXtreme-C Ethernet Virtual Function"), 136 PVID(BROADCOM_VENDOR_ID, NETXTREME_C_VF3, 137 "Broadcom NetXtreme-C Ethernet Virtual Function"), 138 PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF1, 139 "Broadcom NetXtreme-E Ethernet Virtual Function"), 140 PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF2, 141 "Broadcom NetXtreme-E Ethernet Virtual Function"), 142 PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF3, 143 "Broadcom NetXtreme-E Ethernet Virtual Function"), 144 /* required last entry */ 145 146 PVID_END 147}; 148 149/* 150 * Function prototypes 151 */ 152 153static void *bnxt_register(device_t dev); 154 155/* Soft queue setup and teardown */ 156static int bnxt_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 157 uint64_t *paddrs, int ntxqs, int ntxqsets); 158static int bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 159 uint64_t *paddrs, int nrxqs, int nrxqsets); 160static void bnxt_queues_free(if_ctx_t ctx); 161 162/* Device setup and teardown */ 163static int bnxt_attach_pre(if_ctx_t ctx); 164static int bnxt_attach_post(if_ctx_t ctx); 165static int bnxt_detach(if_ctx_t ctx); 166 167/* Device configuration */ 168static void bnxt_init(if_ctx_t ctx); 169static void bnxt_stop(if_ctx_t ctx); 170static void bnxt_multi_set(if_ctx_t ctx); 171static int bnxt_mtu_set(if_ctx_t ctx, uint32_t mtu); 172static void bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr); 173static int bnxt_media_change(if_ctx_t ctx); 174static int bnxt_promisc_set(if_ctx_t ctx, int flags); 175static uint64_t bnxt_get_counter(if_ctx_t, ift_counter); 176static void bnxt_update_admin_status(if_ctx_t ctx); 177 178/* Interrupt enable / disable */ 179static void bnxt_intr_enable(if_ctx_t ctx); 180static int bnxt_queue_intr_enable(if_ctx_t ctx, uint16_t qid); 181static void bnxt_disable_intr(if_ctx_t ctx); 182static int bnxt_msix_intr_assign(if_ctx_t ctx, int msix); 183 184/* vlan support */ 185static void bnxt_vlan_register(if_ctx_t ctx, uint16_t vtag); 186static void bnxt_vlan_unregister(if_ctx_t ctx, uint16_t vtag); 187 188/* ioctl */ 189static int bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data); 190 191/* Internal support functions */ 192static int bnxt_probe_phy(struct bnxt_softc *softc); 193static void bnxt_add_media_types(struct bnxt_softc *softc); 194static int bnxt_pci_mapping(struct bnxt_softc *softc); 195static void bnxt_pci_mapping_free(struct bnxt_softc *softc); 196static int bnxt_update_link(struct bnxt_softc *softc, bool chng_link_state); 197static int bnxt_handle_def_cp(void *arg); 198static int bnxt_handle_rx_cp(void *arg); 199static void bnxt_clear_ids(struct bnxt_softc *softc); 200static void inline bnxt_do_enable_intr(struct bnxt_cp_ring *cpr); 201static void inline bnxt_do_disable_intr(struct bnxt_cp_ring *cpr); 202static void bnxt_mark_cpr_invalid(struct bnxt_cp_ring *cpr); 203static void bnxt_def_cp_task(void *context); 204static void bnxt_handle_async_event(struct bnxt_softc *softc, 205 struct cmpl_base *cmpl); 206static uint8_t get_phy_type(struct bnxt_softc *softc); 207static uint64_t bnxt_get_baudrate(struct bnxt_link_info *link); 208 209/* 210 * Device Interface Declaration 211 */ 212 213static device_method_t bnxt_methods[] = { 214 /* Device interface */ 215 DEVMETHOD(device_register, bnxt_register), 216 DEVMETHOD(device_probe, iflib_device_probe), 217 DEVMETHOD(device_attach, iflib_device_attach), 218 DEVMETHOD(device_detach, iflib_device_detach), 219 DEVMETHOD(device_shutdown, iflib_device_shutdown), 220 DEVMETHOD(device_suspend, iflib_device_suspend), 221 DEVMETHOD(device_resume, iflib_device_resume), 222 DEVMETHOD_END 223}; 224 225static driver_t bnxt_driver = { 226 "bnxt", bnxt_methods, sizeof(struct bnxt_softc), 227}; 228 229devclass_t bnxt_devclass; 230DRIVER_MODULE(bnxt, pci, bnxt_driver, bnxt_devclass, 0, 0); 231 232MODULE_DEPEND(bnxt, pci, 1, 1, 1); 233MODULE_DEPEND(bnxt, ether, 1, 1, 1); 234MODULE_DEPEND(bnxt, iflib, 1, 1, 1); 235 236static device_method_t bnxt_iflib_methods[] = { 237 DEVMETHOD(ifdi_tx_queues_alloc, bnxt_tx_queues_alloc), 238 DEVMETHOD(ifdi_rx_queues_alloc, bnxt_rx_queues_alloc), 239 DEVMETHOD(ifdi_queues_free, bnxt_queues_free), 240 241 DEVMETHOD(ifdi_attach_pre, bnxt_attach_pre), 242 DEVMETHOD(ifdi_attach_post, bnxt_attach_post), 243 DEVMETHOD(ifdi_detach, bnxt_detach), 244 245 DEVMETHOD(ifdi_init, bnxt_init), 246 DEVMETHOD(ifdi_stop, bnxt_stop), 247 DEVMETHOD(ifdi_multi_set, bnxt_multi_set), 248 DEVMETHOD(ifdi_mtu_set, bnxt_mtu_set), 249 DEVMETHOD(ifdi_media_status, bnxt_media_status), 250 DEVMETHOD(ifdi_media_change, bnxt_media_change), 251 DEVMETHOD(ifdi_promisc_set, bnxt_promisc_set), 252 DEVMETHOD(ifdi_get_counter, bnxt_get_counter), 253 DEVMETHOD(ifdi_update_admin_status, bnxt_update_admin_status), 254 255 DEVMETHOD(ifdi_intr_enable, bnxt_intr_enable), 256 DEVMETHOD(ifdi_queue_intr_enable, bnxt_queue_intr_enable), 257 DEVMETHOD(ifdi_intr_disable, bnxt_disable_intr), 258 DEVMETHOD(ifdi_msix_intr_assign, bnxt_msix_intr_assign), 259 260 DEVMETHOD(ifdi_vlan_register, bnxt_vlan_register), 261 DEVMETHOD(ifdi_vlan_unregister, bnxt_vlan_unregister), 262 263 DEVMETHOD(ifdi_priv_ioctl, bnxt_priv_ioctl), 264 265 DEVMETHOD_END 266}; 267 268static driver_t bnxt_iflib_driver = { 269 "bnxt", bnxt_iflib_methods, sizeof(struct bnxt_softc) 270}; 271 272/* 273 * iflib shared context 274 */ 275 276char bnxt_driver_version[] = "FreeBSD base"; 277extern struct if_txrx bnxt_txrx; 278static struct if_shared_ctx bnxt_sctx_init = { 279 .isc_magic = IFLIB_MAGIC, 280 .isc_txrx = &bnxt_txrx, 281 .isc_driver = &bnxt_iflib_driver, 282 .isc_nfl = 2, // Number of Free Lists 283 .isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ, 284 .isc_q_align = PAGE_SIZE, 285 .isc_tx_maxsize = BNXT_TSO_SIZE, 286 .isc_tx_maxsegsize = BNXT_TSO_SIZE, 287 .isc_rx_maxsize = BNXT_TSO_SIZE, 288 .isc_rx_maxsegsize = BNXT_TSO_SIZE, 289 290 // Only use a single segment to avoid page size constraints 291 .isc_rx_nsegments = 1, 292 .isc_ntxqs = 2, 293 .isc_nrxqs = 3, 294 .isc_nrxd_min = {16, 16, 16}, 295 .isc_nrxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 8, 296 PAGE_SIZE / sizeof(struct rx_prod_pkt_bd), 297 PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)}, 298 .isc_nrxd_max = {INT32_MAX, INT32_MAX, INT32_MAX}, 299 .isc_ntxd_min = {16, 16, 16}, 300 .isc_ntxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 2, 301 PAGE_SIZE / sizeof(struct tx_bd_short)}, 302 .isc_ntxd_max = {INT32_MAX, INT32_MAX, INT32_MAX}, 303 304 .isc_admin_intrcnt = 1, 305 .isc_vendor_info = bnxt_vendor_info_array, 306 .isc_driver_version = bnxt_driver_version, 307}; 308 309if_shared_ctx_t bnxt_sctx = &bnxt_sctx_init; 310 311/* 312 * Device Methods 313 */ 314 315static void * 316bnxt_register(device_t dev) 317{ 318 return bnxt_sctx; 319} 320 321/* 322 * Device Dependent Configuration Functions 323*/ 324 325/* Soft queue setup and teardown */ 326static int 327bnxt_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 328 uint64_t *paddrs, int ntxqs, int ntxqsets) 329{ 330 struct bnxt_softc *softc; 331 int i; 332 int rc; 333 334 softc = iflib_get_softc(ctx); 335 336 softc->tx_cp_rings = malloc(sizeof(struct bnxt_cp_ring) * ntxqsets, 337 M_DEVBUF, M_NOWAIT | M_ZERO); 338 if (!softc->tx_cp_rings) { 339 device_printf(iflib_get_dev(ctx), 340 "unable to allocate TX completion rings\n"); 341 rc = ENOMEM; 342 goto cp_alloc_fail; 343 } 344 softc->tx_rings = malloc(sizeof(struct bnxt_ring) * ntxqsets, 345 M_DEVBUF, M_NOWAIT | M_ZERO); 346 if (!softc->tx_rings) { 347 device_printf(iflib_get_dev(ctx), 348 "unable to allocate TX rings\n"); 349 rc = ENOMEM; 350 goto ring_alloc_fail; 351 } 352 rc = iflib_dma_alloc(ctx, sizeof(struct ctx_hw_stats) * ntxqsets, 353 &softc->tx_stats, 0); 354 if (rc) 355 goto dma_alloc_fail; 356 bus_dmamap_sync(softc->tx_stats.idi_tag, softc->tx_stats.idi_map, 357 BUS_DMASYNC_PREREAD); 358 359 for (i = 0; i < ntxqsets; i++) { 360 /* Set up the completion ring */ 361 softc->tx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE; 362 softc->tx_cp_rings[i].ring.phys_id = 363 (uint16_t)HWRM_NA_SIGNATURE; 364 softc->tx_cp_rings[i].ring.softc = softc; 365 softc->tx_cp_rings[i].ring.id = 366 (softc->scctx->isc_nrxqsets * 2) + 1 + i; 367 softc->tx_cp_rings[i].ring.doorbell = 368 softc->tx_cp_rings[i].ring.id * 0x80; 369 softc->tx_cp_rings[i].ring.ring_size = 370 softc->scctx->isc_ntxd[0]; 371 softc->tx_cp_rings[i].ring.vaddr = vaddrs[i * ntxqs]; 372 softc->tx_cp_rings[i].ring.paddr = paddrs[i * ntxqs]; 373 374 /* Set up the TX ring */ 375 softc->tx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 376 softc->tx_rings[i].softc = softc; 377 softc->tx_rings[i].id = 378 (softc->scctx->isc_nrxqsets * 2) + 1 + i; 379 softc->tx_rings[i].doorbell = softc->tx_rings[i].id * 0x80; 380 softc->tx_rings[i].ring_size = softc->scctx->isc_ntxd[1]; 381 softc->tx_rings[i].vaddr = vaddrs[i * ntxqs + 1]; 382 softc->tx_rings[i].paddr = paddrs[i * ntxqs + 1]; 383 384 bnxt_create_tx_sysctls(softc, i); 385 } 386 387 softc->ntxqsets = ntxqsets; 388 return rc; 389 390dma_alloc_fail: 391 free(softc->tx_rings, M_DEVBUF); 392ring_alloc_fail: 393 free(softc->tx_cp_rings, M_DEVBUF); 394cp_alloc_fail: 395 return rc; 396} 397 398static void 399bnxt_queues_free(if_ctx_t ctx) 400{ 401 struct bnxt_softc *softc = iflib_get_softc(ctx); 402 403 // Free TX queues 404 iflib_dma_free(&softc->tx_stats); 405 free(softc->tx_rings, M_DEVBUF); 406 softc->tx_rings = NULL; 407 free(softc->tx_cp_rings, M_DEVBUF); 408 softc->tx_cp_rings = NULL; 409 softc->ntxqsets = 0; 410 411 // Free RX queues 412 iflib_dma_free(&softc->rx_stats); 413 free(softc->grp_info, M_DEVBUF); 414 free(softc->ag_rings, M_DEVBUF); 415 free(softc->rx_rings, M_DEVBUF); 416 free(softc->rx_cp_rings, M_DEVBUF); 417} 418 419static int 420bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 421 uint64_t *paddrs, int nrxqs, int nrxqsets) 422{ 423 struct bnxt_softc *softc; 424 int i; 425 int rc; 426 427 softc = iflib_get_softc(ctx); 428 429 softc->rx_cp_rings = malloc(sizeof(struct bnxt_cp_ring) * nrxqsets, 430 M_DEVBUF, M_NOWAIT | M_ZERO); 431 if (!softc->rx_cp_rings) { 432 device_printf(iflib_get_dev(ctx), 433 "unable to allocate RX completion rings\n"); 434 rc = ENOMEM; 435 goto cp_alloc_fail; 436 } 437 softc->rx_rings = malloc(sizeof(struct bnxt_ring) * nrxqsets, 438 M_DEVBUF, M_NOWAIT | M_ZERO); 439 if (!softc->rx_rings) { 440 device_printf(iflib_get_dev(ctx), 441 "unable to allocate RX rings\n"); 442 rc = ENOMEM; 443 goto ring_alloc_fail; 444 } 445 softc->ag_rings = malloc(sizeof(struct bnxt_ring) * nrxqsets, 446 M_DEVBUF, M_NOWAIT | M_ZERO); 447 if (!softc->ag_rings) { 448 device_printf(iflib_get_dev(ctx), 449 "unable to allocate aggregation rings\n"); 450 rc = ENOMEM; 451 goto ag_alloc_fail; 452 } 453 softc->grp_info = malloc(sizeof(struct bnxt_grp_info) * nrxqsets, 454 M_DEVBUF, M_NOWAIT | M_ZERO); 455 if (!softc->grp_info) { 456 device_printf(iflib_get_dev(ctx), 457 "unable to allocate ring groups\n"); 458 rc = ENOMEM; 459 goto grp_alloc_fail; 460 } 461 462 rc = iflib_dma_alloc(ctx, sizeof(struct ctx_hw_stats) * nrxqsets, 463 &softc->rx_stats, 0); 464 if (rc) 465 goto hw_stats_alloc_fail; 466 bus_dmamap_sync(softc->rx_stats.idi_tag, softc->rx_stats.idi_map, 467 BUS_DMASYNC_PREREAD); 468 469 for (i = 0; i < nrxqsets; i++) { 470 /* Allocation the completion ring */ 471 softc->rx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE; 472 softc->rx_cp_rings[i].ring.phys_id = 473 (uint16_t)HWRM_NA_SIGNATURE; 474 softc->rx_cp_rings[i].ring.softc = softc; 475 softc->rx_cp_rings[i].ring.id = i + 1; 476 softc->rx_cp_rings[i].ring.doorbell = 477 softc->rx_cp_rings[i].ring.id * 0x80; 478 /* 479 * If this ring overflows, RX stops working. 480 */ 481 softc->rx_cp_rings[i].ring.ring_size = 482 softc->scctx->isc_nrxd[0]; 483 softc->rx_cp_rings[i].ring.vaddr = vaddrs[i * nrxqs]; 484 softc->rx_cp_rings[i].ring.paddr = paddrs[i * nrxqs]; 485 486 /* Allocate the RX ring */ 487 softc->rx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 488 softc->rx_rings[i].softc = softc; 489 softc->rx_rings[i].id = i + 1; 490 softc->rx_rings[i].doorbell = softc->rx_rings[i].id * 0x80; 491 softc->rx_rings[i].ring_size = softc->scctx->isc_nrxd[1]; 492 softc->rx_rings[i].vaddr = vaddrs[i * nrxqs + 1]; 493 softc->rx_rings[i].paddr = paddrs[i * nrxqs + 1]; 494 495 /* Allocate the AG ring */ 496 softc->ag_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 497 softc->ag_rings[i].softc = softc; 498 softc->ag_rings[i].id = nrxqsets + i + 1; 499 softc->ag_rings[i].doorbell = softc->ag_rings[i].id * 0x80; 500 softc->ag_rings[i].ring_size = softc->scctx->isc_nrxd[2]; 501 softc->ag_rings[i].vaddr = vaddrs[i * nrxqs + 2]; 502 softc->ag_rings[i].paddr = paddrs[i * nrxqs + 2]; 503 504 /* Allocate the ring group */ 505 softc->grp_info[i].grp_id = (uint16_t)HWRM_NA_SIGNATURE; 506 softc->grp_info[i].stats_ctx = 507 softc->rx_cp_rings[i].stats_ctx_id; 508 softc->grp_info[i].rx_ring_id = softc->rx_rings[i].phys_id; 509 softc->grp_info[i].ag_ring_id = softc->ag_rings[i].phys_id; 510 softc->grp_info[i].cp_ring_id = 511 softc->rx_cp_rings[i].ring.phys_id; 512 513 bnxt_create_rx_sysctls(softc, i); 514 } 515 516 /* And finally, the VNIC */ 517 softc->vnic_info.id = (uint16_t)HWRM_NA_SIGNATURE; 518 softc->vnic_info.flow_id = (uint16_t)HWRM_NA_SIGNATURE; 519 softc->vnic_info.filter_id = -1; 520 softc->vnic_info.def_ring_grp = (uint16_t)HWRM_NA_SIGNATURE; 521 softc->vnic_info.cos_rule = (uint16_t)HWRM_NA_SIGNATURE; 522 softc->vnic_info.lb_rule = (uint16_t)HWRM_NA_SIGNATURE; 523 softc->vnic_info.rx_mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST; 524 softc->vnic_info.mc_list_count = 0; 525 softc->vnic_info.flags = BNXT_VNIC_FLAG_DEFAULT; 526 rc = iflib_dma_alloc(ctx, BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN, 527 &softc->vnic_info.mc_list, 0); 528 if (rc) 529 goto mc_list_alloc_fail; 530 531 /* The VNIC RSS Hash Key */ 532 rc = iflib_dma_alloc(ctx, HW_HASH_KEY_SIZE, 533 &softc->vnic_info.rss_hash_key_tbl, 0); 534 if (rc) 535 goto rss_hash_alloc_fail; 536 bus_dmamap_sync(softc->vnic_info.rss_hash_key_tbl.idi_tag, 537 softc->vnic_info.rss_hash_key_tbl.idi_map, 538 BUS_DMASYNC_PREWRITE); 539 memcpy(softc->vnic_info.rss_hash_key_tbl.idi_vaddr, 540 softc->vnic_info.rss_hash_key, HW_HASH_KEY_SIZE); 541 542 /* Allocate the RSS tables */ 543 rc = iflib_dma_alloc(ctx, HW_HASH_INDEX_SIZE * sizeof(uint16_t), 544 &softc->vnic_info.rss_grp_tbl, 0); 545 if (rc) 546 goto rss_grp_alloc_fail; 547 bus_dmamap_sync(softc->vnic_info.rss_grp_tbl.idi_tag, 548 softc->vnic_info.rss_grp_tbl.idi_map, 549 BUS_DMASYNC_PREWRITE); 550 memset(softc->vnic_info.rss_grp_tbl.idi_vaddr, 0xff, 551 softc->vnic_info.rss_grp_tbl.idi_size); 552 553 softc->nrxqsets = nrxqsets; 554 return rc; 555 556rss_grp_alloc_fail: 557 iflib_dma_free(&softc->vnic_info.rss_hash_key_tbl); 558rss_hash_alloc_fail: 559 iflib_dma_free(&softc->vnic_info.mc_list); 560mc_list_alloc_fail: 561 iflib_dma_free(&softc->rx_stats); 562hw_stats_alloc_fail: 563 free(softc->grp_info, M_DEVBUF); 564grp_alloc_fail: 565 free(softc->ag_rings, M_DEVBUF); 566ag_alloc_fail: 567 free(softc->rx_rings, M_DEVBUF); 568ring_alloc_fail: 569 free(softc->rx_cp_rings, M_DEVBUF); 570cp_alloc_fail: 571 return rc; 572} 573 574/* Device setup and teardown */ 575static int 576bnxt_attach_pre(if_ctx_t ctx) 577{ 578 struct bnxt_softc *softc = iflib_get_softc(ctx); 579 if_softc_ctx_t scctx; 580 int rc = 0; 581 582 softc->ctx = ctx; 583 softc->dev = iflib_get_dev(ctx); 584 softc->media = iflib_get_media(ctx); 585 softc->scctx = iflib_get_softc_ctx(ctx); 586 softc->sctx = iflib_get_sctx(ctx); 587 scctx = softc->scctx; 588 589 /* TODO: Better way of detecting NPAR/VF is needed */ 590 switch (softc->sctx->isc_vendor_info->pvi_device_id) { 591 case BCM57402_NPAR: 592 case BCM57404_NPAR: 593 case BCM57406_NPAR: 594 case BCM57407_NPAR: 595 case BCM57412_NPAR1: 596 case BCM57412_NPAR2: 597 case BCM57414_NPAR1: 598 case BCM57414_NPAR2: 599 case BCM57416_NPAR1: 600 case BCM57416_NPAR2: 601 softc->flags |= BNXT_FLAG_NPAR; 602 break; 603 case NETXTREME_C_VF1: 604 case NETXTREME_C_VF2: 605 case NETXTREME_C_VF3: 606 case NETXTREME_E_VF1: 607 case NETXTREME_E_VF2: 608 case NETXTREME_E_VF3: 609 softc->flags |= BNXT_FLAG_VF; 610 break; 611 } 612 613 pci_enable_busmaster(softc->dev); 614 615 if (bnxt_pci_mapping(softc)) 616 return (ENXIO); 617 618 /* HWRM setup/init */ 619 BNXT_HWRM_LOCK_INIT(softc, device_get_nameunit(softc->dev)); 620 rc = bnxt_alloc_hwrm_dma_mem(softc); 621 if (rc) 622 goto dma_fail; 623 624 /* Allocate the TPA start buffer */ 625 softc->tpa_start = malloc(sizeof(struct bnxt_full_tpa_start) * 626 (RX_TPA_START_CMPL_AGG_ID_MASK >> RX_TPA_START_CMPL_AGG_ID_SFT), 627 M_DEVBUF, M_NOWAIT | M_ZERO); 628 if (softc->tpa_start == NULL) { 629 rc = ENOMEM; 630 device_printf(softc->dev, 631 "Unable to allocate space for TPA\n"); 632 goto tpa_failed; 633 } 634 635 /* Get firmware version and compare with driver */ 636 softc->ver_info = malloc(sizeof(struct bnxt_ver_info), 637 M_DEVBUF, M_NOWAIT | M_ZERO); 638 if (softc->ver_info == NULL) { 639 rc = ENOMEM; 640 device_printf(softc->dev, 641 "Unable to allocate space for version info\n"); 642 goto ver_alloc_fail; 643 } 644 /* Default minimum required HWRM version */ 645 softc->ver_info->hwrm_min_major = 1; 646 softc->ver_info->hwrm_min_minor = 2; 647 softc->ver_info->hwrm_min_update = 2; 648 649 rc = bnxt_hwrm_ver_get(softc); 650 if (rc) { 651 device_printf(softc->dev, "attach: hwrm ver get failed\n"); 652 goto ver_fail; 653 } 654 655 /* Get NVRAM info */ 656 softc->nvm_info = malloc(sizeof(struct bnxt_nvram_info), 657 M_DEVBUF, M_NOWAIT | M_ZERO); 658 if (softc->nvm_info == NULL) { 659 rc = ENOMEM; 660 device_printf(softc->dev, 661 "Unable to allocate space for NVRAM info\n"); 662 goto nvm_alloc_fail; 663 } 664 rc = bnxt_hwrm_nvm_get_dev_info(softc, &softc->nvm_info->mfg_id, 665 &softc->nvm_info->device_id, &softc->nvm_info->sector_size, 666 &softc->nvm_info->size, &softc->nvm_info->reserved_size, 667 &softc->nvm_info->available_size); 668 669 /* Register the driver with the FW */ 670 rc = bnxt_hwrm_func_drv_rgtr(softc); 671 if (rc) { 672 device_printf(softc->dev, "attach: hwrm drv rgtr failed\n"); 673 goto drv_rgtr_fail; 674 } 675 676 /* Get the HW capabilities */ 677 rc = bnxt_hwrm_func_qcaps(softc); 678 if (rc) 679 goto failed; 680 iflib_set_mac(ctx, softc->func.mac_addr); 681 682 /* Get the queue config */ 683 rc = bnxt_hwrm_queue_qportcfg(softc); 684 if (rc) { 685 device_printf(softc->dev, "attach: hwrm qportcfg failed\n"); 686 goto failed; 687 } 688 689 /* Now perform a function reset */ 690 rc = bnxt_hwrm_func_reset(softc); 691 bnxt_clear_ids(softc); 692 if (rc) 693 goto failed; 694 695 /* Now set up iflib sc */ 696 scctx->isc_tx_nsegments = 31, 697 scctx->isc_tx_tso_segments_max = 31; 698 scctx->isc_tx_tso_size_max = BNXT_TSO_SIZE; 699 scctx->isc_tx_tso_segsize_max = BNXT_TSO_SIZE; 700 scctx->isc_vectors = softc->func.max_cp_rings; 701 if (scctx->isc_nrxd[0] < 702 ((scctx->isc_nrxd[1] * 4) + scctx->isc_nrxd[2])) 703 device_printf(softc->dev, 704 "WARNING: nrxd0 (%d) should be at least 4 * nrxd1 (%d) + nrxd2 (%d). Driver may be unstable\n", 705 scctx->isc_nrxd[0], scctx->isc_nrxd[1], scctx->isc_nrxd[2]); 706 if (scctx->isc_ntxd[0] < scctx->isc_ntxd[1] * 2) 707 device_printf(softc->dev, 708 "WARNING: ntxd0 (%d) should be at least 2 * ntxd1 (%d). Driver may be unstable\n", 709 scctx->isc_ntxd[0], scctx->isc_ntxd[1]); 710 scctx->isc_txqsizes[0] = sizeof(struct cmpl_base) * scctx->isc_ntxd[0]; 711 scctx->isc_txqsizes[1] = sizeof(struct tx_bd_short) * 712 scctx->isc_ntxd[1]; 713 scctx->isc_rxqsizes[0] = sizeof(struct cmpl_base) * scctx->isc_nrxd[0]; 714 scctx->isc_rxqsizes[1] = sizeof(struct rx_prod_pkt_bd) * 715 scctx->isc_nrxd[1]; 716 scctx->isc_rxqsizes[2] = sizeof(struct rx_prod_pkt_bd) * 717 scctx->isc_nrxd[2]; 718 scctx->isc_max_rxqsets = min(pci_msix_count(softc->dev)-1, 719 softc->func.max_cp_rings - 1); 720 scctx->isc_max_rxqsets = min(scctx->isc_max_rxqsets, 721 softc->func.max_rx_rings); 722 scctx->isc_max_txqsets = min(softc->func.max_rx_rings, 723 softc->func.max_cp_rings - scctx->isc_max_rxqsets - 1); 724 scctx->isc_rss_table_size = HW_HASH_INDEX_SIZE; 725 scctx->isc_rss_table_mask = scctx->isc_rss_table_size - 1; 726 727 /* iflib will map and release this bar */ 728 scctx->isc_msix_bar = pci_msix_table_bar(softc->dev); 729 730 /* Allocate the default completion ring */ 731 softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE; 732 softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE; 733 softc->def_cp_ring.ring.softc = softc; 734 softc->def_cp_ring.ring.id = 0; 735 softc->def_cp_ring.ring.doorbell = softc->def_cp_ring.ring.id * 0x80; 736 softc->def_cp_ring.ring.ring_size = PAGE_SIZE / 737 sizeof(struct cmpl_base); 738 rc = iflib_dma_alloc(ctx, 739 sizeof(struct cmpl_base) * softc->def_cp_ring.ring.ring_size, 740 &softc->def_cp_ring_mem, 0); 741 softc->def_cp_ring.ring.vaddr = softc->def_cp_ring_mem.idi_vaddr; 742 softc->def_cp_ring.ring.paddr = softc->def_cp_ring_mem.idi_paddr; 743 iflib_config_gtask_init(ctx, &softc->def_cp_task, bnxt_def_cp_task, 744 "dflt_cp"); 745 746 rc = bnxt_init_sysctl_ctx(softc); 747 if (rc) 748 goto init_sysctl_failed; 749 rc = bnxt_create_nvram_sysctls(softc->nvm_info); 750 if (rc) 751 goto failed; 752 753 arc4rand(softc->vnic_info.rss_hash_key, HW_HASH_KEY_SIZE, 0); 754 softc->vnic_info.rss_hash_type = 755 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 | 756 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4 | 757 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 | 758 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6 | 759 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6 | 760 HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; 761 rc = bnxt_create_config_sysctls_pre(softc); 762 if (rc) 763 goto failed; 764 765 /* Initialize the vlan list */ 766 SLIST_INIT(&softc->vnic_info.vlan_tags); 767 softc->vnic_info.vlan_tag_list.idi_vaddr = NULL; 768 769 return (rc); 770 771failed: 772 bnxt_free_sysctl_ctx(softc); 773init_sysctl_failed: 774 bnxt_hwrm_func_drv_unrgtr(softc, false); 775drv_rgtr_fail: 776 free(softc->nvm_info, M_DEVBUF); 777nvm_alloc_fail: 778ver_fail: 779 free(softc->ver_info, M_DEVBUF); 780ver_alloc_fail: 781 free(softc->tpa_start, M_DEVBUF); 782tpa_failed: 783 bnxt_free_hwrm_dma_mem(softc); 784dma_fail: 785 BNXT_HWRM_LOCK_DESTROY(softc); 786 bnxt_pci_mapping_free(softc); 787 pci_disable_busmaster(softc->dev); 788 return (rc); 789} 790 791static int 792bnxt_attach_post(if_ctx_t ctx) 793{ 794 struct bnxt_softc *softc = iflib_get_softc(ctx); 795 if_t ifp = iflib_get_ifp(ctx); 796 int capabilities, enabling; 797 int rc; 798 799 bnxt_create_config_sysctls_post(softc); 800 801 /* Update link state etc... */ 802 rc = bnxt_probe_phy(softc); 803 if (rc) 804 goto failed; 805 806 /* Needs to be done after probing the phy */ 807 bnxt_create_ver_sysctls(softc); 808 bnxt_add_media_types(softc); 809 ifmedia_set(softc->media, IFM_ETHER | IFM_AUTO); 810 811 if_sethwassist(ifp, (CSUM_TCP | CSUM_UDP | CSUM_TCP_IPV6 | 812 CSUM_UDP_IPV6 | CSUM_TSO)); 813 814 capabilities = 815 /* These are translated to hwassit bits */ 816 IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6 | IFCAP_TSO4 | IFCAP_TSO6 | 817 /* These are checked by iflib */ 818 IFCAP_LRO | IFCAP_VLAN_HWFILTER | 819 /* These are part of the iflib mask */ 820 IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_VLAN_MTU | 821 IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO | 822 /* These likely get lost... */ 823 IFCAP_VLAN_HWCSUM | IFCAP_JUMBO_MTU; 824 825 if_setcapabilities(ifp, capabilities); 826 827 enabling = capabilities; 828 829 if_setcapenable(ifp, enabling); 830 831 softc->scctx->isc_max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + 832 ETHER_CRC_LEN; 833 834failed: 835 return rc; 836} 837 838static int 839bnxt_detach(if_ctx_t ctx) 840{ 841 struct bnxt_softc *softc = iflib_get_softc(ctx); 842 struct bnxt_vlan_tag *tag; 843 struct bnxt_vlan_tag *tmp; 844 int i; 845 846 bnxt_do_disable_intr(&softc->def_cp_ring); 847 bnxt_free_sysctl_ctx(softc); 848 bnxt_hwrm_func_reset(softc); 849 bnxt_clear_ids(softc); 850 iflib_irq_free(ctx, &softc->def_cp_ring.irq); 851 iflib_config_gtask_deinit(&softc->def_cp_task); 852 /* We need to free() these here... */ 853 for (i = softc->nrxqsets-1; i>=0; i--) { 854 iflib_irq_free(ctx, &softc->rx_cp_rings[i].irq); 855 } 856 iflib_dma_free(&softc->vnic_info.mc_list); 857 iflib_dma_free(&softc->vnic_info.rss_hash_key_tbl); 858 iflib_dma_free(&softc->vnic_info.rss_grp_tbl); 859 if (softc->vnic_info.vlan_tag_list.idi_vaddr) 860 iflib_dma_free(&softc->vnic_info.vlan_tag_list); 861 SLIST_FOREACH_SAFE(tag, &softc->vnic_info.vlan_tags, next, tmp) 862 free(tag, M_DEVBUF); 863 iflib_dma_free(&softc->def_cp_ring_mem); 864 free(softc->tpa_start, M_DEVBUF); 865 free(softc->ver_info, M_DEVBUF); 866 free(softc->nvm_info, M_DEVBUF); 867 868 bnxt_hwrm_func_drv_unrgtr(softc, false); 869 bnxt_free_hwrm_dma_mem(softc); 870 BNXT_HWRM_LOCK_DESTROY(softc); 871 872 pci_disable_busmaster(softc->dev); 873 bnxt_pci_mapping_free(softc); 874 875 return 0; 876} 877 878/* Device configuration */ 879static void 880bnxt_init(if_ctx_t ctx) 881{ 882 struct bnxt_softc *softc = iflib_get_softc(ctx); 883 struct ifmediareq ifmr; 884 int i, j; 885 int rc; 886 887 rc = bnxt_hwrm_func_reset(softc); 888 if (rc) 889 return; 890 bnxt_clear_ids(softc); 891 892 /* Allocate the default completion ring */ 893 softc->def_cp_ring.cons = UINT32_MAX; 894 softc->def_cp_ring.v_bit = 1; 895 bnxt_mark_cpr_invalid(&softc->def_cp_ring); 896 rc = bnxt_hwrm_ring_alloc(softc, 897 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, 898 &softc->def_cp_ring.ring, 899 (uint16_t)HWRM_NA_SIGNATURE, 900 HWRM_NA_SIGNATURE, true); 901 if (rc) 902 goto fail; 903 904 /* And now set the default CP ring as the async CP ring */ 905 rc = bnxt_hwrm_func_cfg(softc); 906 if (rc) 907 goto fail; 908 909 for (i = 0; i < softc->nrxqsets; i++) { 910 /* Allocate the statistics context */ 911 rc = bnxt_hwrm_stat_ctx_alloc(softc, &softc->rx_cp_rings[i], 912 softc->rx_stats.idi_paddr + 913 (sizeof(struct ctx_hw_stats) * i)); 914 if (rc) 915 goto fail; 916 917 /* Allocate the completion ring */ 918 softc->rx_cp_rings[i].cons = UINT32_MAX; 919 softc->rx_cp_rings[i].v_bit = 1; 920 softc->rx_cp_rings[i].last_idx = UINT32_MAX; 921 bnxt_mark_cpr_invalid(&softc->rx_cp_rings[i]); 922 rc = bnxt_hwrm_ring_alloc(softc, 923 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, 924 &softc->rx_cp_rings[i].ring, (uint16_t)HWRM_NA_SIGNATURE, 925 HWRM_NA_SIGNATURE, true); 926 if (rc) 927 goto fail; 928 929 /* Allocate the RX ring */ 930 rc = bnxt_hwrm_ring_alloc(softc, 931 HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, 932 &softc->rx_rings[i], (uint16_t)HWRM_NA_SIGNATURE, 933 HWRM_NA_SIGNATURE, false); 934 if (rc) 935 goto fail; 936 BNXT_RX_DB(&softc->rx_rings[i], 0); 937 /* TODO: Cumulus+ doesn't need the double doorbell */ 938 BNXT_RX_DB(&softc->rx_rings[i], 0); 939 940 /* Allocate the AG ring */ 941 rc = bnxt_hwrm_ring_alloc(softc, 942 HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, 943 &softc->ag_rings[i], (uint16_t)HWRM_NA_SIGNATURE, 944 HWRM_NA_SIGNATURE, false); 945 if (rc) 946 goto fail; 947 BNXT_RX_DB(&softc->rx_rings[i], 0); 948 /* TODO: Cumulus+ doesn't need the double doorbell */ 949 BNXT_RX_DB(&softc->ag_rings[i], 0); 950 951 /* Allocate the ring group */ 952 softc->grp_info[i].stats_ctx = 953 softc->rx_cp_rings[i].stats_ctx_id; 954 softc->grp_info[i].rx_ring_id = softc->rx_rings[i].phys_id; 955 softc->grp_info[i].ag_ring_id = softc->ag_rings[i].phys_id; 956 softc->grp_info[i].cp_ring_id = 957 softc->rx_cp_rings[i].ring.phys_id; 958 rc = bnxt_hwrm_ring_grp_alloc(softc, &softc->grp_info[i]); 959 if (rc) 960 goto fail; 961 962 } 963 964 /* Allocate the VNIC RSS context */ 965 rc = bnxt_hwrm_vnic_ctx_alloc(softc, &softc->vnic_info.rss_id); 966 if (rc) 967 goto fail; 968 969 /* Allocate the vnic */ 970 softc->vnic_info.def_ring_grp = softc->grp_info[0].grp_id; 971 softc->vnic_info.mru = softc->scctx->isc_max_frame_size; 972 rc = bnxt_hwrm_vnic_alloc(softc, &softc->vnic_info); 973 if (rc) 974 goto fail; 975 rc = bnxt_hwrm_vnic_cfg(softc, &softc->vnic_info); 976 if (rc) 977 goto fail; 978 rc = bnxt_hwrm_set_filter(softc, &softc->vnic_info); 979 if (rc) 980 goto fail; 981 982 /* Enable RSS on the VNICs */ 983 for (i = 0, j = 0; i < HW_HASH_INDEX_SIZE; i++) { 984 ((uint16_t *) 985 softc->vnic_info.rss_grp_tbl.idi_vaddr)[i] = 986 htole16(softc->grp_info[j].grp_id); 987 if (++j == softc->nrxqsets) 988 j = 0; 989 } 990 991 rc = bnxt_hwrm_rss_cfg(softc, &softc->vnic_info, 992 softc->vnic_info.rss_hash_type); 993 if (rc) 994 goto fail; 995 996#ifdef notyet 997 /* Enable LRO/TPA/GRO */ 998 rc = bnxt_hwrm_vnic_tpa_cfg(softc, &softc->vnic_info, 999 (if_getcapenable(iflib_get_ifp(ctx)) & IFCAP_LRO) ? 1000 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA : 0); 1001 if (rc) 1002 goto fail; 1003#endif 1004 1005 for (i = 0; i < softc->ntxqsets; i++) { 1006 /* Allocate the statistics context */ 1007 rc = bnxt_hwrm_stat_ctx_alloc(softc, &softc->tx_cp_rings[i], 1008 softc->tx_stats.idi_paddr + 1009 (sizeof(struct ctx_hw_stats) * i)); 1010 if (rc) 1011 goto fail; 1012 1013 /* Allocate the completion ring */ 1014 softc->tx_cp_rings[i].cons = UINT32_MAX; 1015 softc->tx_cp_rings[i].v_bit = 1; 1016 bnxt_mark_cpr_invalid(&softc->tx_cp_rings[i]); 1017 rc = bnxt_hwrm_ring_alloc(softc, 1018 HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, 1019 &softc->tx_cp_rings[i].ring, (uint16_t)HWRM_NA_SIGNATURE, 1020 HWRM_NA_SIGNATURE, false); 1021 if (rc) 1022 goto fail; 1023 1024 /* Allocate the TX ring */ 1025 rc = bnxt_hwrm_ring_alloc(softc, 1026 HWRM_RING_ALLOC_INPUT_RING_TYPE_TX, 1027 &softc->tx_rings[i], softc->tx_cp_rings[i].ring.phys_id, 1028 softc->tx_cp_rings[i].stats_ctx_id, false); 1029 if (rc) 1030 goto fail; 1031 BNXT_TX_DB(&softc->tx_rings[i], 0); 1032 /* TODO: Cumulus+ doesn't need the double doorbell */ 1033 BNXT_TX_DB(&softc->tx_rings[i], 0); 1034 } 1035 1036 bnxt_do_enable_intr(&softc->def_cp_ring); 1037 bnxt_media_status(softc->ctx, &ifmr); 1038 return; 1039 1040fail: 1041 bnxt_hwrm_func_reset(softc); 1042 bnxt_clear_ids(softc); 1043 return; 1044} 1045 1046static void 1047bnxt_stop(if_ctx_t ctx) 1048{ 1049 struct bnxt_softc *softc = iflib_get_softc(ctx); 1050 1051 bnxt_do_disable_intr(&softc->def_cp_ring); 1052 bnxt_hwrm_func_reset(softc); 1053 bnxt_clear_ids(softc); 1054 return; 1055} 1056 1057static void 1058bnxt_multi_set(if_ctx_t ctx) 1059{ 1060 struct bnxt_softc *softc = iflib_get_softc(ctx); 1061 if_t ifp = iflib_get_ifp(ctx); 1062 uint8_t *mta; 1063 int cnt, mcnt; 1064 1065 mcnt = if_multiaddr_count(ifp, -1); 1066 1067 if (mcnt > BNXT_MAX_MC_ADDRS) { 1068 softc->vnic_info.rx_mask |= 1069 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; 1070 bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info); 1071 } 1072 else { 1073 softc->vnic_info.rx_mask &= 1074 ~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; 1075 mta = softc->vnic_info.mc_list.idi_vaddr; 1076 bzero(mta, softc->vnic_info.mc_list.idi_size); 1077 if_multiaddr_array(ifp, mta, &cnt, mcnt); 1078 bus_dmamap_sync(softc->vnic_info.mc_list.idi_tag, 1079 softc->vnic_info.mc_list.idi_map, BUS_DMASYNC_PREWRITE); 1080 softc->vnic_info.mc_list_count = cnt; 1081 softc->vnic_info.rx_mask |= 1082 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST; 1083 if (bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info)) 1084 device_printf(softc->dev, 1085 "set_multi: rx_mask set failed\n"); 1086 } 1087} 1088 1089static int 1090bnxt_mtu_set(if_ctx_t ctx, uint32_t mtu) 1091{ 1092 struct bnxt_softc *softc = iflib_get_softc(ctx); 1093 1094 if (mtu > BNXT_MAX_MTU) 1095 return EINVAL; 1096 1097 softc->scctx->isc_max_frame_size = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; 1098 return 0; 1099} 1100 1101static void 1102bnxt_media_status(if_ctx_t ctx, struct ifmediareq * ifmr) 1103{ 1104 struct bnxt_softc *softc = iflib_get_softc(ctx); 1105 struct bnxt_link_info *link_info = &softc->link_info; 1106 uint8_t phy_type = get_phy_type(softc); 1107 1108 bnxt_update_link(softc, true); 1109 1110 ifmr->ifm_status = IFM_AVALID; 1111 ifmr->ifm_active = IFM_ETHER; 1112 1113 if (link_info->link_up) 1114 ifmr->ifm_status |= IFM_ACTIVE; 1115 else 1116 ifmr->ifm_status &= ~IFM_ACTIVE; 1117 1118 if (link_info->duplex == HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL) 1119 ifmr->ifm_active |= IFM_FDX; 1120 else 1121 ifmr->ifm_active |= IFM_HDX; 1122 1123 switch (link_info->link_speed) { 1124 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB: 1125 ifmr->ifm_active |= IFM_100_T; 1126 break; 1127 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB: 1128 switch (phy_type) { 1129 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: 1130 ifmr->ifm_active |= IFM_1000_KX; 1131 break; 1132 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: 1133 ifmr->ifm_active |= IFM_1000_T; 1134 break; 1135 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY: 1136 ifmr->ifm_active |= IFM_1000_SGMII; 1137 break; 1138 default: 1139 ifmr->ifm_active |= IFM_UNKNOWN; 1140 break; 1141 } 1142 break; 1143 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB: 1144 switch (phy_type) { 1145 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: 1146 ifmr->ifm_active |= IFM_2500_KX; 1147 break; 1148 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: 1149 ifmr->ifm_active |= IFM_2500_T; 1150 break; 1151 default: 1152 ifmr->ifm_active |= IFM_UNKNOWN; 1153 break; 1154 } 1155 break; 1156 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB: 1157 switch (phy_type) { 1158 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1159 ifmr->ifm_active |= IFM_10G_CR1; 1160 break; 1161 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1162 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1163 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1164 ifmr->ifm_active |= IFM_10G_KR; 1165 break; 1166 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: 1167 ifmr->ifm_active |= IFM_10G_LR; 1168 break; 1169 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: 1170 ifmr->ifm_active |= IFM_10G_SR; 1171 break; 1172 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: 1173 ifmr->ifm_active |= IFM_10G_KX4; 1174 break; 1175 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: 1176 ifmr->ifm_active |= IFM_10G_T; 1177 break; 1178 default: 1179 ifmr->ifm_active |= IFM_UNKNOWN; 1180 break; 1181 } 1182 break; 1183 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB: 1184 ifmr->ifm_active |= IFM_20G_KR2; 1185 break; 1186 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB: 1187 switch (phy_type) { 1188 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1189 ifmr->ifm_active |= IFM_25G_CR; 1190 break; 1191 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1192 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1193 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1194 ifmr->ifm_active |= IFM_25G_KR; 1195 break; 1196 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: 1197 ifmr->ifm_active |= IFM_25G_SR; 1198 break; 1199 default: 1200 ifmr->ifm_active |= IFM_UNKNOWN; 1201 break; 1202 } 1203 break; 1204 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB: 1205 switch (phy_type) { 1206 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1207 ifmr->ifm_active |= IFM_40G_CR4; 1208 break; 1209 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1210 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1211 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1212 ifmr->ifm_active |= IFM_40G_KR4; 1213 break; 1214 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: 1215 ifmr->ifm_active |= IFM_40G_LR4; 1216 break; 1217 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: 1218 ifmr->ifm_active |= IFM_40G_SR4; 1219 break; 1220 default: 1221 ifmr->ifm_active |= IFM_UNKNOWN; 1222 break; 1223 } 1224 break; 1225 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB: 1226 switch (phy_type) { 1227 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1228 ifmr->ifm_active |= IFM_50G_CR2; 1229 break; 1230 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1231 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1232 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1233 ifmr->ifm_active |= IFM_50G_KR2; 1234 break; 1235 default: 1236 ifmr->ifm_active |= IFM_UNKNOWN; 1237 break; 1238 } 1239 break; 1240 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB: 1241 switch (phy_type) { 1242 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1243 ifmr->ifm_active |= IFM_100G_CR4; 1244 break; 1245 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1246 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1247 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1248 ifmr->ifm_active |= IFM_100G_KR4; 1249 break; 1250 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: 1251 ifmr->ifm_active |= IFM_100G_LR4; 1252 break; 1253 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: 1254 ifmr->ifm_active |= IFM_100G_SR4; 1255 break; 1256 default: 1257 ifmr->ifm_active |= IFM_UNKNOWN; 1258 break; 1259 } 1260 default: 1261 return; 1262 } 1263 1264 if (link_info->pause == (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1265 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) 1266 ifmr->ifm_active |= (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE); 1267 else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) 1268 ifmr->ifm_active |= IFM_ETH_TXPAUSE; 1269 else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) 1270 ifmr->ifm_active |= IFM_ETH_RXPAUSE; 1271 1272 bnxt_report_link(softc); 1273 return; 1274} 1275 1276static int 1277bnxt_media_change(if_ctx_t ctx) 1278{ 1279 struct bnxt_softc *softc = iflib_get_softc(ctx); 1280 struct ifmedia *ifm = iflib_get_media(ctx); 1281 struct ifmediareq ifmr; 1282 int rc; 1283 1284 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 1285 return EINVAL; 1286 1287 switch (IFM_SUBTYPE(ifm->ifm_media)) { 1288 case IFM_100_T: 1289 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1290 softc->link_info.req_link_speed = 1291 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB; 1292 break; 1293 case IFM_1000_KX: 1294 case IFM_1000_T: 1295 case IFM_1000_SGMII: 1296 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1297 softc->link_info.req_link_speed = 1298 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB; 1299 break; 1300 case IFM_2500_KX: 1301 case IFM_2500_T: 1302 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1303 softc->link_info.req_link_speed = 1304 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB; 1305 break; 1306 case IFM_10G_CR1: 1307 case IFM_10G_KR: 1308 case IFM_10G_LR: 1309 case IFM_10G_SR: 1310 case IFM_10G_T: 1311 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1312 softc->link_info.req_link_speed = 1313 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB; 1314 break; 1315 case IFM_20G_KR2: 1316 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1317 softc->link_info.req_link_speed = 1318 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB; 1319 break; 1320 case IFM_25G_CR: 1321 case IFM_25G_KR: 1322 case IFM_25G_SR: 1323 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1324 softc->link_info.req_link_speed = 1325 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB; 1326 break; 1327 case IFM_40G_CR4: 1328 case IFM_40G_KR4: 1329 case IFM_40G_LR4: 1330 case IFM_40G_SR4: 1331 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1332 softc->link_info.req_link_speed = 1333 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB; 1334 break; 1335 case IFM_50G_CR2: 1336 case IFM_50G_KR2: 1337 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1338 softc->link_info.req_link_speed = 1339 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB; 1340 break; 1341 case IFM_100G_CR4: 1342 case IFM_100G_KR4: 1343 case IFM_100G_LR4: 1344 case IFM_100G_SR4: 1345 softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED; 1346 softc->link_info.req_link_speed = 1347 HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB; 1348 break; 1349 default: 1350 device_printf(softc->dev, 1351 "Unsupported media type! Using auto\n"); 1352 /* Fall-through */ 1353 case IFM_AUTO: 1354 // Auto 1355 softc->link_info.autoneg |= BNXT_AUTONEG_SPEED; 1356 break; 1357 } 1358 rc = bnxt_hwrm_set_link_setting(softc, true, true); 1359 bnxt_media_status(softc->ctx, &ifmr); 1360 return rc; 1361} 1362 1363static int 1364bnxt_promisc_set(if_ctx_t ctx, int flags) 1365{ 1366 struct bnxt_softc *softc = iflib_get_softc(ctx); 1367 if_t ifp = iflib_get_ifp(ctx); 1368 int rc; 1369 1370 if (ifp->if_flags & IFF_ALLMULTI || 1371 if_multiaddr_count(ifp, -1) > BNXT_MAX_MC_ADDRS) 1372 softc->vnic_info.rx_mask |= 1373 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; 1374 else 1375 softc->vnic_info.rx_mask &= 1376 ~HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST; 1377 1378 if (ifp->if_flags & IFF_PROMISC) 1379 softc->vnic_info.rx_mask |= 1380 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS | 1381 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN; 1382 else 1383 softc->vnic_info.rx_mask &= 1384 ~(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS | 1385 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN); 1386 1387 rc = bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info); 1388 1389 return rc; 1390} 1391 1392static uint64_t 1393bnxt_get_counter(if_ctx_t ctx, ift_counter cnt) 1394{ 1395 if_t ifp = iflib_get_ifp(ctx); 1396 1397 if (cnt < IFCOUNTERS) 1398 return if_get_counter_default(ifp, cnt); 1399 1400 return 0; 1401} 1402 1403static void 1404bnxt_update_admin_status(if_ctx_t ctx) 1405{ 1406 /* TODO: do we need to do anything here? */ 1407 return; 1408} 1409 1410static void inline 1411bnxt_do_enable_intr(struct bnxt_cp_ring *cpr) 1412{ 1413 if (cpr->ring.phys_id != (uint16_t)HWRM_NA_SIGNATURE) { 1414 /* First time enabling, do not set index */ 1415 if (cpr->cons == UINT32_MAX) 1416 BNXT_CP_ENABLE_DB(&cpr->ring); 1417 else 1418 BNXT_CP_IDX_ENABLE_DB(&cpr->ring, cpr->cons); 1419 } 1420} 1421 1422static void inline 1423bnxt_do_disable_intr(struct bnxt_cp_ring *cpr) 1424{ 1425 if (cpr->ring.phys_id != (uint16_t)HWRM_NA_SIGNATURE) 1426 BNXT_CP_DISABLE_DB(&cpr->ring); 1427} 1428 1429/* Enable all interrupts */ 1430static void 1431bnxt_intr_enable(if_ctx_t ctx) 1432{ 1433 struct bnxt_softc *softc = iflib_get_softc(ctx); 1434 int i; 1435 1436 bnxt_do_enable_intr(&softc->def_cp_ring); 1437 for (i = 0; i < softc->nrxqsets; i++) 1438 bnxt_do_enable_intr(&softc->rx_cp_rings[i]); 1439 1440 return; 1441} 1442 1443/* Enable interrupt for a single queue */ 1444static int 1445bnxt_queue_intr_enable(if_ctx_t ctx, uint16_t qid) 1446{ 1447 struct bnxt_softc *softc = iflib_get_softc(ctx); 1448 1449 bnxt_do_enable_intr(&softc->rx_cp_rings[qid]); 1450 return 0; 1451} 1452 1453/* Disable all interrupts */ 1454static void 1455bnxt_disable_intr(if_ctx_t ctx) 1456{ 1457 struct bnxt_softc *softc = iflib_get_softc(ctx); 1458 int i; 1459 1460 /* 1461 * NOTE: These TX interrupts should never get enabled, so don't 1462 * update the index 1463 */ 1464 for (i = 0; i < softc->ntxqsets; i++) 1465 bnxt_do_disable_intr(&softc->tx_cp_rings[i]); 1466 for (i = 0; i < softc->nrxqsets; i++) 1467 bnxt_do_disable_intr(&softc->rx_cp_rings[i]); 1468 1469 return; 1470} 1471 1472static int 1473bnxt_msix_intr_assign(if_ctx_t ctx, int msix) 1474{ 1475 struct bnxt_softc *softc = iflib_get_softc(ctx); 1476 int rc; 1477 int i; 1478 1479 rc = iflib_irq_alloc_generic(ctx, &softc->def_cp_ring.irq, 1480 softc->def_cp_ring.ring.id + 1, IFLIB_INTR_ADMIN, 1481 bnxt_handle_def_cp, softc, 0, "def_cp"); 1482 if (rc) { 1483 device_printf(iflib_get_dev(ctx), 1484 "Failed to register default completion ring handler\n"); 1485 return rc; 1486 } 1487 1488 for (i=0; i<softc->scctx->isc_nrxqsets; i++) { 1489 rc = iflib_irq_alloc_generic(ctx, &softc->rx_cp_rings[i].irq, 1490 softc->rx_cp_rings[i].ring.id + 1, IFLIB_INTR_RX, 1491 bnxt_handle_rx_cp, &softc->rx_cp_rings[i], i, "rx_cp"); 1492 if (rc) { 1493 device_printf(iflib_get_dev(ctx), 1494 "Failed to register RX completion ring handler\n"); 1495 i--; 1496 goto fail; 1497 } 1498 } 1499 1500 for (i=0; i<softc->scctx->isc_ntxqsets; i++) 1501 iflib_softirq_alloc_generic(ctx, i + 1, IFLIB_INTR_TX, NULL, i, 1502 "tx_cp"); 1503 1504 return rc; 1505 1506fail: 1507 for (; i>=0; i--) 1508 iflib_irq_free(ctx, &softc->rx_cp_rings[i].irq); 1509 iflib_irq_free(ctx, &softc->def_cp_ring.irq); 1510 return rc; 1511} 1512 1513/* 1514 * We're explicitly allowing duplicates here. They will need to be 1515 * removed as many times as they are added. 1516 */ 1517static void 1518bnxt_vlan_register(if_ctx_t ctx, uint16_t vtag) 1519{ 1520 struct bnxt_softc *softc = iflib_get_softc(ctx); 1521 struct bnxt_vlan_tag *new_tag; 1522 1523 new_tag = malloc(sizeof(struct bnxt_vlan_tag), M_DEVBUF, M_NOWAIT); 1524 if (new_tag == NULL) 1525 return; 1526 new_tag->tag = vtag; 1527 new_tag->tpid = 8100; 1528 SLIST_INSERT_HEAD(&softc->vnic_info.vlan_tags, new_tag, next); 1529}; 1530 1531static void 1532bnxt_vlan_unregister(if_ctx_t ctx, uint16_t vtag) 1533{ 1534 struct bnxt_softc *softc = iflib_get_softc(ctx); 1535 struct bnxt_vlan_tag *vlan_tag; 1536 1537 SLIST_FOREACH(vlan_tag, &softc->vnic_info.vlan_tags, next) { 1538 if (vlan_tag->tag == vtag) { 1539 SLIST_REMOVE(&softc->vnic_info.vlan_tags, vlan_tag, 1540 bnxt_vlan_tag, next); 1541 free(vlan_tag, M_DEVBUF); 1542 break; 1543 } 1544 } 1545} 1546 1547static int 1548bnxt_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data) 1549{ 1550 struct bnxt_softc *softc = iflib_get_softc(ctx); 1551 struct ifreq *ifr = (struct ifreq *)data; 1552 struct ifreq_buffer *ifbuf = &ifr->ifr_ifru.ifru_buffer; 1553 struct bnxt_ioctl_header *ioh = 1554 (struct bnxt_ioctl_header *)(ifbuf->buffer); 1555 int rc = ENOTSUP; 1556 struct bnxt_ioctl_data *iod = NULL; 1557 1558 switch (command) { 1559 case SIOCGPRIVATE_0: 1560 if ((rc = priv_check(curthread, PRIV_DRIVER)) != 0) 1561 goto exit; 1562 1563 iod = malloc(ifbuf->length, M_DEVBUF, M_NOWAIT | M_ZERO); 1564 if (!iod) { 1565 rc = ENOMEM; 1566 goto exit; 1567 } 1568 copyin(ioh, iod, ifbuf->length); 1569 1570 switch (ioh->type) { 1571 case BNXT_HWRM_NVM_FIND_DIR_ENTRY: 1572 { 1573 struct bnxt_ioctl_hwrm_nvm_find_dir_entry *find = 1574 &iod->find; 1575 1576 rc = bnxt_hwrm_nvm_find_dir_entry(softc, find->type, 1577 &find->ordinal, find->ext, &find->index, 1578 find->use_index, find->search_opt, 1579 &find->data_length, &find->item_length, 1580 &find->fw_ver); 1581 if (rc) { 1582 iod->hdr.rc = rc; 1583 copyout(&iod->hdr.rc, &ioh->rc, 1584 sizeof(ioh->rc)); 1585 } 1586 else { 1587 iod->hdr.rc = 0; 1588 copyout(iod, ioh, ifbuf->length); 1589 } 1590 1591 rc = 0; 1592 goto exit; 1593 } 1594 case BNXT_HWRM_NVM_READ: 1595 { 1596 struct bnxt_ioctl_hwrm_nvm_read *rd = &iod->read; 1597 struct iflib_dma_info dma_data; 1598 size_t offset; 1599 size_t remain; 1600 size_t csize; 1601 1602 /* 1603 * Some HWRM versions can't read more than 0x8000 bytes 1604 */ 1605 rc = iflib_dma_alloc(softc->ctx, 1606 min(rd->length, 0x8000), &dma_data, BUS_DMA_NOWAIT); 1607 if (rc) 1608 break; 1609 for (remain = rd->length, offset = 0; 1610 remain && offset < rd->length; offset += 0x8000) { 1611 csize = min(remain, 0x8000); 1612 rc = bnxt_hwrm_nvm_read(softc, rd->index, 1613 rd->offset + offset, csize, &dma_data); 1614 if (rc) { 1615 iod->hdr.rc = rc; 1616 copyout(&iod->hdr.rc, &ioh->rc, 1617 sizeof(ioh->rc)); 1618 break; 1619 } 1620 else { 1621 copyout(dma_data.idi_vaddr, 1622 rd->data + offset, csize); 1623 iod->hdr.rc = 0; 1624 } 1625 remain -= csize; 1626 } 1627 if (iod->hdr.rc == 0) 1628 copyout(iod, ioh, ifbuf->length); 1629 1630 iflib_dma_free(&dma_data); 1631 rc = 0; 1632 goto exit; 1633 } 1634 case BNXT_HWRM_FW_RESET: 1635 { 1636 struct bnxt_ioctl_hwrm_fw_reset *rst = 1637 &iod->reset; 1638 1639 rc = bnxt_hwrm_fw_reset(softc, rst->processor, 1640 &rst->selfreset); 1641 if (rc) { 1642 iod->hdr.rc = rc; 1643 copyout(&iod->hdr.rc, &ioh->rc, 1644 sizeof(ioh->rc)); 1645 } 1646 else { 1647 iod->hdr.rc = 0; 1648 copyout(iod, ioh, ifbuf->length); 1649 } 1650 1651 rc = 0; 1652 goto exit; 1653 } 1654 case BNXT_HWRM_FW_QSTATUS: 1655 { 1656 struct bnxt_ioctl_hwrm_fw_qstatus *qstat = 1657 &iod->status; 1658 1659 rc = bnxt_hwrm_fw_qstatus(softc, qstat->processor, 1660 &qstat->selfreset); 1661 if (rc) { 1662 iod->hdr.rc = rc; 1663 copyout(&iod->hdr.rc, &ioh->rc, 1664 sizeof(ioh->rc)); 1665 } 1666 else { 1667 iod->hdr.rc = 0; 1668 copyout(iod, ioh, ifbuf->length); 1669 } 1670 1671 rc = 0; 1672 goto exit; 1673 } 1674 case BNXT_HWRM_NVM_WRITE: 1675 { 1676 struct bnxt_ioctl_hwrm_nvm_write *wr = 1677 &iod->write; 1678 1679 rc = bnxt_hwrm_nvm_write(softc, wr->data, true, 1680 wr->type, wr->ordinal, wr->ext, wr->attr, 1681 wr->option, wr->data_length, wr->keep, 1682 &wr->item_length, &wr->index); 1683 if (rc) { 1684 iod->hdr.rc = rc; 1685 copyout(&iod->hdr.rc, &ioh->rc, 1686 sizeof(ioh->rc)); 1687 } 1688 else { 1689 iod->hdr.rc = 0; 1690 copyout(iod, ioh, ifbuf->length); 1691 } 1692 1693 rc = 0; 1694 goto exit; 1695 } 1696 case BNXT_HWRM_NVM_ERASE_DIR_ENTRY: 1697 { 1698 struct bnxt_ioctl_hwrm_nvm_erase_dir_entry *erase = 1699 &iod->erase; 1700 1701 rc = bnxt_hwrm_nvm_erase_dir_entry(softc, erase->index); 1702 if (rc) { 1703 iod->hdr.rc = rc; 1704 copyout(&iod->hdr.rc, &ioh->rc, 1705 sizeof(ioh->rc)); 1706 } 1707 else { 1708 iod->hdr.rc = 0; 1709 copyout(iod, ioh, ifbuf->length); 1710 } 1711 1712 rc = 0; 1713 goto exit; 1714 } 1715 case BNXT_HWRM_NVM_GET_DIR_INFO: 1716 { 1717 struct bnxt_ioctl_hwrm_nvm_get_dir_info *info = 1718 &iod->dir_info; 1719 1720 rc = bnxt_hwrm_nvm_get_dir_info(softc, &info->entries, 1721 &info->entry_length); 1722 if (rc) { 1723 iod->hdr.rc = rc; 1724 copyout(&iod->hdr.rc, &ioh->rc, 1725 sizeof(ioh->rc)); 1726 } 1727 else { 1728 iod->hdr.rc = 0; 1729 copyout(iod, ioh, ifbuf->length); 1730 } 1731 1732 rc = 0; 1733 goto exit; 1734 } 1735 case BNXT_HWRM_NVM_GET_DIR_ENTRIES: 1736 { 1737 struct bnxt_ioctl_hwrm_nvm_get_dir_entries *get = 1738 &iod->dir_entries; 1739 struct iflib_dma_info dma_data; 1740 1741 rc = iflib_dma_alloc(softc->ctx, get->max_size, 1742 &dma_data, BUS_DMA_NOWAIT); 1743 if (rc) 1744 break; 1745 rc = bnxt_hwrm_nvm_get_dir_entries(softc, &get->entries, 1746 &get->entry_length, &dma_data); 1747 if (rc) { 1748 iod->hdr.rc = rc; 1749 copyout(&iod->hdr.rc, &ioh->rc, 1750 sizeof(ioh->rc)); 1751 } 1752 else { 1753 copyout(dma_data.idi_vaddr, get->data, 1754 get->entry_length * get->entries); 1755 iod->hdr.rc = 0; 1756 copyout(iod, ioh, ifbuf->length); 1757 } 1758 iflib_dma_free(&dma_data); 1759 1760 rc = 0; 1761 goto exit; 1762 } 1763 case BNXT_HWRM_NVM_VERIFY_UPDATE: 1764 { 1765 struct bnxt_ioctl_hwrm_nvm_verify_update *vrfy = 1766 &iod->verify; 1767 1768 rc = bnxt_hwrm_nvm_verify_update(softc, vrfy->type, 1769 vrfy->ordinal, vrfy->ext); 1770 if (rc) { 1771 iod->hdr.rc = rc; 1772 copyout(&iod->hdr.rc, &ioh->rc, 1773 sizeof(ioh->rc)); 1774 } 1775 else { 1776 iod->hdr.rc = 0; 1777 copyout(iod, ioh, ifbuf->length); 1778 } 1779 1780 rc = 0; 1781 goto exit; 1782 } 1783 case BNXT_HWRM_NVM_INSTALL_UPDATE: 1784 { 1785 struct bnxt_ioctl_hwrm_nvm_install_update *inst = 1786 &iod->install; 1787 1788 rc = bnxt_hwrm_nvm_install_update(softc, 1789 inst->install_type, &inst->installed_items, 1790 &inst->result, &inst->problem_item, 1791 &inst->reset_required); 1792 if (rc) { 1793 iod->hdr.rc = rc; 1794 copyout(&iod->hdr.rc, &ioh->rc, 1795 sizeof(ioh->rc)); 1796 } 1797 else { 1798 iod->hdr.rc = 0; 1799 copyout(iod, ioh, ifbuf->length); 1800 } 1801 1802 rc = 0; 1803 goto exit; 1804 } 1805 case BNXT_HWRM_NVM_MODIFY: 1806 { 1807 struct bnxt_ioctl_hwrm_nvm_modify *mod = &iod->modify; 1808 1809 rc = bnxt_hwrm_nvm_modify(softc, mod->index, 1810 mod->offset, mod->data, true, mod->length); 1811 if (rc) { 1812 iod->hdr.rc = rc; 1813 copyout(&iod->hdr.rc, &ioh->rc, 1814 sizeof(ioh->rc)); 1815 } 1816 else { 1817 iod->hdr.rc = 0; 1818 copyout(iod, ioh, ifbuf->length); 1819 } 1820 1821 rc = 0; 1822 goto exit; 1823 } 1824 case BNXT_HWRM_FW_GET_TIME: 1825 { 1826 struct bnxt_ioctl_hwrm_fw_get_time *gtm = 1827 &iod->get_time; 1828 1829 rc = bnxt_hwrm_fw_get_time(softc, >m->year, 1830 >m->month, >m->day, >m->hour, >m->minute, 1831 >m->second, >m->millisecond, >m->zone); 1832 if (rc) { 1833 iod->hdr.rc = rc; 1834 copyout(&iod->hdr.rc, &ioh->rc, 1835 sizeof(ioh->rc)); 1836 } 1837 else { 1838 iod->hdr.rc = 0; 1839 copyout(iod, ioh, ifbuf->length); 1840 } 1841 1842 rc = 0; 1843 goto exit; 1844 } 1845 case BNXT_HWRM_FW_SET_TIME: 1846 { 1847 struct bnxt_ioctl_hwrm_fw_set_time *stm = 1848 &iod->set_time; 1849 1850 rc = bnxt_hwrm_fw_set_time(softc, stm->year, 1851 stm->month, stm->day, stm->hour, stm->minute, 1852 stm->second, stm->millisecond, stm->zone); 1853 if (rc) { 1854 iod->hdr.rc = rc; 1855 copyout(&iod->hdr.rc, &ioh->rc, 1856 sizeof(ioh->rc)); 1857 } 1858 else { 1859 iod->hdr.rc = 0; 1860 copyout(iod, ioh, ifbuf->length); 1861 } 1862 1863 rc = 0; 1864 goto exit; 1865 } 1866 } 1867 break; 1868 } 1869 1870exit: 1871 if (iod) 1872 free(iod, M_DEVBUF); 1873 return rc; 1874} 1875 1876/* 1877 * Support functions 1878 */ 1879static int 1880bnxt_probe_phy(struct bnxt_softc *softc) 1881{ 1882 struct bnxt_link_info *link_info = &softc->link_info; 1883 int rc = 0; 1884 1885 rc = bnxt_update_link(softc, false); 1886 if (rc) { 1887 device_printf(softc->dev, 1888 "Probe phy can't update link (rc: %x)\n", rc); 1889 return (rc); 1890 } 1891 1892 /*initialize the ethool setting copy with NVM settings */ 1893 if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE) 1894 link_info->autoneg |= BNXT_AUTONEG_SPEED; 1895 1896 if (link_info->auto_pause & (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1897 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) { 1898 if (link_info->auto_pause == ( 1899 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1900 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) 1901 link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; 1902 link_info->req_flow_ctrl = link_info->auto_pause; 1903 } else if (link_info->force_pause & ( 1904 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 1905 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) { 1906 link_info->req_flow_ctrl = link_info->force_pause; 1907 } 1908 link_info->req_duplex = link_info->duplex_setting; 1909 if (link_info->autoneg & BNXT_AUTONEG_SPEED) 1910 link_info->req_link_speed = link_info->auto_link_speed; 1911 else 1912 link_info->req_link_speed = link_info->force_link_speed; 1913 return (rc); 1914} 1915 1916static void 1917bnxt_add_media_types(struct bnxt_softc *softc) 1918{ 1919 struct bnxt_link_info *link_info = &softc->link_info; 1920 uint16_t supported; 1921 uint8_t phy_type = get_phy_type(softc); 1922 1923 supported = link_info->support_speeds; 1924 1925 /* Auto is always supported */ 1926 ifmedia_add(softc->media, IFM_ETHER | IFM_AUTO, 0, NULL); 1927 1928 if (softc->flags & BNXT_FLAG_NPAR) 1929 return; 1930 1931 switch (phy_type) { 1932 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR: 1933 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 1934 ifmedia_add(softc->media, IFM_ETHER | IFM_100G_CR4, 0, 1935 NULL); 1936 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) 1937 ifmedia_add(softc->media, IFM_ETHER | IFM_50G_CR2, 0, 1938 NULL); 1939 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 1940 ifmedia_add(softc->media, IFM_ETHER | IFM_40G_CR4, 0, 1941 NULL); 1942 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) 1943 ifmedia_add(softc->media, IFM_ETHER | IFM_25G_CR, 0, 1944 NULL); 1945 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 1946 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_CR1, 0, 1947 NULL); 1948 break; 1949 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN: 1950 /* Auto only */ 1951 break; 1952 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4: 1953 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2: 1954 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR: 1955 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 1956 ifmedia_add(softc->media, IFM_ETHER | IFM_100G_KR4, 0, 1957 NULL); 1958 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) 1959 ifmedia_add(softc->media, IFM_ETHER | IFM_50G_KR2, 0, 1960 NULL); 1961 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 1962 ifmedia_add(softc->media, IFM_ETHER | IFM_40G_KR4, 0, 1963 NULL); 1964 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) 1965 ifmedia_add(softc->media, IFM_ETHER | IFM_25G_KR, 0, 1966 NULL); 1967 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB) 1968 ifmedia_add(softc->media, IFM_ETHER | IFM_20G_KR2, 0, 1969 NULL); 1970 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 1971 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_KR, 0, 1972 NULL); 1973 break; 1974 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR: 1975 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 1976 ifmedia_add(softc->media, IFM_ETHER | IFM_100G_LR4, 0, 1977 NULL); 1978 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 1979 ifmedia_add(softc->media, IFM_ETHER | IFM_40G_LR4, 0, 1980 NULL); 1981 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 1982 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_LR, 0, 1983 NULL); 1984 break; 1985 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR: 1986 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) 1987 ifmedia_add(softc->media, IFM_ETHER | IFM_100G_SR4, 0, 1988 NULL); 1989 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB) 1990 ifmedia_add(softc->media, IFM_ETHER | IFM_40G_SR4, 0, 1991 NULL); 1992 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB) 1993 ifmedia_add(softc->media, IFM_ETHER | IFM_25G_SR, 0, 1994 NULL); 1995 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 1996 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_SR, 0, 1997 NULL); 1998 break; 1999 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX: 2000 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 2001 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_KX4, 0, 2002 NULL); 2003 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) 2004 ifmedia_add(softc->media, IFM_ETHER | IFM_2500_KX, 0, 2005 NULL); 2006 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) 2007 ifmedia_add(softc->media, IFM_ETHER | IFM_1000_KX, 0, 2008 NULL); 2009 break; 2010 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET: 2011 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE: 2012 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB) 2013 ifmedia_add(softc->media, IFM_ETHER | IFM_10_T, 0, 2014 NULL); 2015 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB) 2016 ifmedia_add(softc->media, IFM_ETHER | IFM_100_T, 0, 2017 NULL); 2018 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) 2019 ifmedia_add(softc->media, IFM_ETHER | IFM_1000_T, 0, 2020 NULL); 2021 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) 2022 ifmedia_add(softc->media, IFM_ETHER | IFM_2500_T, 0, 2023 NULL); 2024 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB) 2025 ifmedia_add(softc->media, IFM_ETHER | IFM_10G_T, 0, 2026 NULL); 2027 break; 2028 case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY: 2029 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB) 2030 ifmedia_add(softc->media, IFM_ETHER | IFM_1000_SGMII, 0, 2031 NULL); 2032 break; 2033 } 2034 2035 return; 2036} 2037 2038static int 2039bnxt_map_bar(struct bnxt_softc *softc, struct bnxt_bar_info *bar, int bar_num, bool shareable) 2040{ 2041 uint32_t flag; 2042 2043 if (bar->res != NULL) { 2044 device_printf(softc->dev, "Bar %d already mapped\n", bar_num); 2045 return EDOOFUS; 2046 } 2047 2048 bar->rid = PCIR_BAR(bar_num); 2049 flag = RF_ACTIVE; 2050 if (shareable) 2051 flag |= RF_SHAREABLE; 2052 2053 if ((bar->res = 2054 bus_alloc_resource_any(softc->dev, 2055 SYS_RES_MEMORY, 2056 &bar->rid, 2057 flag)) == NULL) { 2058 device_printf(softc->dev, 2059 "PCI BAR%d mapping failure\n", bar_num); 2060 return (ENXIO); 2061 } 2062 bar->tag = rman_get_bustag(bar->res); 2063 bar->handle = rman_get_bushandle(bar->res); 2064 bar->size = rman_get_size(bar->res); 2065 2066 return 0; 2067} 2068 2069static int 2070bnxt_pci_mapping(struct bnxt_softc *softc) 2071{ 2072 int rc; 2073 2074 rc = bnxt_map_bar(softc, &softc->hwrm_bar, 0, true); 2075 if (rc) 2076 return rc; 2077 2078 rc = bnxt_map_bar(softc, &softc->doorbell_bar, 2, false); 2079 2080 return rc; 2081} 2082 2083static void 2084bnxt_pci_mapping_free(struct bnxt_softc *softc) 2085{ 2086 if (softc->hwrm_bar.res != NULL) 2087 bus_release_resource(softc->dev, SYS_RES_MEMORY, 2088 softc->hwrm_bar.rid, softc->hwrm_bar.res); 2089 softc->hwrm_bar.res = NULL; 2090 2091 if (softc->doorbell_bar.res != NULL) 2092 bus_release_resource(softc->dev, SYS_RES_MEMORY, 2093 softc->doorbell_bar.rid, softc->doorbell_bar.res); 2094 softc->doorbell_bar.res = NULL; 2095} 2096 2097static int 2098bnxt_update_link(struct bnxt_softc *softc, bool chng_link_state) 2099{ 2100 struct bnxt_link_info *link_info = &softc->link_info; 2101 uint8_t link_up = link_info->link_up; 2102 int rc = 0; 2103 2104 rc = bnxt_hwrm_port_phy_qcfg(softc); 2105 if (rc) 2106 goto exit; 2107 2108 /* TODO: need to add more logic to report VF link */ 2109 if (chng_link_state) { 2110 if (link_info->phy_link_status == 2111 HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) 2112 link_info->link_up = 1; 2113 else 2114 link_info->link_up = 0; 2115 if (link_up != link_info->link_up) 2116 bnxt_report_link(softc); 2117 } else { 2118 /* always link down if not require to update link state */ 2119 link_info->link_up = 0; 2120 } 2121 2122exit: 2123 return rc; 2124} 2125 2126void 2127bnxt_report_link(struct bnxt_softc *softc) 2128{ 2129 const char *duplex = NULL, *flow_ctrl = NULL; 2130 2131 if (softc->link_info.link_up == softc->link_info.last_link_up) { 2132 if (!softc->link_info.link_up) 2133 return; 2134 if (softc->link_info.pause == softc->link_info.last_pause && 2135 softc->link_info.duplex == softc->link_info.last_duplex) 2136 return; 2137 } 2138 2139 if (softc->link_info.link_up) { 2140 if (softc->link_info.duplex == 2141 HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL) 2142 duplex = "full duplex"; 2143 else 2144 duplex = "half duplex"; 2145 if (softc->link_info.pause == ( 2146 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | 2147 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) 2148 flow_ctrl = "FC - receive & transmit"; 2149 else if (softc->link_info.pause == 2150 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX) 2151 flow_ctrl = "FC - transmit"; 2152 else if (softc->link_info.pause == 2153 HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) 2154 flow_ctrl = "FC - receive"; 2155 else 2156 flow_ctrl = "none"; 2157 iflib_link_state_change(softc->ctx, LINK_STATE_UP, 2158 IF_Gbps(100)); 2159 device_printf(softc->dev, "Link is UP %s, %s\n", duplex, 2160 flow_ctrl); 2161 } else { 2162 iflib_link_state_change(softc->ctx, LINK_STATE_DOWN, 2163 bnxt_get_baudrate(&softc->link_info)); 2164 device_printf(softc->dev, "Link is Down\n"); 2165 } 2166 2167 softc->link_info.last_link_up = softc->link_info.link_up; 2168 softc->link_info.last_pause = softc->link_info.pause; 2169 softc->link_info.last_duplex = softc->link_info.duplex; 2170} 2171 2172static int 2173bnxt_handle_rx_cp(void *arg) 2174{ 2175 struct bnxt_cp_ring *cpr = arg; 2176 2177 /* Disable further interrupts for this queue */ 2178 BNXT_CP_DISABLE_DB(&cpr->ring); 2179 return FILTER_SCHEDULE_THREAD; 2180} 2181 2182static int 2183bnxt_handle_def_cp(void *arg) 2184{ 2185 struct bnxt_softc *softc = arg; 2186 2187 BNXT_CP_DISABLE_DB(&softc->def_cp_ring.ring); 2188 GROUPTASK_ENQUEUE(&softc->def_cp_task); 2189 return FILTER_HANDLED; 2190} 2191 2192static void 2193bnxt_clear_ids(struct bnxt_softc *softc) 2194{ 2195 int i; 2196 2197 softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE; 2198 softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE; 2199 for (i = 0; i < softc->ntxqsets; i++) { 2200 softc->tx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE; 2201 softc->tx_cp_rings[i].ring.phys_id = 2202 (uint16_t)HWRM_NA_SIGNATURE; 2203 softc->tx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 2204 } 2205 for (i = 0; i < softc->nrxqsets; i++) { 2206 softc->rx_cp_rings[i].stats_ctx_id = HWRM_NA_SIGNATURE; 2207 softc->rx_cp_rings[i].ring.phys_id = 2208 (uint16_t)HWRM_NA_SIGNATURE; 2209 softc->rx_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 2210 softc->ag_rings[i].phys_id = (uint16_t)HWRM_NA_SIGNATURE; 2211 softc->grp_info[i].grp_id = (uint16_t)HWRM_NA_SIGNATURE; 2212 } 2213 softc->vnic_info.filter_id = -1; 2214 softc->vnic_info.id = (uint16_t)HWRM_NA_SIGNATURE; 2215 softc->vnic_info.rss_id = (uint16_t)HWRM_NA_SIGNATURE; 2216 memset(softc->vnic_info.rss_grp_tbl.idi_vaddr, 0xff, 2217 softc->vnic_info.rss_grp_tbl.idi_size); 2218} 2219 2220static void 2221bnxt_mark_cpr_invalid(struct bnxt_cp_ring *cpr) 2222{ 2223 struct cmpl_base *cmp = (void *)cpr->ring.vaddr; 2224 int i; 2225 2226 for (i = 0; i < cpr->ring.ring_size; i++) 2227 cmp[i].info3_v = !cpr->v_bit; 2228} 2229 2230static void 2231bnxt_handle_async_event(struct bnxt_softc *softc, struct cmpl_base *cmpl) 2232{ 2233 struct hwrm_async_event_cmpl *ae = (void *)cmpl; 2234 uint16_t async_id = le16toh(ae->event_id); 2235 struct ifmediareq ifmr; 2236 2237 switch (async_id) { 2238 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: 2239 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE: 2240 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE: 2241 bnxt_media_status(softc->ctx, &ifmr); 2242 break; 2243 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE: 2244 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE: 2245 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED: 2246 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED: 2247 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD: 2248 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD: 2249 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD: 2250 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD: 2251 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR: 2252 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE: 2253 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE: 2254 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE: 2255 case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR: 2256 device_printf(softc->dev, 2257 "Unhandled async completion type %u\n", async_id); 2258 break; 2259 default: 2260 device_printf(softc->dev, 2261 "Unknown async completion type %u\n", async_id); 2262 break; 2263 } 2264} 2265 2266static void 2267bnxt_def_cp_task(void *context) 2268{ 2269 if_ctx_t ctx = context; 2270 struct bnxt_softc *softc = iflib_get_softc(ctx); 2271 struct bnxt_cp_ring *cpr = &softc->def_cp_ring; 2272 2273 /* Handle completions on the default completion ring */ 2274 struct cmpl_base *cmpl; 2275 uint32_t cons = cpr->cons; 2276 bool v_bit = cpr->v_bit; 2277 bool last_v_bit; 2278 uint32_t last_cons; 2279 uint16_t type; 2280 2281 for (;;) { 2282 last_cons = cons; 2283 last_v_bit = v_bit; 2284 NEXT_CP_CONS_V(&cpr->ring, cons, v_bit); 2285 cmpl = &((struct cmpl_base *)cpr->ring.vaddr)[cons]; 2286 2287 if (!CMP_VALID(cmpl, v_bit)) 2288 break; 2289 2290 type = le16toh(cmpl->type) & CMPL_BASE_TYPE_MASK; 2291 switch (type) { 2292 case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: 2293 bnxt_handle_async_event(softc, cmpl); 2294 break; 2295 case CMPL_BASE_TYPE_TX_L2: 2296 case CMPL_BASE_TYPE_RX_L2: 2297 case CMPL_BASE_TYPE_RX_AGG: 2298 case CMPL_BASE_TYPE_RX_TPA_START: 2299 case CMPL_BASE_TYPE_RX_TPA_END: 2300 case CMPL_BASE_TYPE_STAT_EJECT: 2301 case CMPL_BASE_TYPE_HWRM_DONE: 2302 case CMPL_BASE_TYPE_HWRM_FWD_REQ: 2303 case CMPL_BASE_TYPE_HWRM_FWD_RESP: 2304 case CMPL_BASE_TYPE_CQ_NOTIFICATION: 2305 case CMPL_BASE_TYPE_SRQ_EVENT: 2306 case CMPL_BASE_TYPE_DBQ_EVENT: 2307 case CMPL_BASE_TYPE_QP_EVENT: 2308 case CMPL_BASE_TYPE_FUNC_EVENT: 2309 device_printf(softc->dev, 2310 "Unhandled completion type %u\n", type); 2311 break; 2312 default: 2313 device_printf(softc->dev, 2314 "Unknown completion type %u\n", type); 2315 break; 2316 } 2317 } 2318 2319 cpr->cons = last_cons; 2320 cpr->v_bit = last_v_bit; 2321 BNXT_CP_IDX_ENABLE_DB(&cpr->ring, cpr->cons); 2322} 2323 2324static uint8_t 2325get_phy_type(struct bnxt_softc *softc) 2326{ 2327 struct bnxt_link_info *link_info = &softc->link_info; 2328 uint8_t phy_type = link_info->phy_type; 2329 uint16_t supported; 2330 2331 if (phy_type != HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN) 2332 return phy_type; 2333 2334 /* Deduce the phy type from the media type and supported speeds */ 2335 supported = link_info->support_speeds; 2336 2337 if (link_info->media_type == 2338 HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP) 2339 return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET; 2340 if (link_info->media_type == 2341 HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC) { 2342 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB) 2343 return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX; 2344 if (supported & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB) 2345 return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR; 2346 return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR; 2347 } 2348 if (link_info->media_type == 2349 HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE) 2350 return HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR; 2351 2352 return phy_type; 2353} 2354 2355bool 2356bnxt_check_hwrm_version(struct bnxt_softc *softc) 2357{ 2358 char buf[16]; 2359 2360 sprintf(buf, "%hhu.%hhu.%hhu", softc->ver_info->hwrm_min_major, 2361 softc->ver_info->hwrm_min_minor, softc->ver_info->hwrm_min_update); 2362 if (softc->ver_info->hwrm_min_major > softc->ver_info->hwrm_if_major) { 2363 device_printf(softc->dev, 2364 "WARNING: HWRM version %s is too old (older than %s)\n", 2365 softc->ver_info->hwrm_if_ver, buf); 2366 return false; 2367 } 2368 else if(softc->ver_info->hwrm_min_major == 2369 softc->ver_info->hwrm_if_major) { 2370 if (softc->ver_info->hwrm_min_minor > 2371 softc->ver_info->hwrm_if_minor) { 2372 device_printf(softc->dev, 2373 "WARNING: HWRM version %s is too old (older than %s)\n", 2374 softc->ver_info->hwrm_if_ver, buf); 2375 return false; 2376 } 2377 else if (softc->ver_info->hwrm_min_minor == 2378 softc->ver_info->hwrm_if_minor) { 2379 if (softc->ver_info->hwrm_min_update > 2380 softc->ver_info->hwrm_if_update) { 2381 device_printf(softc->dev, 2382 "WARNING: HWRM version %s is too old (older than %s)\n", 2383 softc->ver_info->hwrm_if_ver, buf); 2384 return false; 2385 } 2386 } 2387 } 2388 return true; 2389} 2390 2391static uint64_t 2392bnxt_get_baudrate(struct bnxt_link_info *link) 2393{ 2394 switch (link->link_speed) { 2395 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB: 2396 return IF_Mbps(100); 2397 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB: 2398 return IF_Gbps(1); 2399 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB: 2400 return IF_Gbps(2); 2401 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB: 2402 return IF_Mbps(2500); 2403 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB: 2404 return IF_Gbps(10); 2405 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB: 2406 return IF_Gbps(20); 2407 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB: 2408 return IF_Gbps(25); 2409 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB: 2410 return IF_Gbps(40); 2411 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB: 2412 return IF_Gbps(50); 2413 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB: 2414 return IF_Gbps(100); 2415 case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB: 2416 return IF_Mbps(10); 2417 } 2418 return IF_Gbps(100); 2419} 2420