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