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