The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bnxt/if_bnxt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 1f3c33dea70ded3de5f689847fe4e3d7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.