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