[BACK]Return to ixv.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci / ixgbe

Annotation of src/sys/dev/pci/ixgbe/ixv.c, Revision 1.84.2.8

1.84.2.8! pgoyette    1: /*$NetBSD: ixv.c,v 1.105 2018/06/06 20:02:31 kamil Exp $*/
1.84.2.6  pgoyette    2:
1.1       dyoung      3: /******************************************************************************
                      4:
1.58      msaitoh     5:   Copyright (c) 2001-2017, Intel Corporation
1.1       dyoung      6:   All rights reserved.
1.58      msaitoh     7:
                      8:   Redistribution and use in source and binary forms, with or without
1.1       dyoung      9:   modification, are permitted provided that the following conditions are met:
1.58      msaitoh    10:
                     11:    1. Redistributions of source code must retain the above copyright notice,
1.1       dyoung     12:       this list of conditions and the following disclaimer.
1.58      msaitoh    13:
                     14:    2. Redistributions in binary form must reproduce the above copyright
                     15:       notice, this list of conditions and the following disclaimer in the
1.1       dyoung     16:       documentation and/or other materials provided with the distribution.
1.58      msaitoh    17:
                     18:    3. Neither the name of the Intel Corporation nor the names of its
                     19:       contributors may be used to endorse or promote products derived from
1.1       dyoung     20:       this software without specific prior written permission.
1.58      msaitoh    21:
1.1       dyoung     22:   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1.58      msaitoh    23:   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
                     26:   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     27:   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     28:   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     29:   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     30:   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.1       dyoung     31:   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     32:   POSSIBILITY OF SUCH DAMAGE.
                     33:
                     34: ******************************************************************************/
1.84.2.4  pgoyette   35: /*$FreeBSD: head/sys/dev/ixgbe/if_ixv.c 331224 2018-03-19 20:55:05Z erj $*/
1.1       dyoung     36:
1.55      msaitoh    37: #ifdef _KERNEL_OPT
1.1       dyoung     38: #include "opt_inet.h"
1.4       msaitoh    39: #include "opt_inet6.h"
1.55      msaitoh    40: #include "opt_net_mpsafe.h"
                     41: #endif
1.1       dyoung     42:
1.21      msaitoh    43: #include "ixgbe.h"
1.13      msaitoh    44: #include "vlan.h"
1.1       dyoung     45:
1.58      msaitoh    46: /************************************************************************
                     47:  * Driver version
                     48:  ************************************************************************/
1.84.2.8! pgoyette   49: static const char ixv_driver_version[] = "2.0.1-k";
1.58      msaitoh    50:
                     51: /************************************************************************
                     52:  * PCI Device ID Table
                     53:  *
                     54:  *   Used by probe to select devices to load on
                     55:  *   Last field stores an index into ixv_strings
                     56:  *   Last entry must be all 0s
1.1       dyoung     57:  *
1.58      msaitoh    58:  *   { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
                     59:  ************************************************************************/
1.84.2.8! pgoyette   60: static const ixgbe_vendor_info_t ixv_vendor_info_array[] =
1.1       dyoung     61: {
                     62:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0},
1.5       msaitoh    63:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0},
1.21      msaitoh    64:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0},
                     65:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0},
1.58      msaitoh    66:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF, 0, 0, 0},
1.1       dyoung     67:        /* required last entry */
                     68:        {0, 0, 0, 0, 0}
                     69: };
                     70:
1.58      msaitoh    71: /************************************************************************
                     72:  * Table of branding strings
                     73:  ************************************************************************/
                     74: static const char *ixv_strings[] = {
1.1       dyoung     75:        "Intel(R) PRO/10GbE Virtual Function Network Driver"
                     76: };
                     77:
                     78: /*********************************************************************
                     79:  *  Function prototypes
                     80:  *********************************************************************/
1.3       msaitoh    81: static int      ixv_probe(device_t, cfdata_t, void *);
1.22      msaitoh    82: static void    ixv_attach(device_t, device_t, void *);
1.3       msaitoh    83: static int      ixv_detach(device_t, int);
                     84: #if 0
1.1       dyoung     85: static int      ixv_shutdown(device_t);
1.3       msaitoh    86: #endif
1.57      msaitoh    87: static int     ixv_ifflags_cb(struct ethercom *);
1.3       msaitoh    88: static int      ixv_ioctl(struct ifnet *, u_long, void *);
                     89: static int     ixv_init(struct ifnet *);
1.1       dyoung     90: static void    ixv_init_locked(struct adapter *);
1.56      msaitoh    91: static void    ixv_ifstop(struct ifnet *, int);
1.1       dyoung     92: static void     ixv_stop(void *);
1.58      msaitoh    93: static void     ixv_init_device_features(struct adapter *);
1.1       dyoung     94: static void     ixv_media_status(struct ifnet *, struct ifmediareq *);
                     95: static int      ixv_media_change(struct ifnet *);
1.3       msaitoh    96: static int      ixv_allocate_pci_resources(struct adapter *,
                     97:                    const struct pci_attach_args *);
1.11      msaitoh    98: static int      ixv_allocate_msix(struct adapter *,
                     99:                    const struct pci_attach_args *);
1.58      msaitoh   100: static int      ixv_configure_interrupts(struct adapter *);
1.1       dyoung    101: static void    ixv_free_pci_resources(struct adapter *);
                    102: static void     ixv_local_timer(void *);
1.22      msaitoh   103: static void     ixv_local_timer_locked(void *);
1.73      msaitoh   104: static int      ixv_setup_interface(device_t, struct adapter *);
1.58      msaitoh   105: static int      ixv_negotiate_api(struct adapter *);
1.1       dyoung    106:
                    107: static void     ixv_initialize_transmit_units(struct adapter *);
                    108: static void     ixv_initialize_receive_units(struct adapter *);
1.58      msaitoh   109: static void     ixv_initialize_rss_mapping(struct adapter *);
                    110: static void     ixv_check_link(struct adapter *);
1.1       dyoung    111:
                    112: static void     ixv_enable_intr(struct adapter *);
                    113: static void     ixv_disable_intr(struct adapter *);
                    114: static void     ixv_set_multi(struct adapter *);
                    115: static void     ixv_update_link_status(struct adapter *);
1.3       msaitoh   116: static int     ixv_sysctl_debug(SYSCTLFN_PROTO);
1.1       dyoung    117: static void    ixv_set_ivar(struct adapter *, u8, u8, s8);
                    118: static void    ixv_configure_ivars(struct adapter *);
                    119: static u8 *    ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
1.84.2.6  pgoyette  120: static void    ixv_eitr_write(struct adapter *, uint32_t, uint32_t);
1.1       dyoung    121:
                    122: static void    ixv_setup_vlan_support(struct adapter *);
1.3       msaitoh   123: #if 0
1.1       dyoung    124: static void    ixv_register_vlan(void *, struct ifnet *, u16);
                    125: static void    ixv_unregister_vlan(void *, struct ifnet *, u16);
1.3       msaitoh   126: #endif
1.1       dyoung    127:
1.48      msaitoh   128: static void    ixv_add_device_sysctls(struct adapter *);
1.1       dyoung    129: static void    ixv_save_stats(struct adapter *);
                    130: static void    ixv_init_stats(struct adapter *);
                    131: static void    ixv_update_stats(struct adapter *);
1.21      msaitoh   132: static void    ixv_add_stats_sysctls(struct adapter *);
1.83      msaitoh   133:
                    134:
                    135: /* Sysctl handlers */
1.25      msaitoh   136: static void    ixv_set_sysctl_value(struct adapter *, const char *,
                    137:                    const char *, int *, int);
1.83      msaitoh   138: static int      ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
1.84.2.8! pgoyette  139: static int      ixv_sysctl_next_to_check_handler(SYSCTLFN_PROTO);
1.83      msaitoh   140: static int      ixv_sysctl_rdh_handler(SYSCTLFN_PROTO);
                    141: static int      ixv_sysctl_rdt_handler(SYSCTLFN_PROTO);
                    142: static int      ixv_sysctl_tdt_handler(SYSCTLFN_PROTO);
                    143: static int      ixv_sysctl_tdh_handler(SYSCTLFN_PROTO);
1.1       dyoung    144:
1.58      msaitoh   145: /* The MSI-X Interrupt handlers */
1.11      msaitoh   146: static int     ixv_msix_que(void *);
                    147: static int     ixv_msix_mbx(void *);
1.1       dyoung    148:
                    149: /* Deferred interrupt tasklets */
1.3       msaitoh   150: static void    ixv_handle_que(void *);
1.58      msaitoh   151: static void     ixv_handle_link(void *);
1.3       msaitoh   152:
1.84      knakahar  153: /* Workqueue handler for deferred work */
                    154: static void    ixv_handle_que_work(struct work *, void *);
                    155:
1.3       msaitoh   156: const struct sysctlnode *ixv_sysctl_instance(struct adapter *);
1.84.2.8! pgoyette  157: static const ixgbe_vendor_info_t *ixv_lookup(const struct pci_attach_args *);
1.1       dyoung    158:
1.58      msaitoh   159: /************************************************************************
                    160:  * FreeBSD Device Interface Entry Points
                    161:  ************************************************************************/
1.3       msaitoh   162: CFATTACH_DECL3_NEW(ixv, sizeof(struct adapter),
                    163:     ixv_probe, ixv_attach, ixv_detach, NULL, NULL, NULL,
                    164:     DVF_DETACH_SHUTDOWN);
                    165:
1.1       dyoung    166: #if 0
                    167: static driver_t ixv_driver = {
1.21      msaitoh   168:        "ixv", ixv_methods, sizeof(struct adapter),
1.1       dyoung    169: };
                    170:
1.22      msaitoh   171: devclass_t ixv_devclass;
                    172: DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0);
1.1       dyoung    173: MODULE_DEPEND(ixv, pci, 1, 1, 1);
                    174: MODULE_DEPEND(ixv, ether, 1, 1, 1);
                    175: #endif
                    176:
                    177: /*
1.58      msaitoh   178:  * TUNEABLE PARAMETERS:
                    179:  */
1.1       dyoung    180:
1.58      msaitoh   181: /* Number of Queues - do not exceed MSI-X vectors - 1 */
1.44      msaitoh   182: static int ixv_num_queues = 0;
1.23      msaitoh   183: #define        TUNABLE_INT(__x, __y)
                    184: TUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues);
                    185:
1.1       dyoung    186: /*
1.58      msaitoh   187:  * AIM: Adaptive Interrupt Moderation
                    188:  * which means that the interrupt rate
                    189:  * is varied over time based on the
                    190:  * traffic for that interrupt vector
                    191:  */
1.50      msaitoh   192: static bool ixv_enable_aim = false;
1.1       dyoung    193: TUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim);
                    194:
1.83      msaitoh   195: static int ixv_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY);
                    196: TUNABLE_INT("hw.ixv.max_interrupt_rate", &ixv_max_interrupt_rate);
                    197:
1.1       dyoung    198: /* How many packets rxeof tries to clean at a time */
1.21      msaitoh   199: static int ixv_rx_process_limit = 256;
1.1       dyoung    200: TUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit);
                    201:
1.21      msaitoh   202: /* How many packets txeof tries to clean at a time */
                    203: static int ixv_tx_process_limit = 256;
                    204: TUNABLE_INT("hw.ixv.tx_process_limit", &ixv_tx_process_limit);
1.1       dyoung    205:
1.84      knakahar  206: /* Which pakcet processing uses workqueue or softint */
                    207: static bool ixv_txrx_workqueue = false;
                    208:
1.1       dyoung    209: /*
1.58      msaitoh   210:  * Number of TX descriptors per ring,
                    211:  * setting higher than RX as this seems
                    212:  * the better performing choice.
                    213:  */
1.64      msaitoh   214: static int ixv_txd = PERFORM_TXD;
1.1       dyoung    215: TUNABLE_INT("hw.ixv.txd", &ixv_txd);
                    216:
                    217: /* Number of RX descriptors per ring */
1.64      msaitoh   218: static int ixv_rxd = PERFORM_RXD;
1.1       dyoung    219: TUNABLE_INT("hw.ixv.rxd", &ixv_rxd);
                    220:
1.58      msaitoh   221: /* Legacy Transmit (single queue) */
                    222: static int ixv_enable_legacy_tx = 0;
                    223: TUNABLE_INT("hw.ixv.enable_legacy_tx", &ixv_enable_legacy_tx);
                    224:
1.55      msaitoh   225: #ifdef NET_MPSAFE
                    226: #define IXGBE_MPSAFE           1
                    227: #define IXGBE_CALLOUT_FLAGS    CALLOUT_MPSAFE
                    228: #define IXGBE_SOFTINFT_FLAGS   SOFTINT_MPSAFE
1.84      knakahar  229: #define IXGBE_WORKQUEUE_FLAGS  WQ_PERCPU | WQ_MPSAFE
1.55      msaitoh   230: #else
                    231: #define IXGBE_CALLOUT_FLAGS    0
                    232: #define IXGBE_SOFTINFT_FLAGS   0
1.84      knakahar  233: #define IXGBE_WORKQUEUE_FLAGS  WQ_PERCPU
1.55      msaitoh   234: #endif
1.84      knakahar  235: #define IXGBE_WORKQUEUE_PRI PRI_SOFTNET
1.55      msaitoh   236:
1.58      msaitoh   237: #if 0
                    238: static int (*ixv_start_locked)(struct ifnet *, struct tx_ring *);
                    239: static int (*ixv_ring_empty)(struct ifnet *, struct buf_ring *);
                    240: #endif
                    241:
                    242: /************************************************************************
                    243:  * ixv_probe - Device identification routine
1.1       dyoung    244:  *
1.58      msaitoh   245:  *   Determines if the driver should be loaded on
                    246:  *   adapter based on its PCI vendor/device ID.
1.1       dyoung    247:  *
1.58      msaitoh   248:  *   return BUS_PROBE_DEFAULT on success, positive on failure
                    249:  ************************************************************************/
1.1       dyoung    250: static int
1.3       msaitoh   251: ixv_probe(device_t dev, cfdata_t cf, void *aux)
                    252: {
1.19      knakahar  253: #ifdef __HAVE_PCI_MSI_MSIX
1.3       msaitoh   254:        const struct pci_attach_args *pa = aux;
                    255:
                    256:        return (ixv_lookup(pa) != NULL) ? 1 : 0;
1.18      msaitoh   257: #else
                    258:        return 0;
                    259: #endif
1.58      msaitoh   260: } /* ixv_probe */
1.3       msaitoh   261:
1.84.2.8! pgoyette  262: static const ixgbe_vendor_info_t *
1.3       msaitoh   263: ixv_lookup(const struct pci_attach_args *pa)
1.1       dyoung    264: {
1.84.2.8! pgoyette  265:        const ixgbe_vendor_info_t *ent;
1.3       msaitoh   266:        pcireg_t subid;
1.1       dyoung    267:
1.31      msaitoh   268:        INIT_DEBUGOUT("ixv_lookup: begin");
1.1       dyoung    269:
1.3       msaitoh   270:        if (PCI_VENDOR(pa->pa_id) != IXGBE_INTEL_VENDOR_ID)
                    271:                return NULL;
1.1       dyoung    272:
1.3       msaitoh   273:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
1.1       dyoung    274:
1.3       msaitoh   275:        for (ent = ixv_vendor_info_array; ent->vendor_id != 0; ent++) {
                    276:                if ((PCI_VENDOR(pa->pa_id) == ent->vendor_id) &&
                    277:                    (PCI_PRODUCT(pa->pa_id) == ent->device_id) &&
                    278:                    ((PCI_SUBSYS_VENDOR(subid) == ent->subvendor_id) ||
1.1       dyoung    279:                     (ent->subvendor_id == 0)) &&
1.3       msaitoh   280:                    ((PCI_SUBSYS_ID(subid) == ent->subdevice_id) ||
1.1       dyoung    281:                     (ent->subdevice_id == 0))) {
1.3       msaitoh   282:                        return ent;
1.1       dyoung    283:                }
                    284:        }
1.58      msaitoh   285:
1.3       msaitoh   286:        return NULL;
                    287: }
                    288:
1.58      msaitoh   289: /************************************************************************
                    290:  * ixv_attach - Device initialization routine
1.57      msaitoh   291:  *
1.58      msaitoh   292:  *   Called when the driver is being loaded.
                    293:  *   Identifies the type of hardware, allocates all resources
                    294:  *   and initializes the hardware.
1.57      msaitoh   295:  *
1.58      msaitoh   296:  *   return 0 on success, positive on failure
                    297:  ************************************************************************/
1.3       msaitoh   298: static void
                    299: ixv_attach(device_t parent, device_t dev, void *aux)
1.1       dyoung    300: {
                    301:        struct adapter *adapter;
                    302:        struct ixgbe_hw *hw;
                    303:        int             error = 0;
1.58      msaitoh   304:        pcireg_t        id, subid;
1.84.2.8! pgoyette  305:        const ixgbe_vendor_info_t *ent;
1.3       msaitoh   306:        const struct pci_attach_args *pa = aux;
1.60      msaitoh   307:        const char *apivstr;
1.66      msaitoh   308:        const char *str;
1.63      msaitoh   309:        char buf[256];
                    310:
1.1       dyoung    311:        INIT_DEBUGOUT("ixv_attach: begin");
                    312:
1.58      msaitoh   313:        /*
                    314:         * Make sure BUSMASTER is set, on a VM under
                    315:         * KVM it may not be and will break things.
                    316:         */
                    317:        ixgbe_pci_enable_busmaster(pa->pa_pc, pa->pa_tag);
                    318:
1.1       dyoung    319:        /* Allocate, clear, and link in our adapter structure */
1.3       msaitoh   320:        adapter = device_private(dev);
1.26      msaitoh   321:        adapter->dev = dev;
1.58      msaitoh   322:        adapter->hw.back = adapter;
1.1       dyoung    323:        hw = &adapter->hw;
1.26      msaitoh   324:
                    325:        adapter->init_locked = ixv_init_locked;
                    326:        adapter->stop_locked = ixv_stop;
                    327:
1.13      msaitoh   328:        adapter->osdep.pc = pa->pa_pc;
                    329:        adapter->osdep.tag = pa->pa_tag;
1.43      msaitoh   330:        if (pci_dma64_available(pa))
                    331:                adapter->osdep.dmat = pa->pa_dmat64;
                    332:        else
                    333:                adapter->osdep.dmat = pa->pa_dmat;
1.13      msaitoh   334:        adapter->osdep.attached = false;
1.1       dyoung    335:
1.3       msaitoh   336:        ent = ixv_lookup(pa);
                    337:
                    338:        KASSERT(ent != NULL);
                    339:
                    340:        aprint_normal(": %s, Version - %s\n",
                    341:            ixv_strings[ent->index], ixv_driver_version);
                    342:
1.1       dyoung    343:        /* Core Lock Init*/
1.21      msaitoh   344:        IXGBE_CORE_LOCK_INIT(adapter, device_xname(dev));
1.1       dyoung    345:
                    346:        /* Do base PCI setup - map BAR0 */
1.3       msaitoh   347:        if (ixv_allocate_pci_resources(adapter, pa)) {
1.26      msaitoh   348:                aprint_error_dev(dev, "ixv_allocate_pci_resources() failed!\n");
1.1       dyoung    349:                error = ENXIO;
                    350:                goto err_out;
                    351:        }
                    352:
1.58      msaitoh   353:        /* SYSCTL APIs */
                    354:        ixv_add_device_sysctls(adapter);
1.25      msaitoh   355:
1.58      msaitoh   356:        /* Set up the timer callout */
                    357:        callout_init(&adapter->timer, IXGBE_CALLOUT_FLAGS);
1.25      msaitoh   358:
1.58      msaitoh   359:        /* Save off the information about this board */
                    360:        id = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
                    361:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                    362:        hw->vendor_id = PCI_VENDOR(id);
                    363:        hw->device_id = PCI_PRODUCT(id);
                    364:        hw->revision_id =
                    365:            PCI_REVISION(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG));
                    366:        hw->subsystem_vendor_id = PCI_SUBSYS_VENDOR(subid);
                    367:        hw->subsystem_device_id = PCI_SUBSYS_ID(subid);
1.1       dyoung    368:
1.58      msaitoh   369:        /* A subset of set_mac_type */
                    370:        switch (hw->device_id) {
                    371:        case IXGBE_DEV_ID_82599_VF:
                    372:                hw->mac.type = ixgbe_mac_82599_vf;
1.66      msaitoh   373:                str = "82599 VF";
1.58      msaitoh   374:                break;
                    375:        case IXGBE_DEV_ID_X540_VF:
                    376:                hw->mac.type = ixgbe_mac_X540_vf;
1.66      msaitoh   377:                str = "X540 VF";
1.58      msaitoh   378:                break;
                    379:        case IXGBE_DEV_ID_X550_VF:
                    380:                hw->mac.type = ixgbe_mac_X550_vf;
1.66      msaitoh   381:                str = "X550 VF";
1.58      msaitoh   382:                break;
                    383:        case IXGBE_DEV_ID_X550EM_X_VF:
                    384:                hw->mac.type = ixgbe_mac_X550EM_x_vf;
1.66      msaitoh   385:                str = "X550EM X VF";
1.58      msaitoh   386:                break;
                    387:        case IXGBE_DEV_ID_X550EM_A_VF:
                    388:                hw->mac.type = ixgbe_mac_X550EM_a_vf;
1.66      msaitoh   389:                str = "X550EM A VF";
1.58      msaitoh   390:                break;
                    391:        default:
                    392:                /* Shouldn't get here since probe succeeded */
                    393:                aprint_error_dev(dev, "Unknown device ID!\n");
                    394:                error = ENXIO;
1.1       dyoung    395:                goto err_out;
1.58      msaitoh   396:                break;
1.1       dyoung    397:        }
1.66      msaitoh   398:        aprint_normal_dev(dev, "device %s\n", str);
1.1       dyoung    399:
1.58      msaitoh   400:        ixv_init_device_features(adapter);
                    401:
                    402:        /* Initialize the shared code */
                    403:        error = ixgbe_init_ops_vf(hw);
1.1       dyoung    404:        if (error) {
1.58      msaitoh   405:                aprint_error_dev(dev, "ixgbe_init_ops_vf() failed!\n");
1.1       dyoung    406:                error = EIO;
1.58      msaitoh   407:                goto err_out;
1.1       dyoung    408:        }
                    409:
                    410:        /* Setup the mailbox */
                    411:        ixgbe_init_mbx_params_vf(hw);
                    412:
1.58      msaitoh   413:        /* Set the right number of segments */
                    414:        adapter->num_segs = IXGBE_82599_SCATTER;
                    415:
1.26      msaitoh   416:        /* Reset mbox api to 1.0 */
1.58      msaitoh   417:        error = hw->mac.ops.reset_hw(hw);
1.26      msaitoh   418:        if (error == IXGBE_ERR_RESET_FAILED)
1.58      msaitoh   419:                aprint_error_dev(dev, "...reset_hw() failure: Reset Failed!\n");
1.26      msaitoh   420:        else if (error)
1.58      msaitoh   421:                aprint_error_dev(dev, "...reset_hw() failed with error %d\n",
                    422:                    error);
1.26      msaitoh   423:        if (error) {
                    424:                error = EIO;
1.58      msaitoh   425:                goto err_out;
1.26      msaitoh   426:        }
1.1       dyoung    427:
1.58      msaitoh   428:        error = hw->mac.ops.init_hw(hw);
1.1       dyoung    429:        if (error) {
1.58      msaitoh   430:                aprint_error_dev(dev, "...init_hw() failed!\n");
1.1       dyoung    431:                error = EIO;
1.58      msaitoh   432:                goto err_out;
1.1       dyoung    433:        }
1.63      msaitoh   434:
1.58      msaitoh   435:        /* Negotiate mailbox API version */
                    436:        error = ixv_negotiate_api(adapter);
                    437:        if (error)
                    438:                aprint_normal_dev(dev,
                    439:                    "MBX API negotiation failed during attach!\n");
1.60      msaitoh   440:        switch (hw->api_version) {
                    441:        case ixgbe_mbox_api_10:
                    442:                apivstr = "1.0";
                    443:                break;
                    444:        case ixgbe_mbox_api_20:
                    445:                apivstr = "2.0";
                    446:                break;
                    447:        case ixgbe_mbox_api_11:
                    448:                apivstr = "1.1";
                    449:                break;
                    450:        case ixgbe_mbox_api_12:
                    451:                apivstr = "1.2";
                    452:                break;
                    453:        case ixgbe_mbox_api_13:
                    454:                apivstr = "1.3";
                    455:                break;
                    456:        default:
                    457:                apivstr = "unknown";
                    458:                break;
                    459:        }
                    460:        aprint_normal_dev(dev, "Mailbox API %s\n", apivstr);
1.1       dyoung    461:
1.21      msaitoh   462:        /* If no mac address was assigned, make a random one */
                    463:        if (!ixv_check_ether_addr(hw->mac.addr)) {
                    464:                u8 addr[ETHER_ADDR_LEN];
1.59      msaitoh   465:                uint64_t rndval = cprng_strong64();
1.21      msaitoh   466:
                    467:                memcpy(addr, &rndval, sizeof(addr));
                    468:                addr[0] &= 0xFE;
                    469:                addr[0] |= 0x02;
                    470:                bcopy(addr, hw->mac.addr, sizeof(addr));
                    471:        }
                    472:
1.58      msaitoh   473:        /* Register for VLAN events */
                    474: #if 0 /* XXX delete after write? */
                    475:        adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
                    476:            ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
                    477:        adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
                    478:            ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
                    479: #endif
                    480:
                    481:        /* Sysctls for limiting the amount of work done in the taskqueues */
                    482:        ixv_set_sysctl_value(adapter, "rx_processing_limit",
                    483:            "max number of rx packets to process",
                    484:            &adapter->rx_process_limit, ixv_rx_process_limit);
                    485:
                    486:        ixv_set_sysctl_value(adapter, "tx_processing_limit",
                    487:            "max number of tx packets to process",
                    488:            &adapter->tx_process_limit, ixv_tx_process_limit);
                    489:
                    490:        /* Do descriptor calc and sanity checks */
                    491:        if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
                    492:            ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) {
                    493:                aprint_error_dev(dev, "TXD config issue, using default!\n");
                    494:                adapter->num_tx_desc = DEFAULT_TXD;
                    495:        } else
                    496:                adapter->num_tx_desc = ixv_txd;
                    497:
                    498:        if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 ||
                    499:            ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) {
                    500:                aprint_error_dev(dev, "RXD config issue, using default!\n");
                    501:                adapter->num_rx_desc = DEFAULT_RXD;
                    502:        } else
                    503:                adapter->num_rx_desc = ixv_rxd;
                    504:
                    505:        /* Setup MSI-X */
1.63      msaitoh   506:        error = ixv_configure_interrupts(adapter);
1.58      msaitoh   507:        if (error)
                    508:                goto err_out;
                    509:
                    510:        /* Allocate our TX/RX Queues */
                    511:        if (ixgbe_allocate_queues(adapter)) {
                    512:                aprint_error_dev(dev, "ixgbe_allocate_queues() failed!\n");
                    513:                error = ENOMEM;
                    514:                goto err_out;
                    515:        }
                    516:
1.50      msaitoh   517:        /* hw.ix defaults init */
                    518:        adapter->enable_aim = ixv_enable_aim;
                    519:
1.84      knakahar  520:        adapter->txrx_use_workqueue = ixv_txrx_workqueue;
                    521:
1.76      msaitoh   522:        error = ixv_allocate_msix(adapter, pa);
                    523:        if (error) {
                    524:                device_printf(dev, "ixv_allocate_msix() failed!\n");
                    525:                goto err_late;
                    526:        }
                    527:
1.1       dyoung    528:        /* Setup OS specific network interface */
1.73      msaitoh   529:        error = ixv_setup_interface(dev, adapter);
                    530:        if (error != 0) {
                    531:                aprint_error_dev(dev, "ixv_setup_interface() failed!\n");
                    532:                goto err_late;
                    533:        }
1.1       dyoung    534:
                    535:        /* Do the stats setup */
                    536:        ixv_save_stats(adapter);
                    537:        ixv_init_stats(adapter);
1.58      msaitoh   538:        ixv_add_stats_sysctls(adapter);
1.1       dyoung    539:
1.58      msaitoh   540:        if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
                    541:                ixgbe_netmap_attach(adapter);
1.48      msaitoh   542:
1.63      msaitoh   543:        snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_cap);
                    544:        aprint_verbose_dev(dev, "feature cap %s\n", buf);
                    545:        snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_en);
                    546:        aprint_verbose_dev(dev, "feature ena %s\n", buf);
                    547:
1.1       dyoung    548:        INIT_DEBUGOUT("ixv_attach: end");
1.13      msaitoh   549:        adapter->osdep.attached = true;
1.57      msaitoh   550:
1.3       msaitoh   551:        return;
1.1       dyoung    552:
                    553: err_late:
1.21      msaitoh   554:        ixgbe_free_transmit_structures(adapter);
                    555:        ixgbe_free_receive_structures(adapter);
1.58      msaitoh   556:        free(adapter->queues, M_DEVBUF);
1.1       dyoung    557: err_out:
                    558:        ixv_free_pci_resources(adapter);
1.58      msaitoh   559:        IXGBE_CORE_LOCK_DESTROY(adapter);
                    560:
1.3       msaitoh   561:        return;
1.58      msaitoh   562: } /* ixv_attach */
1.1       dyoung    563:
1.58      msaitoh   564: /************************************************************************
                    565:  * ixv_detach - Device removal routine
1.1       dyoung    566:  *
1.58      msaitoh   567:  *   Called when the driver is being removed.
                    568:  *   Stops the adapter and deallocates all the resources
                    569:  *   that were allocated for driver operation.
1.1       dyoung    570:  *
1.58      msaitoh   571:  *   return 0 on success, positive on failure
                    572:  ************************************************************************/
1.1       dyoung    573: static int
1.3       msaitoh   574: ixv_detach(device_t dev, int flags)
1.1       dyoung    575: {
1.58      msaitoh   576:        struct adapter  *adapter = device_private(dev);
1.67      msaitoh   577:        struct ixgbe_hw *hw = &adapter->hw;
1.1       dyoung    578:        struct ix_queue *que = adapter->queues;
1.41      msaitoh   579:        struct tx_ring *txr = adapter->tx_rings;
1.49      msaitoh   580:        struct rx_ring *rxr = adapter->rx_rings;
                    581:        struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.1       dyoung    582:
                    583:        INIT_DEBUGOUT("ixv_detach: begin");
1.13      msaitoh   584:        if (adapter->osdep.attached == false)
                    585:                return 0;
1.1       dyoung    586:
1.56      msaitoh   587:        /* Stop the interface. Callouts are stopped in it. */
                    588:        ixv_ifstop(adapter->ifp, 1);
                    589:
1.13      msaitoh   590: #if NVLAN > 0
1.58      msaitoh   591:        /* Make sure VLANs are not using driver */
1.3       msaitoh   592:        if (!VLAN_ATTACHED(&adapter->osdep.ec))
                    593:                ;       /* nothing to do: no VLANs */
                    594:        else if ((flags & (DETACH_SHUTDOWN|DETACH_FORCE)) != 0)
                    595:                vlan_ifdetach(adapter->ifp);
                    596:        else {
1.26      msaitoh   597:                aprint_error_dev(dev, "VLANs in use, detach first\n");
1.3       msaitoh   598:                return EBUSY;
1.1       dyoung    599:        }
1.13      msaitoh   600: #endif
1.1       dyoung    601:
1.21      msaitoh   602:        IXGBE_CORE_LOCK(adapter);
1.1       dyoung    603:        ixv_stop(adapter);
1.21      msaitoh   604:        IXGBE_CORE_UNLOCK(adapter);
1.1       dyoung    605:
1.41      msaitoh   606:        for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
1.58      msaitoh   607:                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
                    608:                        softint_disestablish(txr->txr_si);
1.3       msaitoh   609:                softint_disestablish(que->que_si);
1.1       dyoung    610:        }
1.84      knakahar  611:        if (adapter->txr_wq != NULL)
                    612:                workqueue_destroy(adapter->txr_wq);
                    613:        if (adapter->txr_wq_enqueued != NULL)
                    614:                percpu_free(adapter->txr_wq_enqueued, sizeof(u_int));
                    615:        if (adapter->que_wq != NULL)
                    616:                workqueue_destroy(adapter->que_wq);
1.1       dyoung    617:
1.21      msaitoh   618:        /* Drain the Mailbox(link) queue */
                    619:        softint_disestablish(adapter->link_si);
1.1       dyoung    620:
                    621:        /* Unregister VLAN events */
1.3       msaitoh   622: #if 0 /* XXX msaitoh delete after write? */
1.1       dyoung    623:        if (adapter->vlan_attach != NULL)
                    624:                EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
                    625:        if (adapter->vlan_detach != NULL)
                    626:                EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
1.3       msaitoh   627: #endif
1.1       dyoung    628:
                    629:        ether_ifdetach(adapter->ifp);
1.3       msaitoh   630:        callout_halt(&adapter->timer, NULL);
1.58      msaitoh   631:
                    632:        if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
                    633:                netmap_detach(adapter->ifp);
                    634:
1.1       dyoung    635:        ixv_free_pci_resources(adapter);
1.3       msaitoh   636: #if 0 /* XXX the NetBSD port is probably missing something here */
1.1       dyoung    637:        bus_generic_detach(dev);
1.3       msaitoh   638: #endif
                    639:        if_detach(adapter->ifp);
1.52      msaitoh   640:        if_percpuq_destroy(adapter->ipq);
1.1       dyoung    641:
1.41      msaitoh   642:        sysctl_teardown(&adapter->sysctllog);
1.49      msaitoh   643:        evcnt_detach(&adapter->efbig_tx_dma_setup);
                    644:        evcnt_detach(&adapter->mbuf_defrag_failed);
                    645:        evcnt_detach(&adapter->efbig2_tx_dma_setup);
                    646:        evcnt_detach(&adapter->einval_tx_dma_setup);
                    647:        evcnt_detach(&adapter->other_tx_dma_setup);
                    648:        evcnt_detach(&adapter->eagain_tx_dma_setup);
                    649:        evcnt_detach(&adapter->enomem_tx_dma_setup);
                    650:        evcnt_detach(&adapter->watchdog_events);
                    651:        evcnt_detach(&adapter->tso_err);
                    652:        evcnt_detach(&adapter->link_irq);
                    653:
                    654:        txr = adapter->tx_rings;
                    655:        for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
                    656:                evcnt_detach(&adapter->queues[i].irqs);
1.84.2.1  pgoyette  657:                evcnt_detach(&adapter->queues[i].handleq);
                    658:                evcnt_detach(&adapter->queues[i].req);
1.49      msaitoh   659:                evcnt_detach(&txr->no_desc_avail);
                    660:                evcnt_detach(&txr->total_packets);
                    661:                evcnt_detach(&txr->tso_tx);
                    662: #ifndef IXGBE_LEGACY_TX
                    663:                evcnt_detach(&txr->pcq_drops);
                    664: #endif
                    665:
                    666:                evcnt_detach(&rxr->rx_packets);
                    667:                evcnt_detach(&rxr->rx_bytes);
                    668:                evcnt_detach(&rxr->rx_copies);
                    669:                evcnt_detach(&rxr->no_jmbuf);
                    670:                evcnt_detach(&rxr->rx_discarded);
                    671:        }
                    672:        evcnt_detach(&stats->ipcs);
                    673:        evcnt_detach(&stats->l4cs);
                    674:        evcnt_detach(&stats->ipcs_bad);
                    675:        evcnt_detach(&stats->l4cs_bad);
                    676:
                    677:        /* Packet Reception Stats */
                    678:        evcnt_detach(&stats->vfgorc);
                    679:        evcnt_detach(&stats->vfgprc);
                    680:        evcnt_detach(&stats->vfmprc);
                    681:
                    682:        /* Packet Transmission Stats */
                    683:        evcnt_detach(&stats->vfgotc);
                    684:        evcnt_detach(&stats->vfgptc);
1.41      msaitoh   685:
1.67      msaitoh   686:        /* Mailbox Stats */
                    687:        evcnt_detach(&hw->mbx.stats.msgs_tx);
                    688:        evcnt_detach(&hw->mbx.stats.msgs_rx);
                    689:        evcnt_detach(&hw->mbx.stats.acks);
                    690:        evcnt_detach(&hw->mbx.stats.reqs);
                    691:        evcnt_detach(&hw->mbx.stats.rsts);
                    692:
1.21      msaitoh   693:        ixgbe_free_transmit_structures(adapter);
                    694:        ixgbe_free_receive_structures(adapter);
1.82      knakahar  695:        for (int i = 0; i < adapter->num_queues; i++) {
                    696:                struct ix_queue *lque = &adapter->queues[i];
1.84.2.3  pgoyette  697:                mutex_destroy(&lque->dc_mtx);
1.82      knakahar  698:        }
1.58      msaitoh   699:        free(adapter->queues, M_DEVBUF);
1.1       dyoung    700:
1.21      msaitoh   701:        IXGBE_CORE_LOCK_DESTROY(adapter);
1.58      msaitoh   702:
1.1       dyoung    703:        return (0);
1.58      msaitoh   704: } /* ixv_detach */
1.1       dyoung    705:
1.58      msaitoh   706: /************************************************************************
                    707:  * ixv_init_locked - Init entry point
                    708:  *
                    709:  *   Used in two ways: It is used by the stack as an init entry
                    710:  *   point in network interface structure. It is also used
                    711:  *   by the driver as a hw/sw initialization routine to get
                    712:  *   to a consistent state.
1.1       dyoung    713:  *
1.58      msaitoh   714:  *   return 0 on success, positive on failure
                    715:  ************************************************************************/
1.1       dyoung    716: static void
                    717: ixv_init_locked(struct adapter *adapter)
                    718: {
                    719:        struct ifnet    *ifp = adapter->ifp;
                    720:        device_t        dev = adapter->dev;
                    721:        struct ixgbe_hw *hw = &adapter->hw;
1.84.2.8! pgoyette  722:        struct ix_queue *que;
1.58      msaitoh   723:        int             error = 0;
1.68      msaitoh   724:        uint32_t mask;
                    725:        int i;
1.1       dyoung    726:
1.26      msaitoh   727:        INIT_DEBUGOUT("ixv_init_locked: begin");
1.3       msaitoh   728:        KASSERT(mutex_owned(&adapter->core_mtx));
1.1       dyoung    729:        hw->adapter_stopped = FALSE;
1.58      msaitoh   730:        hw->mac.ops.stop_adapter(hw);
1.63      msaitoh   731:        callout_stop(&adapter->timer);
1.84.2.8! pgoyette  732:        for (i = 0, que = adapter->queues; i < adapter->num_queues; i++, que++)
        !           733:                que->disabled_count = 0;
1.1       dyoung    734:
1.57      msaitoh   735:        /* reprogram the RAR[0] in case user changed it. */
1.58      msaitoh   736:        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1.1       dyoung    737:
                    738:        /* Get the latest mac address, User can use a LAA */
1.84.2.4  pgoyette  739:        memcpy(hw->mac.addr, CLLADDR(ifp->if_sadl),
1.1       dyoung    740:             IXGBE_ETH_LENGTH_OF_ADDRESS);
1.58      msaitoh   741:        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, 1);
1.1       dyoung    742:
                    743:        /* Prepare transmit descriptors and buffers */
1.21      msaitoh   744:        if (ixgbe_setup_transmit_structures(adapter)) {
1.26      msaitoh   745:                aprint_error_dev(dev, "Could not setup transmit structures\n");
1.1       dyoung    746:                ixv_stop(adapter);
                    747:                return;
                    748:        }
                    749:
1.26      msaitoh   750:        /* Reset VF and renegotiate mailbox API version */
1.58      msaitoh   751:        hw->mac.ops.reset_hw(hw);
1.84.2.4  pgoyette  752:        hw->mac.ops.start_hw(hw);
1.58      msaitoh   753:        error = ixv_negotiate_api(adapter);
1.26      msaitoh   754:        if (error)
1.58      msaitoh   755:                device_printf(dev,
                    756:                    "Mailbox API negotiation failed in init_locked!\n");
1.26      msaitoh   757:
1.1       dyoung    758:        ixv_initialize_transmit_units(adapter);
                    759:
                    760:        /* Setup Multicast table */
                    761:        ixv_set_multi(adapter);
                    762:
                    763:        /*
1.58      msaitoh   764:         * Determine the correct mbuf pool
                    765:         * for doing jumbo/headersplit
                    766:         */
1.1       dyoung    767:        if (ifp->if_mtu > ETHERMTU)
                    768:                adapter->rx_mbuf_sz = MJUMPAGESIZE;
                    769:        else
                    770:                adapter->rx_mbuf_sz = MCLBYTES;
                    771:
                    772:        /* Prepare receive descriptors and buffers */
1.21      msaitoh   773:        if (ixgbe_setup_receive_structures(adapter)) {
1.26      msaitoh   774:                device_printf(dev, "Could not setup receive structures\n");
1.1       dyoung    775:                ixv_stop(adapter);
                    776:                return;
                    777:        }
                    778:
                    779:        /* Configure RX settings */
                    780:        ixv_initialize_receive_units(adapter);
                    781:
1.3       msaitoh   782: #if 0 /* XXX isn't it required? -- msaitoh  */
1.1       dyoung    783:        /* Set the various hardware offload abilities */
                    784:        ifp->if_hwassist = 0;
                    785:        if (ifp->if_capenable & IFCAP_TSO4)
                    786:                ifp->if_hwassist |= CSUM_TSO;
                    787:        if (ifp->if_capenable & IFCAP_TXCSUM) {
                    788:                ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
                    789: #if __FreeBSD_version >= 800000
                    790:                ifp->if_hwassist |= CSUM_SCTP;
                    791: #endif
                    792:        }
1.3       msaitoh   793: #endif
1.1       dyoung    794:
                    795:        /* Set up VLAN offload and filter */
                    796:        ixv_setup_vlan_support(adapter);
                    797:
1.58      msaitoh   798:        /* Set up MSI-X routing */
1.1       dyoung    799:        ixv_configure_ivars(adapter);
                    800:
                    801:        /* Set up auto-mask */
1.68      msaitoh   802:        mask = (1 << adapter->vector);
1.84.2.8! pgoyette  803:        for (i = 0, que = adapter->queues; i < adapter->num_queues; i++, que++)
1.68      msaitoh   804:                mask |= (1 << que->msix);
                    805:        IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, mask);
1.1       dyoung    806:
1.57      msaitoh   807:        /* Set moderation on the Link interrupt */
1.84.2.6  pgoyette  808:        ixv_eitr_write(adapter, adapter->vector, IXGBE_LINK_ITR);
1.1       dyoung    809:
                    810:        /* Stats init */
                    811:        ixv_init_stats(adapter);
                    812:
                    813:        /* Config/Enable Link */
1.62      msaitoh   814:        hw->mac.get_link_status = TRUE;
1.58      msaitoh   815:        hw->mac.ops.check_link(hw, &adapter->link_speed, &adapter->link_up,
                    816:            FALSE);
1.1       dyoung    817:
1.26      msaitoh   818:        /* Start watchdog */
                    819:        callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
                    820:
1.1       dyoung    821:        /* And now turn on interrupts */
                    822:        ixv_enable_intr(adapter);
                    823:
1.79      msaitoh   824:        /* Update saved flags. See ixgbe_ifflags_cb() */
                    825:        adapter->if_flags = ifp->if_flags;
                    826:
1.1       dyoung    827:        /* Now inform the stack we're ready */
1.3       msaitoh   828:        ifp->if_flags |= IFF_RUNNING;
                    829:        ifp->if_flags &= ~IFF_OACTIVE;
1.1       dyoung    830:
                    831:        return;
1.58      msaitoh   832: } /* ixv_init_locked */
1.1       dyoung    833:
1.84.2.1  pgoyette  834: /************************************************************************
                    835:  * ixv_enable_queue
                    836:  ************************************************************************/
1.1       dyoung    837: static inline void
                    838: ixv_enable_queue(struct adapter *adapter, u32 vector)
                    839: {
                    840:        struct ixgbe_hw *hw = &adapter->hw;
1.82      knakahar  841:        struct ix_queue *que = &adapter->queues[vector];
1.58      msaitoh   842:        u32             queue = 1 << vector;
                    843:        u32             mask;
1.1       dyoung    844:
1.84.2.3  pgoyette  845:        mutex_enter(&que->dc_mtx);
                    846:        if (que->disabled_count > 0 && --que->disabled_count > 0)
1.82      knakahar  847:                goto out;
                    848:
1.1       dyoung    849:        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                    850:        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
1.82      knakahar  851: out:
1.84.2.3  pgoyette  852:        mutex_exit(&que->dc_mtx);
1.58      msaitoh   853: } /* ixv_enable_queue */
1.1       dyoung    854:
1.84.2.1  pgoyette  855: /************************************************************************
                    856:  * ixv_disable_queue
                    857:  ************************************************************************/
1.1       dyoung    858: static inline void
                    859: ixv_disable_queue(struct adapter *adapter, u32 vector)
                    860: {
                    861:        struct ixgbe_hw *hw = &adapter->hw;
1.82      knakahar  862:        struct ix_queue *que = &adapter->queues[vector];
1.58      msaitoh   863:        u64             queue = (u64)(1 << vector);
                    864:        u32             mask;
1.1       dyoung    865:
1.84.2.3  pgoyette  866:        mutex_enter(&que->dc_mtx);
                    867:        if (que->disabled_count++ > 0)
1.82      knakahar  868:                goto  out;
                    869:
1.1       dyoung    870:        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                    871:        IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
1.82      knakahar  872: out:
1.84.2.3  pgoyette  873:        mutex_exit(&que->dc_mtx);
1.58      msaitoh   874: } /* ixv_disable_queue */
1.1       dyoung    875:
1.84.2.8! pgoyette  876: #if 0
1.1       dyoung    877: static inline void
                    878: ixv_rearm_queues(struct adapter *adapter, u64 queues)
                    879: {
                    880:        u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues);
                    881:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask);
1.58      msaitoh   882: } /* ixv_rearm_queues */
1.84.2.8! pgoyette  883: #endif
1.1       dyoung    884:
                    885:
1.58      msaitoh   886: /************************************************************************
1.84.2.4  pgoyette  887:  * ixv_msix_que - MSI-X Queue Interrupt Service routine
1.58      msaitoh   888:  ************************************************************************/
                    889: static int
1.1       dyoung    890: ixv_msix_que(void *arg)
                    891: {
                    892:        struct ix_queue *que = arg;
                    893:        struct adapter  *adapter = que->adapter;
                    894:        struct tx_ring  *txr = que->txr;
                    895:        struct rx_ring  *rxr = que->rxr;
1.21      msaitoh   896:        bool            more;
1.1       dyoung    897:        u32             newitr = 0;
                    898:
                    899:        ixv_disable_queue(adapter, que->msix);
1.21      msaitoh   900:        ++que->irqs.ev_count;
1.1       dyoung    901:
1.34      msaitoh   902: #ifdef __NetBSD__
                    903:        /* Don't run ixgbe_rxeof in interrupt context */
                    904:        more = true;
                    905: #else
1.21      msaitoh   906:        more = ixgbe_rxeof(que);
1.34      msaitoh   907: #endif
1.1       dyoung    908:
1.21      msaitoh   909:        IXGBE_TX_LOCK(txr);
                    910:        ixgbe_txeof(txr);
                    911:        IXGBE_TX_UNLOCK(txr);
1.1       dyoung    912:
                    913:        /* Do AIM now? */
                    914:
1.50      msaitoh   915:        if (adapter->enable_aim == false)
1.1       dyoung    916:                goto no_calc;
                    917:        /*
1.58      msaitoh   918:         * Do Adaptive Interrupt Moderation:
                    919:         *  - Write out last calculated setting
                    920:         *  - Calculate based on average size over
                    921:         *    the last interval.
                    922:         */
1.63      msaitoh   923:        if (que->eitr_setting)
1.84.2.6  pgoyette  924:                ixv_eitr_write(adapter, que->msix, que->eitr_setting);
1.58      msaitoh   925:
1.57      msaitoh   926:        que->eitr_setting = 0;
                    927:
                    928:        /* Idle, do nothing */
                    929:        if ((txr->bytes == 0) && (rxr->bytes == 0))
                    930:                goto no_calc;
1.1       dyoung    931:
                    932:        if ((txr->bytes) && (txr->packets))
1.57      msaitoh   933:                newitr = txr->bytes/txr->packets;
1.1       dyoung    934:        if ((rxr->bytes) && (rxr->packets))
1.58      msaitoh   935:                newitr = max(newitr, (rxr->bytes / rxr->packets));
1.1       dyoung    936:        newitr += 24; /* account for hardware frame, crc */
                    937:
                    938:        /* set an upper boundary */
                    939:        newitr = min(newitr, 3000);
                    940:
                    941:        /* Be nice to the mid range */
                    942:        if ((newitr > 300) && (newitr < 1200))
                    943:                newitr = (newitr / 3);
                    944:        else
                    945:                newitr = (newitr / 2);
                    946:
1.80      msaitoh   947:        /*
                    948:         * When RSC is used, ITR interval must be larger than RSC_DELAY.
                    949:         * Currently, we use 2us for RSC_DELAY. The minimum value is always
                    950:         * greater than 2us on 100M (and 10M?(not documented)), but it's not
                    951:         * on 1G and higher.
                    952:         */
                    953:        if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
                    954:            && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
                    955:                if (newitr < IXGBE_MIN_RSC_EITR_10G1G)
                    956:                        newitr = IXGBE_MIN_RSC_EITR_10G1G;
                    957:        }
1.58      msaitoh   958:
                    959:        /* save for next interrupt */
                    960:        que->eitr_setting = newitr;
1.1       dyoung    961:
1.57      msaitoh   962:        /* Reset state */
                    963:        txr->bytes = 0;
                    964:        txr->packets = 0;
                    965:        rxr->bytes = 0;
                    966:        rxr->packets = 0;
1.1       dyoung    967:
                    968: no_calc:
1.21      msaitoh   969:        if (more)
1.3       msaitoh   970:                softint_schedule(que->que_si);
1.58      msaitoh   971:        else /* Re-enable this interrupt */
1.1       dyoung    972:                ixv_enable_queue(adapter, que->msix);
1.58      msaitoh   973:
1.11      msaitoh   974:        return 1;
1.58      msaitoh   975: } /* ixv_msix_que */
1.1       dyoung    976:
1.58      msaitoh   977: /************************************************************************
                    978:  * ixv_msix_mbx
                    979:  ************************************************************************/
1.11      msaitoh   980: static int
1.1       dyoung    981: ixv_msix_mbx(void *arg)
                    982: {
                    983:        struct adapter  *adapter = arg;
                    984:        struct ixgbe_hw *hw = &adapter->hw;
                    985:
1.22      msaitoh   986:        ++adapter->link_irq.ev_count;
1.69      msaitoh   987:        /* NetBSD: We use auto-clear, so it's not required to write VTEICR */
1.1       dyoung    988:
                    989:        /* Link status change */
1.69      msaitoh   990:        hw->mac.get_link_status = TRUE;
                    991:        softint_schedule(adapter->link_si);
1.1       dyoung    992:
1.68      msaitoh   993:        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector));
1.57      msaitoh   994:
1.11      msaitoh   995:        return 1;
1.58      msaitoh   996: } /* ixv_msix_mbx */
1.1       dyoung    997:
1.80      msaitoh   998: static void
1.84.2.6  pgoyette  999: ixv_eitr_write(struct adapter *adapter, uint32_t index, uint32_t itr)
1.80      msaitoh  1000: {
                   1001:
                   1002:        /*
                   1003:         * Newer devices than 82598 have VF function, so this function is
                   1004:         * simple.
                   1005:         */
                   1006:        itr |= IXGBE_EITR_CNT_WDIS;
                   1007:
1.84.2.6  pgoyette 1008:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(index), itr);
1.80      msaitoh  1009: }
                   1010:
                   1011:
1.58      msaitoh  1012: /************************************************************************
                   1013:  * ixv_media_status - Media Ioctl callback
1.1       dyoung   1014:  *
1.58      msaitoh  1015:  *   Called whenever the user queries the status of
                   1016:  *   the interface using ifconfig.
                   1017:  ************************************************************************/
1.1       dyoung   1018: static void
1.63      msaitoh  1019: ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1       dyoung   1020: {
                   1021:        struct adapter *adapter = ifp->if_softc;
                   1022:
                   1023:        INIT_DEBUGOUT("ixv_media_status: begin");
1.21      msaitoh  1024:        IXGBE_CORE_LOCK(adapter);
1.1       dyoung   1025:        ixv_update_link_status(adapter);
                   1026:
                   1027:        ifmr->ifm_status = IFM_AVALID;
                   1028:        ifmr->ifm_active = IFM_ETHER;
                   1029:
                   1030:        if (!adapter->link_active) {
1.39      msaitoh  1031:                ifmr->ifm_active |= IFM_NONE;
1.21      msaitoh  1032:                IXGBE_CORE_UNLOCK(adapter);
1.1       dyoung   1033:                return;
                   1034:        }
                   1035:
                   1036:        ifmr->ifm_status |= IFM_ACTIVE;
                   1037:
                   1038:        switch (adapter->link_speed) {
1.42      msaitoh  1039:                case IXGBE_LINK_SPEED_10GB_FULL:
                   1040:                        ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
                   1041:                        break;
1.71      msaitoh  1042:                case IXGBE_LINK_SPEED_5GB_FULL:
                   1043:                        ifmr->ifm_active |= IFM_5000_T | IFM_FDX;
                   1044:                        break;
                   1045:                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   1046:                        ifmr->ifm_active |= IFM_2500_T | IFM_FDX;
                   1047:                        break;
1.1       dyoung   1048:                case IXGBE_LINK_SPEED_1GB_FULL:
                   1049:                        ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
                   1050:                        break;
1.42      msaitoh  1051:                case IXGBE_LINK_SPEED_100_FULL:
                   1052:                        ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
1.1       dyoung   1053:                        break;
1.58      msaitoh  1054:                case IXGBE_LINK_SPEED_10_FULL:
                   1055:                        ifmr->ifm_active |= IFM_10_T | IFM_FDX;
                   1056:                        break;
1.1       dyoung   1057:        }
                   1058:
1.70      msaitoh  1059:        ifp->if_baudrate = ifmedia_baudrate(ifmr->ifm_active);
                   1060:
1.21      msaitoh  1061:        IXGBE_CORE_UNLOCK(adapter);
1.58      msaitoh  1062: } /* ixv_media_status */
1.1       dyoung   1063:
1.58      msaitoh  1064: /************************************************************************
                   1065:  * ixv_media_change - Media Ioctl callback
1.1       dyoung   1066:  *
1.58      msaitoh  1067:  *   Called when the user changes speed/duplex using
                   1068:  *   media/mediopt option with ifconfig.
                   1069:  ************************************************************************/
1.1       dyoung   1070: static int
1.57      msaitoh  1071: ixv_media_change(struct ifnet *ifp)
1.1       dyoung   1072: {
                   1073:        struct adapter *adapter = ifp->if_softc;
                   1074:        struct ifmedia *ifm = &adapter->media;
                   1075:
                   1076:        INIT_DEBUGOUT("ixv_media_change: begin");
                   1077:
                   1078:        if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
                   1079:                return (EINVAL);
                   1080:
1.57      msaitoh  1081:        switch (IFM_SUBTYPE(ifm->ifm_media)) {
                   1082:        case IFM_AUTO:
                   1083:                break;
                   1084:        default:
                   1085:                device_printf(adapter->dev, "Only auto media type\n");
1.1       dyoung   1086:                return (EINVAL);
1.57      msaitoh  1087:        }
1.1       dyoung   1088:
                   1089:        return (0);
1.58      msaitoh  1090: } /* ixv_media_change */
1.1       dyoung   1091:
                   1092:
1.58      msaitoh  1093: /************************************************************************
                   1094:  * ixv_negotiate_api
1.1       dyoung   1095:  *
1.58      msaitoh  1096:  *   Negotiate the Mailbox API with the PF;
                   1097:  *   start with the most featured API first.
                   1098:  ************************************************************************/
                   1099: static int
                   1100: ixv_negotiate_api(struct adapter *adapter)
                   1101: {
                   1102:        struct ixgbe_hw *hw = &adapter->hw;
                   1103:        int             mbx_api[] = { ixgbe_mbox_api_11,
                   1104:                                      ixgbe_mbox_api_10,
                   1105:                                      ixgbe_mbox_api_unknown };
                   1106:        int             i = 0;
                   1107:
                   1108:        while (mbx_api[i] != ixgbe_mbox_api_unknown) {
                   1109:                if (ixgbevf_negotiate_api_version(hw, mbx_api[i]) == 0)
                   1110:                        return (0);
                   1111:                i++;
                   1112:        }
                   1113:
                   1114:        return (EINVAL);
                   1115: } /* ixv_negotiate_api */
                   1116:
                   1117:
                   1118: /************************************************************************
                   1119:  * ixv_set_multi - Multicast Update
1.1       dyoung   1120:  *
1.58      msaitoh  1121:  *   Called whenever multicast address list is updated.
                   1122:  ************************************************************************/
1.1       dyoung   1123: static void
                   1124: ixv_set_multi(struct adapter *adapter)
                   1125: {
1.3       msaitoh  1126:        struct ether_multi *enm;
                   1127:        struct ether_multistep step;
1.58      msaitoh  1128:        struct ethercom *ec = &adapter->osdep.ec;
1.1       dyoung   1129:        u8      mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
1.58      msaitoh  1130:        u8                 *update_ptr;
                   1131:        int                mcnt = 0;
1.1       dyoung   1132:
1.72      msaitoh  1133:        KASSERT(mutex_owned(&adapter->core_mtx));
1.1       dyoung   1134:        IOCTL_DEBUGOUT("ixv_set_multi: begin");
                   1135:
1.72      msaitoh  1136:        ETHER_LOCK(ec);
1.3       msaitoh  1137:        ETHER_FIRST_MULTI(step, ec, enm);
                   1138:        while (enm != NULL) {
                   1139:                bcopy(enm->enm_addrlo,
1.1       dyoung   1140:                    &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
                   1141:                    IXGBE_ETH_LENGTH_OF_ADDRESS);
                   1142:                mcnt++;
1.3       msaitoh  1143:                /* XXX This might be required --msaitoh */
                   1144:                if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES)
                   1145:                        break;
                   1146:                ETHER_NEXT_MULTI(step, enm);
1.1       dyoung   1147:        }
1.72      msaitoh  1148:        ETHER_UNLOCK(ec);
1.1       dyoung   1149:
                   1150:        update_ptr = mta;
                   1151:
1.58      msaitoh  1152:        adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
                   1153:            ixv_mc_array_itr, TRUE);
                   1154: } /* ixv_set_multi */
1.1       dyoung   1155:
1.58      msaitoh  1156: /************************************************************************
                   1157:  * ixv_mc_array_itr
                   1158:  *
                   1159:  *   An iterator function needed by the multicast shared code.
                   1160:  *   It feeds the shared code routine the addresses in the
                   1161:  *   array of ixv_set_multi() one by one.
                   1162:  ************************************************************************/
1.1       dyoung   1163: static u8 *
                   1164: ixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
                   1165: {
                   1166:        u8 *addr = *update_ptr;
                   1167:        u8 *newptr;
1.84.2.1  pgoyette 1168:
1.1       dyoung   1169:        *vmdq = 0;
                   1170:
                   1171:        newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS;
                   1172:        *update_ptr = newptr;
1.57      msaitoh  1173:
1.1       dyoung   1174:        return addr;
1.58      msaitoh  1175: } /* ixv_mc_array_itr */
1.1       dyoung   1176:
1.58      msaitoh  1177: /************************************************************************
                   1178:  * ixv_local_timer - Timer routine
1.1       dyoung   1179:  *
1.58      msaitoh  1180:  *   Checks for link status, updates statistics,
                   1181:  *   and runs the watchdog check.
                   1182:  ************************************************************************/
1.1       dyoung   1183: static void
1.22      msaitoh  1184: ixv_local_timer(void *arg)
                   1185: {
                   1186:        struct adapter *adapter = arg;
                   1187:
                   1188:        IXGBE_CORE_LOCK(adapter);
                   1189:        ixv_local_timer_locked(adapter);
                   1190:        IXGBE_CORE_UNLOCK(adapter);
                   1191: }
                   1192:
                   1193: static void
                   1194: ixv_local_timer_locked(void *arg)
1.1       dyoung   1195: {
                   1196:        struct adapter  *adapter = arg;
                   1197:        device_t        dev = adapter->dev;
1.22      msaitoh  1198:        struct ix_queue *que = adapter->queues;
1.21      msaitoh  1199:        u64             queues = 0;
1.84.2.1  pgoyette 1200:        u64             v0, v1, v2, v3, v4, v5, v6, v7;
1.21      msaitoh  1201:        int             hung = 0;
1.84.2.1  pgoyette 1202:        int             i;
1.1       dyoung   1203:
1.3       msaitoh  1204:        KASSERT(mutex_owned(&adapter->core_mtx));
1.1       dyoung   1205:
1.58      msaitoh  1206:        ixv_check_link(adapter);
1.1       dyoung   1207:
                   1208:        /* Stats Update */
                   1209:        ixv_update_stats(adapter);
                   1210:
1.84.2.1  pgoyette 1211:        /* Update some event counters */
                   1212:        v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = 0;
                   1213:        que = adapter->queues;
                   1214:        for (i = 0; i < adapter->num_queues; i++, que++) {
                   1215:                struct tx_ring  *txr = que->txr;
                   1216:
                   1217:                v0 += txr->q_efbig_tx_dma_setup;
                   1218:                v1 += txr->q_mbuf_defrag_failed;
                   1219:                v2 += txr->q_efbig2_tx_dma_setup;
                   1220:                v3 += txr->q_einval_tx_dma_setup;
                   1221:                v4 += txr->q_other_tx_dma_setup;
                   1222:                v5 += txr->q_eagain_tx_dma_setup;
                   1223:                v6 += txr->q_enomem_tx_dma_setup;
                   1224:                v7 += txr->q_tso_err;
                   1225:        }
                   1226:        adapter->efbig_tx_dma_setup.ev_count = v0;
                   1227:        adapter->mbuf_defrag_failed.ev_count = v1;
                   1228:        adapter->efbig2_tx_dma_setup.ev_count = v2;
                   1229:        adapter->einval_tx_dma_setup.ev_count = v3;
                   1230:        adapter->other_tx_dma_setup.ev_count = v4;
                   1231:        adapter->eagain_tx_dma_setup.ev_count = v5;
                   1232:        adapter->enomem_tx_dma_setup.ev_count = v6;
                   1233:        adapter->tso_err.ev_count = v7;
                   1234:
1.1       dyoung   1235:        /*
1.58      msaitoh  1236:         * Check the TX queues status
                   1237:         *      - mark hung queues so we don't schedule on them
                   1238:         *      - watchdog only if all queues show hung
                   1239:         */
1.84.2.1  pgoyette 1240:        que = adapter->queues;
                   1241:        for (i = 0; i < adapter->num_queues; i++, que++) {
1.21      msaitoh  1242:                /* Keep track of queues with work for soft irq */
                   1243:                if (que->txr->busy)
                   1244:                        queues |= ((u64)1 << que->me);
                   1245:                /*
1.58      msaitoh  1246:                 * Each time txeof runs without cleaning, but there
                   1247:                 * are uncleaned descriptors it increments busy. If
                   1248:                 * we get to the MAX we declare it hung.
                   1249:                 */
1.21      msaitoh  1250:                if (que->busy == IXGBE_QUEUE_HUNG) {
                   1251:                        ++hung;
                   1252:                        /* Mark the queue as inactive */
                   1253:                        adapter->active_queues &= ~((u64)1 << que->me);
1.22      msaitoh  1254:                        continue;
1.21      msaitoh  1255:                } else {
                   1256:                        /* Check if we've come back from hung */
                   1257:                        if ((adapter->active_queues & ((u64)1 << que->me)) == 0)
1.57      msaitoh  1258:                                adapter->active_queues |= ((u64)1 << que->me);
1.22      msaitoh  1259:                }
1.21      msaitoh  1260:                if (que->busy >= IXGBE_MAX_TX_BUSY) {
1.58      msaitoh  1261:                        device_printf(dev,
                   1262:                            "Warning queue %d appears to be hung!\n", i);
1.21      msaitoh  1263:                        que->txr->busy = IXGBE_QUEUE_HUNG;
                   1264:                        ++hung;
1.1       dyoung   1265:                }
1.21      msaitoh  1266:        }
                   1267:
1.29      msaitoh  1268:        /* Only truly watchdog if all queues show hung */
1.21      msaitoh  1269:        if (hung == adapter->num_queues)
                   1270:                goto watchdog;
1.84.2.8! pgoyette 1271: #if 0
1.21      msaitoh  1272:        else if (queues != 0) { /* Force an IRQ on queues with work */
                   1273:                ixv_rearm_queues(adapter, queues);
1.1       dyoung   1274:        }
1.84.2.8! pgoyette 1275: #endif
1.21      msaitoh  1276:
1.1       dyoung   1277:        callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
1.57      msaitoh  1278:
1.1       dyoung   1279:        return;
                   1280:
1.21      msaitoh  1281: watchdog:
1.57      msaitoh  1282:
1.1       dyoung   1283:        device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
1.3       msaitoh  1284:        adapter->ifp->if_flags &= ~IFF_RUNNING;
                   1285:        adapter->watchdog_events.ev_count++;
1.1       dyoung   1286:        ixv_init_locked(adapter);
1.58      msaitoh  1287: } /* ixv_local_timer */
1.1       dyoung   1288:
1.58      msaitoh  1289: /************************************************************************
                   1290:  * ixv_update_link_status - Update OS on link state
                   1291:  *
                   1292:  * Note: Only updates the OS on the cached link state.
                   1293:  *       The real check of the hardware only happens with
                   1294:  *       a link interrupt.
                   1295:  ************************************************************************/
1.1       dyoung   1296: static void
                   1297: ixv_update_link_status(struct adapter *adapter)
                   1298: {
1.58      msaitoh  1299:        struct ifnet *ifp = adapter->ifp;
                   1300:        device_t     dev = adapter->dev;
1.1       dyoung   1301:
1.84.2.2  pgoyette 1302:        KASSERT(mutex_owned(&adapter->core_mtx));
                   1303:
1.57      msaitoh  1304:        if (adapter->link_up) {
1.1       dyoung   1305:                if (adapter->link_active == FALSE) {
1.42      msaitoh  1306:                        if (bootverbose) {
                   1307:                                const char *bpsmsg;
                   1308:
                   1309:                                switch (adapter->link_speed) {
                   1310:                                case IXGBE_LINK_SPEED_10GB_FULL:
                   1311:                                        bpsmsg = "10 Gbps";
                   1312:                                        break;
1.58      msaitoh  1313:                                case IXGBE_LINK_SPEED_5GB_FULL:
                   1314:                                        bpsmsg = "5 Gbps";
                   1315:                                        break;
                   1316:                                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   1317:                                        bpsmsg = "2.5 Gbps";
                   1318:                                        break;
1.42      msaitoh  1319:                                case IXGBE_LINK_SPEED_1GB_FULL:
                   1320:                                        bpsmsg = "1 Gbps";
                   1321:                                        break;
                   1322:                                case IXGBE_LINK_SPEED_100_FULL:
                   1323:                                        bpsmsg = "100 Mbps";
                   1324:                                        break;
1.58      msaitoh  1325:                                case IXGBE_LINK_SPEED_10_FULL:
                   1326:                                        bpsmsg = "10 Mbps";
                   1327:                                        break;
1.42      msaitoh  1328:                                default:
                   1329:                                        bpsmsg = "unknown speed";
                   1330:                                        break;
                   1331:                                }
1.63      msaitoh  1332:                                device_printf(dev, "Link is up %s %s \n",
1.42      msaitoh  1333:                                    bpsmsg, "Full Duplex");
                   1334:                        }
1.1       dyoung   1335:                        adapter->link_active = TRUE;
                   1336:                        if_link_state_change(ifp, LINK_STATE_UP);
                   1337:                }
                   1338:        } else { /* Link down */
                   1339:                if (adapter->link_active == TRUE) {
                   1340:                        if (bootverbose)
1.63      msaitoh  1341:                                device_printf(dev, "Link is Down\n");
1.1       dyoung   1342:                        if_link_state_change(ifp, LINK_STATE_DOWN);
                   1343:                        adapter->link_active = FALSE;
                   1344:                }
                   1345:        }
1.58      msaitoh  1346: } /* ixv_update_link_status */
1.1       dyoung   1347:
                   1348:
1.58      msaitoh  1349: /************************************************************************
                   1350:  * ixv_stop - Stop the hardware
                   1351:  *
                   1352:  *   Disables all traffic on the adapter by issuing a
                   1353:  *   global reset on the MAC and deallocates TX/RX buffers.
                   1354:  ************************************************************************/
1.3       msaitoh  1355: static void
                   1356: ixv_ifstop(struct ifnet *ifp, int disable)
                   1357: {
                   1358:        struct adapter *adapter = ifp->if_softc;
                   1359:
1.21      msaitoh  1360:        IXGBE_CORE_LOCK(adapter);
1.3       msaitoh  1361:        ixv_stop(adapter);
1.21      msaitoh  1362:        IXGBE_CORE_UNLOCK(adapter);
1.3       msaitoh  1363: }
                   1364:
1.1       dyoung   1365: static void
                   1366: ixv_stop(void *arg)
                   1367: {
1.58      msaitoh  1368:        struct ifnet    *ifp;
                   1369:        struct adapter  *adapter = arg;
1.1       dyoung   1370:        struct ixgbe_hw *hw = &adapter->hw;
1.58      msaitoh  1371:
1.1       dyoung   1372:        ifp = adapter->ifp;
                   1373:
1.3       msaitoh  1374:        KASSERT(mutex_owned(&adapter->core_mtx));
1.1       dyoung   1375:
                   1376:        INIT_DEBUGOUT("ixv_stop: begin\n");
                   1377:        ixv_disable_intr(adapter);
                   1378:
                   1379:        /* Tell the stack that the interface is no longer active */
1.3       msaitoh  1380:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1.1       dyoung   1381:
1.58      msaitoh  1382:        hw->mac.ops.reset_hw(hw);
1.1       dyoung   1383:        adapter->hw.adapter_stopped = FALSE;
1.58      msaitoh  1384:        hw->mac.ops.stop_adapter(hw);
1.1       dyoung   1385:        callout_stop(&adapter->timer);
                   1386:
                   1387:        /* reprogram the RAR[0] in case user changed it. */
1.58      msaitoh  1388:        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1.1       dyoung   1389:
                   1390:        return;
1.58      msaitoh  1391: } /* ixv_stop */
1.1       dyoung   1392:
                   1393:
1.58      msaitoh  1394: /************************************************************************
                   1395:  * ixv_allocate_pci_resources
                   1396:  ************************************************************************/
1.57      msaitoh  1397: static int
                   1398: ixv_allocate_pci_resources(struct adapter *adapter,
                   1399:     const struct pci_attach_args *pa)
1.1       dyoung   1400: {
1.57      msaitoh  1401:        pcireg_t        memtype;
                   1402:        device_t        dev = adapter->dev;
                   1403:        bus_addr_t addr;
                   1404:        int flags;
1.3       msaitoh  1405:
1.57      msaitoh  1406:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR(0));
                   1407:        switch (memtype) {
                   1408:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                   1409:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                   1410:                adapter->osdep.mem_bus_space_tag = pa->pa_memt;
                   1411:                if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_BAR(0),
                   1412:                      memtype, &addr, &adapter->osdep.mem_size, &flags) != 0)
                   1413:                        goto map_err;
                   1414:                if ((flags & BUS_SPACE_MAP_PREFETCHABLE) != 0) {
                   1415:                        aprint_normal_dev(dev, "clearing prefetchable bit\n");
                   1416:                        flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
                   1417:                }
                   1418:                if (bus_space_map(adapter->osdep.mem_bus_space_tag, addr,
                   1419:                     adapter->osdep.mem_size, flags,
1.3       msaitoh  1420:                     &adapter->osdep.mem_bus_space_handle) != 0) {
                   1421: map_err:
                   1422:                        adapter->osdep.mem_size = 0;
                   1423:                        aprint_error_dev(dev, "unable to map BAR0\n");
                   1424:                        return ENXIO;
                   1425:                }
                   1426:                break;
                   1427:        default:
                   1428:                aprint_error_dev(dev, "unexpected type on BAR0\n");
                   1429:                return ENXIO;
1.1       dyoung   1430:        }
                   1431:
1.23      msaitoh  1432:        /* Pick up the tuneable queues */
                   1433:        adapter->num_queues = ixv_num_queues;
1.1       dyoung   1434:
1.58      msaitoh  1435:        return (0);
                   1436: } /* ixv_allocate_pci_resources */
1.1       dyoung   1437:
1.58      msaitoh  1438: /************************************************************************
                   1439:  * ixv_free_pci_resources
                   1440:  ************************************************************************/
1.1       dyoung   1441: static void
                   1442: ixv_free_pci_resources(struct adapter * adapter)
                   1443: {
                   1444:        struct          ix_queue *que = adapter->queues;
1.11      msaitoh  1445:        int             rid;
1.1       dyoung   1446:
                   1447:        /*
1.58      msaitoh  1448:         *  Release all msix queue resources:
                   1449:         */
1.1       dyoung   1450:        for (int i = 0; i < adapter->num_queues; i++, que++) {
                   1451:                if (que->res != NULL)
1.11      msaitoh  1452:                        pci_intr_disestablish(adapter->osdep.pc,
                   1453:                            adapter->osdep.ihs[i]);
1.1       dyoung   1454:        }
                   1455:
1.12      msaitoh  1456:
1.58      msaitoh  1457:        /* Clean the Mailbox interrupt last */
1.49      msaitoh  1458:        rid = adapter->vector;
1.1       dyoung   1459:
1.41      msaitoh  1460:        if (adapter->osdep.ihs[rid] != NULL) {
1.11      msaitoh  1461:                pci_intr_disestablish(adapter->osdep.pc,
                   1462:                    adapter->osdep.ihs[rid]);
1.41      msaitoh  1463:                adapter->osdep.ihs[rid] = NULL;
                   1464:        }
1.11      msaitoh  1465:
                   1466:        pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs,
                   1467:            adapter->osdep.nintrs);
                   1468:
                   1469:        if (adapter->osdep.mem_size != 0) {
                   1470:                bus_space_unmap(adapter->osdep.mem_bus_space_tag,
                   1471:                    adapter->osdep.mem_bus_space_handle,
                   1472:                    adapter->osdep.mem_size);
                   1473:        }
1.1       dyoung   1474:
                   1475:        return;
1.58      msaitoh  1476: } /* ixv_free_pci_resources */
1.1       dyoung   1477:
1.58      msaitoh  1478: /************************************************************************
                   1479:  * ixv_setup_interface
1.1       dyoung   1480:  *
1.58      msaitoh  1481:  *   Setup networking device structure and register an interface.
                   1482:  ************************************************************************/
1.73      msaitoh  1483: static int
1.1       dyoung   1484: ixv_setup_interface(device_t dev, struct adapter *adapter)
                   1485: {
1.3       msaitoh  1486:        struct ethercom *ec = &adapter->osdep.ec;
1.1       dyoung   1487:        struct ifnet   *ifp;
1.73      msaitoh  1488:        int rv;
1.1       dyoung   1489:
                   1490:        INIT_DEBUGOUT("ixv_setup_interface: begin");
                   1491:
1.3       msaitoh  1492:        ifp = adapter->ifp = &ec->ec_if;
                   1493:        strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ);
1.46      msaitoh  1494:        ifp->if_baudrate = IF_Gbps(10);
1.1       dyoung   1495:        ifp->if_init = ixv_init;
1.3       msaitoh  1496:        ifp->if_stop = ixv_ifstop;
1.1       dyoung   1497:        ifp->if_softc = adapter;
                   1498:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1.55      msaitoh  1499: #ifdef IXGBE_MPSAFE
1.74      ozaki-r  1500:        ifp->if_extflags = IFEF_MPSAFE;
1.55      msaitoh  1501: #endif
1.1       dyoung   1502:        ifp->if_ioctl = ixv_ioctl;
1.58      msaitoh  1503:        if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) {
                   1504: #if 0
                   1505:                ixv_start_locked = ixgbe_legacy_start_locked;
                   1506: #endif
                   1507:        } else {
                   1508:                ifp->if_transmit = ixgbe_mq_start;
                   1509: #if 0
                   1510:                ixv_start_locked = ixgbe_mq_start_locked;
1.35      msaitoh  1511: #endif
1.58      msaitoh  1512:        }
                   1513:        ifp->if_start = ixgbe_legacy_start;
1.45      msaitoh  1514:        IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
                   1515:        IFQ_SET_READY(&ifp->if_snd);
1.1       dyoung   1516:
1.73      msaitoh  1517:        rv = if_initialize(ifp);
                   1518:        if (rv != 0) {
                   1519:                aprint_error_dev(dev, "if_initialize failed(%d)\n", rv);
                   1520:                return rv;
                   1521:        }
1.52      msaitoh  1522:        adapter->ipq = if_percpuq_create(&adapter->osdep.ec.ec_if);
1.1       dyoung   1523:        ether_ifattach(ifp, adapter->hw.mac.addr);
1.51      msaitoh  1524:        /*
                   1525:         * We use per TX queue softint, so if_deferred_start_init() isn't
                   1526:         * used.
                   1527:         */
1.3       msaitoh  1528:        ether_set_ifflags_cb(ec, ixv_ifflags_cb);
1.1       dyoung   1529:
1.58      msaitoh  1530:        adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR;
1.1       dyoung   1531:
                   1532:        /*
                   1533:         * Tell the upper layer(s) we support long frames.
                   1534:         */
1.3       msaitoh  1535:        ifp->if_hdrlen = sizeof(struct ether_vlan_header);
                   1536:
1.58      msaitoh  1537:        /* Set capability flags */
                   1538:        ifp->if_capabilities |= IFCAP_HWCSUM
                   1539:                             |  IFCAP_TSOv4
                   1540:                             |  IFCAP_TSOv6;
1.3       msaitoh  1541:        ifp->if_capenable = 0;
1.1       dyoung   1542:
1.4       msaitoh  1543:        ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING
1.58      msaitoh  1544:                            |  ETHERCAP_VLAN_HWCSUM
                   1545:                            |  ETHERCAP_JUMBO_MTU
                   1546:                            |  ETHERCAP_VLAN_MTU;
                   1547:
                   1548:        /* Enable the above capabilities by default */
1.3       msaitoh  1549:        ec->ec_capenable = ec->ec_capabilities;
1.1       dyoung   1550:
1.3       msaitoh  1551:        /* Don't enable LRO by default */
                   1552:        ifp->if_capabilities |= IFCAP_LRO;
1.21      msaitoh  1553: #if 0
                   1554:        ifp->if_capenable = ifp->if_capabilities;
                   1555: #endif
1.3       msaitoh  1556:
                   1557:        /*
1.1       dyoung   1558:         * Specify the media types supported by this adapter and register
                   1559:         * callbacks to update media and link information
                   1560:         */
                   1561:        ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change,
1.57      msaitoh  1562:            ixv_media_status);
1.1       dyoung   1563:        ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
                   1564:        ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
                   1565:
1.84.2.8! pgoyette 1566:        if_register(ifp);
        !          1567:
1.73      msaitoh  1568:        return 0;
1.58      msaitoh  1569: } /* ixv_setup_interface */
                   1570:
                   1571:
                   1572: /************************************************************************
                   1573:  * ixv_initialize_transmit_units - Enable transmit unit.
                   1574:  ************************************************************************/
1.21      msaitoh  1575: static void
                   1576: ixv_initialize_transmit_units(struct adapter *adapter)
1.1       dyoung   1577: {
1.21      msaitoh  1578:        struct tx_ring  *txr = adapter->tx_rings;
                   1579:        struct ixgbe_hw *hw = &adapter->hw;
1.84.2.4  pgoyette 1580:        int i;
1.1       dyoung   1581:
1.84.2.4  pgoyette 1582:        for (i = 0; i < adapter->num_queues; i++, txr++) {
1.58      msaitoh  1583:                u64 tdba = txr->txdma.dma_paddr;
                   1584:                u32 txctrl, txdctl;
1.84.2.4  pgoyette 1585:                int j = txr->me;
1.1       dyoung   1586:
1.21      msaitoh  1587:                /* Set WTHRESH to 8, burst writeback */
1.84.2.4  pgoyette 1588:                txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
1.21      msaitoh  1589:                txdctl |= (8 << 16);
1.84.2.4  pgoyette 1590:                IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
1.1       dyoung   1591:
1.21      msaitoh  1592:                /* Set the HW Tx Head and Tail indices */
1.84.2.4  pgoyette 1593:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(j), 0);
                   1594:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(j), 0);
1.1       dyoung   1595:
1.21      msaitoh  1596:                /* Set Tx Tail register */
1.84.2.4  pgoyette 1597:                txr->tail = IXGBE_VFTDT(j);
1.1       dyoung   1598:
1.84.2.8! pgoyette 1599:                txr->txr_no_space = false;
        !          1600:
1.21      msaitoh  1601:                /* Set Ring parameters */
1.84.2.4  pgoyette 1602:                IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(j),
1.57      msaitoh  1603:                    (tdba & 0x00000000ffffffffULL));
1.84.2.4  pgoyette 1604:                IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(j), (tdba >> 32));
                   1605:                IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(j),
1.58      msaitoh  1606:                    adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc));
1.84.2.4  pgoyette 1607:                txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(j));
1.21      msaitoh  1608:                txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
1.84.2.4  pgoyette 1609:                IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(j), txctrl);
1.1       dyoung   1610:
1.21      msaitoh  1611:                /* Now enable */
1.84.2.4  pgoyette 1612:                txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
1.21      msaitoh  1613:                txdctl |= IXGBE_TXDCTL_ENABLE;
1.84.2.4  pgoyette 1614:                IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
1.1       dyoung   1615:        }
                   1616:
1.21      msaitoh  1617:        return;
1.58      msaitoh  1618: } /* ixv_initialize_transmit_units */
                   1619:
                   1620:
                   1621: /************************************************************************
                   1622:  * ixv_initialize_rss_mapping
                   1623:  ************************************************************************/
                   1624: static void
                   1625: ixv_initialize_rss_mapping(struct adapter *adapter)
                   1626: {
                   1627:        struct ixgbe_hw *hw = &adapter->hw;
                   1628:        u32             reta = 0, mrqc, rss_key[10];
                   1629:        int             queue_id;
                   1630:        int             i, j;
                   1631:        u32             rss_hash_config;
                   1632:
1.78      knakahar 1633:        /* force use default RSS key. */
                   1634: #ifdef __NetBSD__
                   1635:        rss_getkey((uint8_t *) &rss_key);
                   1636: #else
1.58      msaitoh  1637:        if (adapter->feat_en & IXGBE_FEATURE_RSS) {
                   1638:                /* Fetch the configured RSS key */
                   1639:                rss_getkey((uint8_t *)&rss_key);
                   1640:        } else {
                   1641:                /* set up random bits */
                   1642:                cprng_fast(&rss_key, sizeof(rss_key));
                   1643:        }
1.78      knakahar 1644: #endif
1.58      msaitoh  1645:
                   1646:        /* Now fill out hash function seeds */
                   1647:        for (i = 0; i < 10; i++)
                   1648:                IXGBE_WRITE_REG(hw, IXGBE_VFRSSRK(i), rss_key[i]);
                   1649:
                   1650:        /* Set up the redirection table */
                   1651:        for (i = 0, j = 0; i < 64; i++, j++) {
                   1652:                if (j == adapter->num_queues)
                   1653:                        j = 0;
1.1       dyoung   1654:
1.58      msaitoh  1655:                if (adapter->feat_en & IXGBE_FEATURE_RSS) {
                   1656:                        /*
                   1657:                         * Fetch the RSS bucket id for the given indirection
                   1658:                         * entry. Cap it at the number of configured buckets
                   1659:                         * (which is num_queues.)
                   1660:                         */
                   1661:                        queue_id = rss_get_indirection_to_bucket(i);
                   1662:                        queue_id = queue_id % adapter->num_queues;
                   1663:                } else
                   1664:                        queue_id = j;
1.1       dyoung   1665:
1.58      msaitoh  1666:                /*
                   1667:                 * The low 8 bits are for hash value (n+0);
                   1668:                 * The next 8 bits are for hash value (n+1), etc.
                   1669:                 */
                   1670:                reta >>= 8;
                   1671:                reta |= ((uint32_t)queue_id) << 24;
                   1672:                if ((i & 3) == 3) {
                   1673:                        IXGBE_WRITE_REG(hw, IXGBE_VFRETA(i >> 2), reta);
                   1674:                        reta = 0;
                   1675:                }
                   1676:        }
1.21      msaitoh  1677:
1.58      msaitoh  1678:        /* Perform hash on these packet types */
                   1679:        if (adapter->feat_en & IXGBE_FEATURE_RSS)
                   1680:                rss_hash_config = rss_gethashconfig();
                   1681:        else {
                   1682:                /*
                   1683:                 * Disable UDP - IP fragments aren't currently being handled
                   1684:                 * and so we end up with a mix of 2-tuple and 4-tuple
                   1685:                 * traffic.
                   1686:                 */
                   1687:                rss_hash_config = RSS_HASHTYPE_RSS_IPV4
                   1688:                                | RSS_HASHTYPE_RSS_TCP_IPV4
                   1689:                                | RSS_HASHTYPE_RSS_IPV6
                   1690:                                | RSS_HASHTYPE_RSS_TCP_IPV6;
                   1691:        }
                   1692:
                   1693:        mrqc = IXGBE_MRQC_RSSEN;
                   1694:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
                   1695:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4;
                   1696:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
                   1697:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP;
                   1698:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
                   1699:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6;
                   1700:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
                   1701:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
                   1702:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
                   1703:                device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_IPV6_EX defined, but not supported\n",
                   1704:                    __func__);
                   1705:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX)
                   1706:                device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_TCP_IPV6_EX defined, but not supported\n",
                   1707:                    __func__);
                   1708:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
                   1709:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
                   1710:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
                   1711:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
                   1712:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX)
                   1713:                device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV6_EX defined, but not supported\n",
                   1714:                    __func__);
                   1715:        IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, mrqc);
                   1716: } /* ixv_initialize_rss_mapping */
                   1717:
                   1718:
                   1719: /************************************************************************
                   1720:  * ixv_initialize_receive_units - Setup receive registers and features.
                   1721:  ************************************************************************/
1.21      msaitoh  1722: static void
                   1723: ixv_initialize_receive_units(struct adapter *adapter)
1.1       dyoung   1724: {
1.21      msaitoh  1725:        struct  rx_ring *rxr = adapter->rx_rings;
                   1726:        struct ixgbe_hw *hw = &adapter->hw;
1.23      msaitoh  1727:        struct ifnet    *ifp = adapter->ifp;
                   1728:        u32             bufsz, rxcsum, psrtype;
1.1       dyoung   1729:
1.23      msaitoh  1730:        if (ifp->if_mtu > ETHERMTU)
                   1731:                bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
                   1732:        else
                   1733:                bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1.1       dyoung   1734:
1.58      msaitoh  1735:        psrtype = IXGBE_PSRTYPE_TCPHDR
                   1736:                | IXGBE_PSRTYPE_UDPHDR
                   1737:                | IXGBE_PSRTYPE_IPV4HDR
                   1738:                | IXGBE_PSRTYPE_IPV6HDR
                   1739:                | IXGBE_PSRTYPE_L2HDR;
                   1740:
                   1741:        if (adapter->num_queues > 1)
                   1742:                psrtype |= 1 << 29;
1.1       dyoung   1743:
1.23      msaitoh  1744:        IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
                   1745:
1.26      msaitoh  1746:        /* Tell PF our max_frame size */
1.58      msaitoh  1747:        if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) {
                   1748:                device_printf(adapter->dev, "There is a problem with the PF setup.  It is likely the receive unit for this VF will not function correctly.\n");
                   1749:        }
1.1       dyoung   1750:
1.23      msaitoh  1751:        for (int i = 0; i < adapter->num_queues; i++, rxr++) {
1.1       dyoung   1752:                u64 rdba = rxr->rxdma.dma_paddr;
                   1753:                u32 reg, rxdctl;
1.84.2.4  pgoyette 1754:                int j = rxr->me;
1.1       dyoung   1755:
1.23      msaitoh  1756:                /* Disable the queue */
1.84.2.4  pgoyette 1757:                rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j));
1.28      msaitoh  1758:                rxdctl &= ~IXGBE_RXDCTL_ENABLE;
1.84.2.4  pgoyette 1759:                IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl);
                   1760:                for (int k = 0; k < 10; k++) {
                   1761:                        if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) &
1.23      msaitoh  1762:                            IXGBE_RXDCTL_ENABLE)
                   1763:                                msec_delay(1);
                   1764:                        else
                   1765:                                break;
                   1766:                }
                   1767:                wmb();
1.1       dyoung   1768:                /* Setup the Base and Length of the Rx Descriptor Ring */
1.84.2.4  pgoyette 1769:                IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(j),
1.1       dyoung   1770:                    (rdba & 0x00000000ffffffffULL));
1.84.2.4  pgoyette 1771:                IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(j), (rdba >> 32));
                   1772:                IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(j),
1.1       dyoung   1773:                    adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
                   1774:
1.23      msaitoh  1775:                /* Reset the ring indices */
                   1776:                IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0);
                   1777:                IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0);
                   1778:
1.1       dyoung   1779:                /* Set up the SRRCTL register */
1.84.2.4  pgoyette 1780:                reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(j));
1.1       dyoung   1781:                reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
                   1782:                reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
                   1783:                reg |= bufsz;
1.21      msaitoh  1784:                reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
1.84.2.4  pgoyette 1785:                IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(j), reg);
1.1       dyoung   1786:
1.23      msaitoh  1787:                /* Capture Rx Tail index */
1.21      msaitoh  1788:                rxr->tail = IXGBE_VFRDT(rxr->me);
                   1789:
                   1790:                /* Do the queue enabling last */
1.28      msaitoh  1791:                rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME;
1.84.2.4  pgoyette 1792:                IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl);
1.21      msaitoh  1793:                for (int k = 0; k < 10; k++) {
1.84.2.4  pgoyette 1794:                        if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) &
1.21      msaitoh  1795:                            IXGBE_RXDCTL_ENABLE)
                   1796:                                break;
1.58      msaitoh  1797:                        msec_delay(1);
1.21      msaitoh  1798:                }
                   1799:                wmb();
1.24      msaitoh  1800:
                   1801:                /* Set the Tail Pointer */
1.84.2.1  pgoyette 1802: #ifdef DEV_NETMAP
1.25      msaitoh  1803:                /*
                   1804:                 * In netmap mode, we must preserve the buffers made
                   1805:                 * available to userspace before the if_init()
                   1806:                 * (this is true by default on the TX side, because
                   1807:                 * init makes all buffers available to userspace).
                   1808:                 *
                   1809:                 * netmap_reset() and the device specific routines
                   1810:                 * (e.g. ixgbe_setup_receive_rings()) map these
                   1811:                 * buffers at the end of the NIC ring, so here we
                   1812:                 * must set the RDT (tail) register to make sure
                   1813:                 * they are not overwritten.
                   1814:                 *
                   1815:                 * In this driver the NIC ring starts at RDH = 0,
                   1816:                 * RDT points to the last slot available for reception (?),
                   1817:                 * so RDT = num_rx_desc - 1 means the whole ring is available.
                   1818:                 */
1.58      msaitoh  1819:                if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) &&
                   1820:                    (ifp->if_capenable & IFCAP_NETMAP)) {
1.25      msaitoh  1821:                        struct netmap_adapter *na = NA(adapter->ifp);
                   1822:                        struct netmap_kring *kring = &na->rx_rings[i];
                   1823:                        int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
                   1824:
                   1825:                        IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t);
                   1826:                } else
                   1827: #endif /* DEV_NETMAP */
                   1828:                        IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
                   1829:                            adapter->num_rx_desc - 1);
1.1       dyoung   1830:        }
                   1831:
                   1832:        rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
                   1833:
1.58      msaitoh  1834:        ixv_initialize_rss_mapping(adapter);
                   1835:
                   1836:        if (adapter->num_queues > 1) {
                   1837:                /* RSS and RX IPP Checksum are mutually exclusive */
                   1838:                rxcsum |= IXGBE_RXCSUM_PCSD;
                   1839:        }
                   1840:
1.1       dyoung   1841:        if (ifp->if_capenable & IFCAP_RXCSUM)
                   1842:                rxcsum |= IXGBE_RXCSUM_PCSD;
                   1843:
                   1844:        if (!(rxcsum & IXGBE_RXCSUM_PCSD))
                   1845:                rxcsum |= IXGBE_RXCSUM_IPPCSE;
                   1846:
                   1847:        IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
1.58      msaitoh  1848: } /* ixv_initialize_receive_units */
1.1       dyoung   1849:
1.58      msaitoh  1850: /************************************************************************
1.83      msaitoh  1851:  * ixv_sysctl_tdh_handler - Transmit Descriptor Head handler function
                   1852:  *
                   1853:  *   Retrieves the TDH value from the hardware
                   1854:  ************************************************************************/
                   1855: static int
                   1856: ixv_sysctl_tdh_handler(SYSCTLFN_ARGS)
                   1857: {
                   1858:        struct sysctlnode node = *rnode;
                   1859:        struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
                   1860:        uint32_t val;
                   1861:
                   1862:        if (!txr)
                   1863:                return (0);
                   1864:
                   1865:        val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDH(txr->me));
                   1866:        node.sysctl_data = &val;
                   1867:        return sysctl_lookup(SYSCTLFN_CALL(&node));
                   1868: } /* ixv_sysctl_tdh_handler */
                   1869:
                   1870: /************************************************************************
                   1871:  * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function
                   1872:  *
                   1873:  *   Retrieves the TDT value from the hardware
                   1874:  ************************************************************************/
                   1875: static int
                   1876: ixv_sysctl_tdt_handler(SYSCTLFN_ARGS)
                   1877: {
                   1878:        struct sysctlnode node = *rnode;
                   1879:        struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
                   1880:        uint32_t val;
                   1881:
                   1882:        if (!txr)
                   1883:                return (0);
                   1884:
                   1885:        val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDT(txr->me));
                   1886:        node.sysctl_data = &val;
                   1887:        return sysctl_lookup(SYSCTLFN_CALL(&node));
                   1888: } /* ixv_sysctl_tdt_handler */
                   1889:
                   1890: /************************************************************************
1.84.2.8! pgoyette 1891:  * ixv_sysctl_next_to_check_handler - Receive Descriptor next to check
        !          1892:  * handler function
        !          1893:  *
        !          1894:  *   Retrieves the next_to_check value
        !          1895:  ************************************************************************/
        !          1896: static int
        !          1897: ixv_sysctl_next_to_check_handler(SYSCTLFN_ARGS)
        !          1898: {
        !          1899:        struct sysctlnode node = *rnode;
        !          1900:        struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
        !          1901:        uint32_t val;
        !          1902:
        !          1903:        if (!rxr)
        !          1904:                return (0);
        !          1905:
        !          1906:        val = rxr->next_to_check;
        !          1907:        node.sysctl_data = &val;
        !          1908:        return sysctl_lookup(SYSCTLFN_CALL(&node));
        !          1909: } /* ixv_sysctl_next_to_check_handler */
        !          1910:
        !          1911: /************************************************************************
1.83      msaitoh  1912:  * ixv_sysctl_rdh_handler - Receive Descriptor Head handler function
                   1913:  *
                   1914:  *   Retrieves the RDH value from the hardware
                   1915:  ************************************************************************/
                   1916: static int
                   1917: ixv_sysctl_rdh_handler(SYSCTLFN_ARGS)
                   1918: {
                   1919:        struct sysctlnode node = *rnode;
                   1920:        struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
                   1921:        uint32_t val;
                   1922:
                   1923:        if (!rxr)
                   1924:                return (0);
                   1925:
                   1926:        val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDH(rxr->me));
                   1927:        node.sysctl_data = &val;
                   1928:        return sysctl_lookup(SYSCTLFN_CALL(&node));
                   1929: } /* ixv_sysctl_rdh_handler */
                   1930:
                   1931: /************************************************************************
                   1932:  * ixv_sysctl_rdt_handler - Receive Descriptor Tail handler function
                   1933:  *
                   1934:  *   Retrieves the RDT value from the hardware
                   1935:  ************************************************************************/
                   1936: static int
                   1937: ixv_sysctl_rdt_handler(SYSCTLFN_ARGS)
                   1938: {
                   1939:        struct sysctlnode node = *rnode;
                   1940:        struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
                   1941:        uint32_t val;
                   1942:
                   1943:        if (!rxr)
                   1944:                return (0);
                   1945:
                   1946:        val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDT(rxr->me));
                   1947:        node.sysctl_data = &val;
                   1948:        return sysctl_lookup(SYSCTLFN_CALL(&node));
                   1949: } /* ixv_sysctl_rdt_handler */
                   1950:
                   1951: /************************************************************************
1.58      msaitoh  1952:  * ixv_setup_vlan_support
                   1953:  ************************************************************************/
1.1       dyoung   1954: static void
                   1955: ixv_setup_vlan_support(struct adapter *adapter)
                   1956: {
1.65      msaitoh  1957:        struct ethercom *ec = &adapter->osdep.ec;
1.1       dyoung   1958:        struct ixgbe_hw *hw = &adapter->hw;
1.65      msaitoh  1959:        struct rx_ring  *rxr;
1.1       dyoung   1960:        u32             ctrl, vid, vfta, retry;
                   1961:
                   1962:        /*
1.58      msaitoh  1963:         * We get here thru init_locked, meaning
                   1964:         * a soft reset, this has already cleared
                   1965:         * the VFTA and other state, so if there
                   1966:         * have been no vlan's registered do nothing.
                   1967:         */
1.65      msaitoh  1968:        if (!VLAN_ATTACHED(ec))
1.1       dyoung   1969:                return;
                   1970:
                   1971:        /* Enable the queues */
                   1972:        for (int i = 0; i < adapter->num_queues; i++) {
1.65      msaitoh  1973:                rxr = &adapter->rx_rings[i];
                   1974:                ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(rxr->me));
1.1       dyoung   1975:                ctrl |= IXGBE_RXDCTL_VME;
1.65      msaitoh  1976:                IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(rxr->me), ctrl);
1.26      msaitoh  1977:                /*
                   1978:                 * Let Rx path know that it needs to store VLAN tag
                   1979:                 * as part of extra mbuf info.
                   1980:                 */
1.65      msaitoh  1981:                rxr->vtag_strip = TRUE;
1.1       dyoung   1982:        }
                   1983:
1.65      msaitoh  1984: #if 1
                   1985:        /* XXX dirty hack. Enable all VIDs */
                   1986:        for (int i = 0; i < IXGBE_VFTA_SIZE; i++)
                   1987:          adapter->shadow_vfta[i] = 0xffffffff;
                   1988: #endif
1.1       dyoung   1989:        /*
1.58      msaitoh  1990:         * A soft reset zero's out the VFTA, so
                   1991:         * we need to repopulate it now.
                   1992:         */
1.21      msaitoh  1993:        for (int i = 0; i < IXGBE_VFTA_SIZE; i++) {
1.65      msaitoh  1994:                if (adapter->shadow_vfta[i] == 0)
1.1       dyoung   1995:                        continue;
1.65      msaitoh  1996:                vfta = adapter->shadow_vfta[i];
1.1       dyoung   1997:                /*
1.58      msaitoh  1998:                 * Reconstruct the vlan id's
                   1999:                 * based on the bits set in each
                   2000:                 * of the array ints.
                   2001:                 */
1.26      msaitoh  2002:                for (int j = 0; j < 32; j++) {
1.1       dyoung   2003:                        retry = 0;
                   2004:                        if ((vfta & (1 << j)) == 0)
                   2005:                                continue;
                   2006:                        vid = (i * 32) + j;
                   2007:                        /* Call the shared code mailbox routine */
1.58      msaitoh  2008:                        while (hw->mac.ops.set_vfta(hw, vid, 0, TRUE, FALSE)) {
1.1       dyoung   2009:                                if (++retry > 5)
                   2010:                                        break;
                   2011:                        }
                   2012:                }
                   2013:        }
1.58      msaitoh  2014: } /* ixv_setup_vlan_support */
1.1       dyoung   2015:
1.3       msaitoh  2016: #if 0  /* XXX Badly need to overhaul vlan(4) on NetBSD. */
1.58      msaitoh  2017: /************************************************************************
                   2018:  * ixv_register_vlan
                   2019:  *
                   2020:  *   Run via a vlan config EVENT, it enables us to use the
                   2021:  *   HW Filter table since we can get the vlan id. This just
                   2022:  *   creates the entry in the soft version of the VFTA, init
                   2023:  *   will repopulate the real table.
                   2024:  ************************************************************************/
1.1       dyoung   2025: static void
                   2026: ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
                   2027: {
                   2028:        struct adapter  *adapter = ifp->if_softc;
                   2029:        u16             index, bit;
                   2030:
1.26      msaitoh  2031:        if (ifp->if_softc != arg) /* Not our event */
1.1       dyoung   2032:                return;
                   2033:
1.26      msaitoh  2034:        if ((vtag == 0) || (vtag > 4095)) /* Invalid */
1.1       dyoung   2035:                return;
                   2036:
1.21      msaitoh  2037:        IXGBE_CORE_LOCK(adapter);
1.1       dyoung   2038:        index = (vtag >> 5) & 0x7F;
                   2039:        bit = vtag & 0x1F;
1.65      msaitoh  2040:        adapter->shadow_vfta[index] |= (1 << bit);
1.1       dyoung   2041:        /* Re-init to load the changes */
1.5       msaitoh  2042:        ixv_init_locked(adapter);
1.21      msaitoh  2043:        IXGBE_CORE_UNLOCK(adapter);
1.58      msaitoh  2044: } /* ixv_register_vlan */
1.1       dyoung   2045:
1.58      msaitoh  2046: /************************************************************************
                   2047:  * ixv_unregister_vlan
                   2048:  *
                   2049:  *   Run via a vlan unconfig EVENT, remove our entry
                   2050:  *   in the soft vfta.
                   2051:  ************************************************************************/
1.1       dyoung   2052: static void
                   2053: ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
                   2054: {
                   2055:        struct adapter  *adapter = ifp->if_softc;
                   2056:        u16             index, bit;
                   2057:
                   2058:        if (ifp->if_softc !=  arg)
                   2059:                return;
                   2060:
1.58      msaitoh  2061:        if ((vtag == 0) || (vtag > 4095))  /* Invalid */
1.1       dyoung   2062:                return;
                   2063:
1.21      msaitoh  2064:        IXGBE_CORE_LOCK(adapter);
1.1       dyoung   2065:        index = (vtag >> 5) & 0x7F;
                   2066:        bit = vtag & 0x1F;
1.65      msaitoh  2067:        adapter->shadow_vfta[index] &= ~(1 << bit);
1.1       dyoung   2068:        /* Re-init to load the changes */
1.5       msaitoh  2069:        ixv_init_locked(adapter);
1.21      msaitoh  2070:        IXGBE_CORE_UNLOCK(adapter);
1.58      msaitoh  2071: } /* ixv_unregister_vlan */
1.3       msaitoh  2072: #endif
1.1       dyoung   2073:
1.58      msaitoh  2074: /************************************************************************
                   2075:  * ixv_enable_intr
                   2076:  ************************************************************************/
1.1       dyoung   2077: static void
                   2078: ixv_enable_intr(struct adapter *adapter)
                   2079: {
                   2080:        struct ixgbe_hw *hw = &adapter->hw;
                   2081:        struct ix_queue *que = adapter->queues;
1.68      msaitoh  2082:        u32             mask;
                   2083:        int i;
1.1       dyoung   2084:
1.68      msaitoh  2085:        /* For VTEIAC */
                   2086:        mask = (1 << adapter->vector);
                   2087:        for (i = 0; i < adapter->num_queues; i++, que++)
                   2088:                mask |= (1 << que->msix);
1.1       dyoung   2089:        IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask);
                   2090:
1.68      msaitoh  2091:        /* For VTEIMS */
                   2092:        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector));
1.69      msaitoh  2093:        que = adapter->queues;
1.68      msaitoh  2094:        for (i = 0; i < adapter->num_queues; i++, que++)
1.1       dyoung   2095:                ixv_enable_queue(adapter, que->msix);
                   2096:
                   2097:        IXGBE_WRITE_FLUSH(hw);
1.58      msaitoh  2098: } /* ixv_enable_intr */
1.1       dyoung   2099:
1.58      msaitoh  2100: /************************************************************************
                   2101:  * ixv_disable_intr
                   2102:  ************************************************************************/
1.1       dyoung   2103: static void
                   2104: ixv_disable_intr(struct adapter *adapter)
                   2105: {
1.82      knakahar 2106:        struct ix_queue *que = adapter->queues;
                   2107:
1.1       dyoung   2108:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0);
1.82      knakahar 2109:
                   2110:        /* disable interrupts other than queues */
                   2111:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, adapter->vector);
                   2112:
                   2113:        for (int i = 0; i < adapter->num_queues; i++, que++)
                   2114:                ixv_disable_queue(adapter, que->msix);
                   2115:
1.1       dyoung   2116:        IXGBE_WRITE_FLUSH(&adapter->hw);
1.58      msaitoh  2117: } /* ixv_disable_intr */
1.1       dyoung   2118:
1.58      msaitoh  2119: /************************************************************************
                   2120:  * ixv_set_ivar
                   2121:  *
                   2122:  *   Setup the correct IVAR register for a particular MSI-X interrupt
                   2123:  *    - entry is the register array entry
                   2124:  *    - vector is the MSI-X vector for this queue
                   2125:  *    - type is RX/TX/MISC
                   2126:  ************************************************************************/
1.1       dyoung   2127: static void
                   2128: ixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
                   2129: {
                   2130:        struct ixgbe_hw *hw = &adapter->hw;
1.58      msaitoh  2131:        u32             ivar, index;
1.1       dyoung   2132:
                   2133:        vector |= IXGBE_IVAR_ALLOC_VAL;
                   2134:
                   2135:        if (type == -1) { /* MISC IVAR */
                   2136:                ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
                   2137:                ivar &= ~0xFF;
                   2138:                ivar |= vector;
                   2139:                IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar);
1.58      msaitoh  2140:        } else {          /* RX/TX IVARS */
1.1       dyoung   2141:                index = (16 * (entry & 1)) + (8 * type);
                   2142:                ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1));
                   2143:                ivar &= ~(0xFF << index);
                   2144:                ivar |= (vector << index);
                   2145:                IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar);
                   2146:        }
1.58      msaitoh  2147: } /* ixv_set_ivar */
1.1       dyoung   2148:
1.58      msaitoh  2149: /************************************************************************
                   2150:  * ixv_configure_ivars
                   2151:  ************************************************************************/
1.1       dyoung   2152: static void
                   2153: ixv_configure_ivars(struct adapter *adapter)
                   2154: {
1.58      msaitoh  2155:        struct ix_queue *que = adapter->queues;
1.1       dyoung   2156:
1.80      msaitoh  2157:        /* XXX We should sync EITR value calculation with ixgbe.c? */
                   2158:
1.57      msaitoh  2159:        for (int i = 0; i < adapter->num_queues; i++, que++) {
1.1       dyoung   2160:                /* First the RX queue entry */
1.57      msaitoh  2161:                ixv_set_ivar(adapter, i, que->msix, 0);
1.1       dyoung   2162:                /* ... and the TX */
                   2163:                ixv_set_ivar(adapter, i, que->msix, 1);
                   2164:                /* Set an initial value in EITR */
1.84.2.6  pgoyette 2165:                ixv_eitr_write(adapter, que->msix, IXGBE_EITR_DEFAULT);
1.1       dyoung   2166:        }
                   2167:
1.21      msaitoh  2168:        /* For the mailbox interrupt */
1.57      msaitoh  2169:        ixv_set_ivar(adapter, 1, adapter->vector, -1);
1.58      msaitoh  2170: } /* ixv_configure_ivars */
1.1       dyoung   2171:
                   2172:
1.58      msaitoh  2173: /************************************************************************
                   2174:  * ixv_save_stats
                   2175:  *
                   2176:  *   The VF stats registers never have a truly virgin
                   2177:  *   starting point, so this routine tries to make an
                   2178:  *   artificial one, marking ground zero on attach as
                   2179:  *   it were.
                   2180:  ************************************************************************/
1.1       dyoung   2181: static void
                   2182: ixv_save_stats(struct adapter *adapter)
                   2183: {
1.21      msaitoh  2184:        struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
                   2185:
                   2186:        if (stats->vfgprc.ev_count || stats->vfgptc.ev_count) {
                   2187:                stats->saved_reset_vfgprc +=
                   2188:                    stats->vfgprc.ev_count - stats->base_vfgprc;
                   2189:                stats->saved_reset_vfgptc +=
                   2190:                    stats->vfgptc.ev_count - stats->base_vfgptc;
                   2191:                stats->saved_reset_vfgorc +=
                   2192:                    stats->vfgorc.ev_count - stats->base_vfgorc;
                   2193:                stats->saved_reset_vfgotc +=
                   2194:                    stats->vfgotc.ev_count - stats->base_vfgotc;
                   2195:                stats->saved_reset_vfmprc +=
                   2196:                    stats->vfmprc.ev_count - stats->base_vfmprc;
1.1       dyoung   2197:        }
1.58      msaitoh  2198: } /* ixv_save_stats */
1.63      msaitoh  2199:
1.58      msaitoh  2200: /************************************************************************
                   2201:  * ixv_init_stats
                   2202:  ************************************************************************/
1.1       dyoung   2203: static void
                   2204: ixv_init_stats(struct adapter *adapter)
                   2205: {
                   2206:        struct ixgbe_hw *hw = &adapter->hw;
1.57      msaitoh  2207:
1.21      msaitoh  2208:        adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
                   2209:        adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
                   2210:        adapter->stats.vf.last_vfgorc |=
1.1       dyoung   2211:            (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
                   2212:
1.21      msaitoh  2213:        adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
                   2214:        adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
                   2215:        adapter->stats.vf.last_vfgotc |=
1.1       dyoung   2216:            (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
                   2217:
1.21      msaitoh  2218:        adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
1.1       dyoung   2219:
1.21      msaitoh  2220:        adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc;
                   2221:        adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc;
                   2222:        adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc;
                   2223:        adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc;
                   2224:        adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc;
1.58      msaitoh  2225: } /* ixv_init_stats */
1.1       dyoung   2226:
                   2227: #define UPDATE_STAT_32(reg, last, count)               \
1.58      msaitoh  2228: {                                                       \
                   2229:        u32 current = IXGBE_READ_REG(hw, (reg));        \
                   2230:        if (current < (last))                           \
1.21      msaitoh  2231:                count.ev_count += 0x100000000LL;        \
1.58      msaitoh  2232:        (last) = current;                               \
1.21      msaitoh  2233:        count.ev_count &= 0xFFFFFFFF00000000LL;         \
                   2234:        count.ev_count |= current;                      \
1.1       dyoung   2235: }
                   2236:
1.58      msaitoh  2237: #define UPDATE_STAT_36(lsb, msb, last, count)           \
                   2238: {                                                       \
                   2239:        u64 cur_lsb = IXGBE_READ_REG(hw, (lsb));        \
                   2240:        u64 cur_msb = IXGBE_READ_REG(hw, (msb));        \
                   2241:        u64 current = ((cur_msb << 32) | cur_lsb);      \
                   2242:        if (current < (last))                           \
1.21      msaitoh  2243:                count.ev_count += 0x1000000000LL;       \
1.58      msaitoh  2244:        (last) = current;                               \
1.21      msaitoh  2245:        count.ev_count &= 0xFFFFFFF000000000LL;         \
                   2246:        count.ev_count |= current;                      \
1.1       dyoung   2247: }
                   2248:
1.58      msaitoh  2249: /************************************************************************
                   2250:  * ixv_update_stats - Update the board statistics counters.
                   2251:  ************************************************************************/
1.1       dyoung   2252: void
                   2253: ixv_update_stats(struct adapter *adapter)
                   2254: {
1.63      msaitoh  2255:        struct ixgbe_hw *hw = &adapter->hw;
1.58      msaitoh  2256:        struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.1       dyoung   2257:
1.84.2.1  pgoyette 2258:        UPDATE_STAT_32(IXGBE_VFGPRC, stats->last_vfgprc, stats->vfgprc);
                   2259:        UPDATE_STAT_32(IXGBE_VFGPTC, stats->last_vfgptc, stats->vfgptc);
                   2260:        UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB, stats->last_vfgorc,
1.58      msaitoh  2261:            stats->vfgorc);
1.84.2.1  pgoyette 2262:        UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB, stats->last_vfgotc,
1.58      msaitoh  2263:            stats->vfgotc);
1.84.2.1  pgoyette 2264:        UPDATE_STAT_32(IXGBE_VFMPRC, stats->last_vfmprc, stats->vfmprc);
1.58      msaitoh  2265:
                   2266:        /* Fill out the OS statistics structure */
                   2267:        /*
                   2268:         * NetBSD: Don't override if_{i|o}{packets|bytes|mcasts} with
                   2269:         * adapter->stats counters. It's required to make ifconfig -z
                   2270:         * (SOICZIFDATA) work.
                   2271:         */
                   2272: } /* ixv_update_stats */
1.1       dyoung   2273:
1.83      msaitoh  2274: /************************************************************************
                   2275:  * ixv_sysctl_interrupt_rate_handler
                   2276:  ************************************************************************/
                   2277: static int
                   2278: ixv_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS)
                   2279: {
                   2280:        struct sysctlnode node = *rnode;
                   2281:        struct ix_queue *que = (struct ix_queue *)node.sysctl_data;
                   2282:        struct adapter  *adapter = que->adapter;
                   2283:        uint32_t reg, usec, rate;
                   2284:        int error;
                   2285:
                   2286:        if (que == NULL)
                   2287:                return 0;
                   2288:        reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_VTEITR(que->msix));
                   2289:        usec = ((reg & 0x0FF8) >> 3);
                   2290:        if (usec > 0)
                   2291:                rate = 500000 / usec;
                   2292:        else
                   2293:                rate = 0;
                   2294:        node.sysctl_data = &rate;
                   2295:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   2296:        if (error || newp == NULL)
                   2297:                return error;
                   2298:        reg &= ~0xfff; /* default, no limitation */
                   2299:        if (rate > 0 && rate < 500000) {
                   2300:                if (rate < 1000)
                   2301:                        rate = 1000;
                   2302:                reg |= ((4000000/rate) & 0xff8);
                   2303:                /*
                   2304:                 * When RSC is used, ITR interval must be larger than
                   2305:                 * RSC_DELAY. Currently, we use 2us for RSC_DELAY.
                   2306:                 * The minimum value is always greater than 2us on 100M
                   2307:                 * (and 10M?(not documented)), but it's not on 1G and higher.
                   2308:                 */
                   2309:                if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
                   2310:                    && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
                   2311:                        if ((adapter->num_queues > 1)
                   2312:                            && (reg < IXGBE_MIN_RSC_EITR_10G1G))
                   2313:                                return EINVAL;
                   2314:                }
                   2315:                ixv_max_interrupt_rate = rate;
                   2316:        } else
                   2317:                ixv_max_interrupt_rate = 0;
1.84.2.6  pgoyette 2318:        ixv_eitr_write(adapter, que->msix, reg);
1.83      msaitoh  2319:
                   2320:        return (0);
                   2321: } /* ixv_sysctl_interrupt_rate_handler */
                   2322:
1.3       msaitoh  2323: const struct sysctlnode *
                   2324: ixv_sysctl_instance(struct adapter *adapter)
                   2325: {
                   2326:        const char *dvname;
                   2327:        struct sysctllog **log;
                   2328:        int rc;
                   2329:        const struct sysctlnode *rnode;
                   2330:
                   2331:        log = &adapter->sysctllog;
                   2332:        dvname = device_xname(adapter->dev);
                   2333:
                   2334:        if ((rc = sysctl_createv(log, 0, NULL, &rnode,
                   2335:            0, CTLTYPE_NODE, dvname,
                   2336:            SYSCTL_DESCR("ixv information and settings"),
                   2337:            NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
                   2338:                goto err;
                   2339:
                   2340:        return rnode;
                   2341: err:
                   2342:        printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
                   2343:        return NULL;
                   2344: }
1.48      msaitoh  2345:
                   2346: static void
                   2347: ixv_add_device_sysctls(struct adapter *adapter)
                   2348: {
                   2349:        struct sysctllog **log;
                   2350:        const struct sysctlnode *rnode, *cnode;
                   2351:        device_t dev;
                   2352:
                   2353:        dev = adapter->dev;
                   2354:        log = &adapter->sysctllog;
                   2355:
                   2356:        if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
                   2357:                aprint_error_dev(dev, "could not create sysctl root\n");
                   2358:                return;
                   2359:        }
                   2360:
                   2361:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   2362:            CTLFLAG_READWRITE, CTLTYPE_INT,
                   2363:            "debug", SYSCTL_DESCR("Debug Info"),
                   2364:            ixv_sysctl_debug, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL) != 0)
                   2365:                aprint_error_dev(dev, "could not create sysctl\n");
                   2366:
                   2367:        if (sysctl_createv(log, 0, &rnode, &cnode,
1.50      msaitoh  2368:            CTLFLAG_READWRITE, CTLTYPE_BOOL,
1.48      msaitoh  2369:            "enable_aim", SYSCTL_DESCR("Interrupt Moderation"),
1.50      msaitoh  2370:            NULL, 0, &adapter->enable_aim, 0, CTL_CREATE, CTL_EOL) != 0)
1.48      msaitoh  2371:                aprint_error_dev(dev, "could not create sysctl\n");
1.84      knakahar 2372:
                   2373:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   2374:            CTLFLAG_READWRITE, CTLTYPE_BOOL,
                   2375:            "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"),
                   2376:                NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL) != 0)
                   2377:                aprint_error_dev(dev, "could not create sysctl\n");
1.48      msaitoh  2378: }
                   2379:
1.58      msaitoh  2380: /************************************************************************
                   2381:  * ixv_add_stats_sysctls - Add statistic sysctls for the VF.
                   2382:  ************************************************************************/
1.48      msaitoh  2383: static void
                   2384: ixv_add_stats_sysctls(struct adapter *adapter)
                   2385: {
1.58      msaitoh  2386:        device_t                dev = adapter->dev;
                   2387:        struct tx_ring          *txr = adapter->tx_rings;
                   2388:        struct rx_ring          *rxr = adapter->rx_rings;
                   2389:        struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.67      msaitoh  2390:        struct ixgbe_hw *hw = &adapter->hw;
1.83      msaitoh  2391:        const struct sysctlnode *rnode, *cnode;
1.49      msaitoh  2392:        struct sysctllog **log = &adapter->sysctllog;
1.48      msaitoh  2393:        const char *xname = device_xname(dev);
                   2394:
                   2395:        /* Driver Statistics */
1.49      msaitoh  2396:        evcnt_attach_dynamic(&adapter->efbig_tx_dma_setup, EVCNT_TYPE_MISC,
                   2397:            NULL, xname, "Driver tx dma soft fail EFBIG");
1.48      msaitoh  2398:        evcnt_attach_dynamic(&adapter->mbuf_defrag_failed, EVCNT_TYPE_MISC,
                   2399:            NULL, xname, "m_defrag() failed");
1.49      msaitoh  2400:        evcnt_attach_dynamic(&adapter->efbig2_tx_dma_setup, EVCNT_TYPE_MISC,
                   2401:            NULL, xname, "Driver tx dma hard fail EFBIG");
                   2402:        evcnt_attach_dynamic(&adapter->einval_tx_dma_setup, EVCNT_TYPE_MISC,
                   2403:            NULL, xname, "Driver tx dma hard fail EINVAL");
                   2404:        evcnt_attach_dynamic(&adapter->other_tx_dma_setup, EVCNT_TYPE_MISC,
                   2405:            NULL, xname, "Driver tx dma hard fail other");
                   2406:        evcnt_attach_dynamic(&adapter->eagain_tx_dma_setup, EVCNT_TYPE_MISC,
                   2407:            NULL, xname, "Driver tx dma soft fail EAGAIN");
                   2408:        evcnt_attach_dynamic(&adapter->enomem_tx_dma_setup, EVCNT_TYPE_MISC,
                   2409:            NULL, xname, "Driver tx dma soft fail ENOMEM");
1.48      msaitoh  2410:        evcnt_attach_dynamic(&adapter->watchdog_events, EVCNT_TYPE_MISC,
                   2411:            NULL, xname, "Watchdog timeouts");
1.49      msaitoh  2412:        evcnt_attach_dynamic(&adapter->tso_err, EVCNT_TYPE_MISC,
                   2413:            NULL, xname, "TSO errors");
                   2414:        evcnt_attach_dynamic(&adapter->link_irq, EVCNT_TYPE_INTR,
1.58      msaitoh  2415:            NULL, xname, "Link MSI-X IRQ Handled");
1.49      msaitoh  2416:
                   2417:        for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
                   2418:                snprintf(adapter->queues[i].evnamebuf,
                   2419:                    sizeof(adapter->queues[i].evnamebuf), "%s q%d",
                   2420:                    xname, i);
                   2421:                snprintf(adapter->queues[i].namebuf,
                   2422:                    sizeof(adapter->queues[i].namebuf), "q%d", i);
                   2423:
                   2424:                if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
                   2425:                        aprint_error_dev(dev, "could not create sysctl root\n");
                   2426:                        break;
                   2427:                }
                   2428:
                   2429:                if (sysctl_createv(log, 0, &rnode, &rnode,
                   2430:                    0, CTLTYPE_NODE,
                   2431:                    adapter->queues[i].namebuf, SYSCTL_DESCR("Queue Name"),
                   2432:                    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
                   2433:                        break;
                   2434:
                   2435:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   2436:                    CTLFLAG_READWRITE, CTLTYPE_INT,
                   2437:                    "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"),
1.83      msaitoh  2438:                    ixv_sysctl_interrupt_rate_handler, 0,
1.49      msaitoh  2439:                    (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0)
                   2440:                        break;
                   2441:
                   2442:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   2443:                    CTLFLAG_READONLY, CTLTYPE_INT,
                   2444:                    "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"),
1.83      msaitoh  2445:                    ixv_sysctl_tdh_handler, 0, (void *)txr,
1.49      msaitoh  2446:                    0, CTL_CREATE, CTL_EOL) != 0)
                   2447:                        break;
                   2448:
                   2449:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   2450:                    CTLFLAG_READONLY, CTLTYPE_INT,
                   2451:                    "txd_tail", SYSCTL_DESCR("Transmit Descriptor Tail"),
1.83      msaitoh  2452:                    ixv_sysctl_tdt_handler, 0, (void *)txr,
1.49      msaitoh  2453:                    0, CTL_CREATE, CTL_EOL) != 0)
                   2454:                        break;
1.83      msaitoh  2455:
1.49      msaitoh  2456:                evcnt_attach_dynamic(&adapter->queues[i].irqs, EVCNT_TYPE_INTR,
                   2457:                    NULL, adapter->queues[i].evnamebuf, "IRQs on queue");
1.84.2.1  pgoyette 2458:                evcnt_attach_dynamic(&adapter->queues[i].handleq,
                   2459:                    EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   2460:                    "Handled queue in softint");
                   2461:                evcnt_attach_dynamic(&adapter->queues[i].req, EVCNT_TYPE_MISC,
                   2462:                    NULL, adapter->queues[i].evnamebuf, "Requeued in softint");
1.49      msaitoh  2463:                evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC,
                   2464:                    NULL, adapter->queues[i].evnamebuf, "TSO");
                   2465:                evcnt_attach_dynamic(&txr->no_desc_avail, EVCNT_TYPE_MISC,
                   2466:                    NULL, adapter->queues[i].evnamebuf,
                   2467:                    "Queue No Descriptor Available");
                   2468:                evcnt_attach_dynamic(&txr->total_packets, EVCNT_TYPE_MISC,
                   2469:                    NULL, adapter->queues[i].evnamebuf,
                   2470:                    "Queue Packets Transmitted");
                   2471: #ifndef IXGBE_LEGACY_TX
                   2472:                evcnt_attach_dynamic(&txr->pcq_drops, EVCNT_TYPE_MISC,
                   2473:                    NULL, adapter->queues[i].evnamebuf,
                   2474:                    "Packets dropped in pcq");
                   2475: #endif
                   2476:
                   2477: #ifdef LRO
                   2478:                struct lro_ctrl *lro = &rxr->lro;
                   2479: #endif /* LRO */
                   2480:
                   2481:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   2482:                    CTLFLAG_READONLY,
                   2483:                    CTLTYPE_INT,
1.84.2.8! pgoyette 2484:                    "rxd_nxck", SYSCTL_DESCR("Receive Descriptor next to check"),
        !          2485:                        ixv_sysctl_next_to_check_handler, 0, (void *)rxr, 0,
        !          2486:                    CTL_CREATE, CTL_EOL) != 0)
        !          2487:                        break;
        !          2488:
        !          2489:                if (sysctl_createv(log, 0, &rnode, &cnode,
        !          2490:                    CTLFLAG_READONLY,
        !          2491:                    CTLTYPE_INT,
1.49      msaitoh  2492:                    "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"),
1.83      msaitoh  2493:                    ixv_sysctl_rdh_handler, 0, (void *)rxr, 0,
1.49      msaitoh  2494:                    CTL_CREATE, CTL_EOL) != 0)
                   2495:                        break;
                   2496:
                   2497:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   2498:                    CTLFLAG_READONLY,
                   2499:                    CTLTYPE_INT,
                   2500:                    "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"),
1.83      msaitoh  2501:                    ixv_sysctl_rdt_handler, 0, (void *)rxr, 0,
1.49      msaitoh  2502:                    CTL_CREATE, CTL_EOL) != 0)
                   2503:                        break;
                   2504:
                   2505:                evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC,
                   2506:                    NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");
                   2507:                evcnt_attach_dynamic(&rxr->rx_bytes, EVCNT_TYPE_MISC,
                   2508:                    NULL, adapter->queues[i].evnamebuf, "Queue Bytes Received");
                   2509:                evcnt_attach_dynamic(&rxr->rx_copies, EVCNT_TYPE_MISC,
                   2510:                    NULL, adapter->queues[i].evnamebuf, "Copied RX Frames");
                   2511:                evcnt_attach_dynamic(&rxr->no_jmbuf, EVCNT_TYPE_MISC,
                   2512:                    NULL, adapter->queues[i].evnamebuf, "Rx no jumbo mbuf");
                   2513:                evcnt_attach_dynamic(&rxr->rx_discarded, EVCNT_TYPE_MISC,
                   2514:                    NULL, adapter->queues[i].evnamebuf, "Rx discarded");
                   2515: #ifdef LRO
                   2516:                SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_queued",
                   2517:                                CTLFLAG_RD, &lro->lro_queued, 0,
                   2518:                                "LRO Queued");
                   2519:                SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_flushed",
                   2520:                                CTLFLAG_RD, &lro->lro_flushed, 0,
                   2521:                                "LRO Flushed");
                   2522: #endif /* LRO */
                   2523:        }
                   2524:
1.58      msaitoh  2525:        /* MAC stats get their own sub node */
1.49      msaitoh  2526:
                   2527:        snprintf(stats->namebuf,
                   2528:            sizeof(stats->namebuf), "%s MAC Statistics", xname);
                   2529:
                   2530:        evcnt_attach_dynamic(&stats->ipcs, EVCNT_TYPE_MISC, NULL,
                   2531:            stats->namebuf, "rx csum offload - IP");
                   2532:        evcnt_attach_dynamic(&stats->l4cs, EVCNT_TYPE_MISC, NULL,
                   2533:            stats->namebuf, "rx csum offload - L4");
                   2534:        evcnt_attach_dynamic(&stats->ipcs_bad, EVCNT_TYPE_MISC, NULL,
                   2535:            stats->namebuf, "rx csum offload - IP bad");
                   2536:        evcnt_attach_dynamic(&stats->l4cs_bad, EVCNT_TYPE_MISC, NULL,
                   2537:            stats->namebuf, "rx csum offload - L4 bad");
1.48      msaitoh  2538:
1.49      msaitoh  2539:        /* Packet Reception Stats */
1.48      msaitoh  2540:        evcnt_attach_dynamic(&stats->vfgprc, EVCNT_TYPE_MISC, NULL,
                   2541:            xname, "Good Packets Received");
                   2542:        evcnt_attach_dynamic(&stats->vfgorc, EVCNT_TYPE_MISC, NULL,
                   2543:            xname, "Good Octets Received");
                   2544:        evcnt_attach_dynamic(&stats->vfmprc, EVCNT_TYPE_MISC, NULL,
                   2545:            xname, "Multicast Packets Received");
                   2546:        evcnt_attach_dynamic(&stats->vfgptc, EVCNT_TYPE_MISC, NULL,
                   2547:            xname, "Good Packets Transmitted");
                   2548:        evcnt_attach_dynamic(&stats->vfgotc, EVCNT_TYPE_MISC, NULL,
                   2549:            xname, "Good Octets Transmitted");
1.67      msaitoh  2550:
                   2551:        /* Mailbox Stats */
                   2552:        evcnt_attach_dynamic(&hw->mbx.stats.msgs_tx, EVCNT_TYPE_MISC, NULL,
                   2553:            xname, "message TXs");
                   2554:        evcnt_attach_dynamic(&hw->mbx.stats.msgs_rx, EVCNT_TYPE_MISC, NULL,
                   2555:            xname, "message RXs");
                   2556:        evcnt_attach_dynamic(&hw->mbx.stats.acks, EVCNT_TYPE_MISC, NULL,
                   2557:            xname, "ACKs");
                   2558:        evcnt_attach_dynamic(&hw->mbx.stats.reqs, EVCNT_TYPE_MISC, NULL,
                   2559:            xname, "REQs");
                   2560:        evcnt_attach_dynamic(&hw->mbx.stats.rsts, EVCNT_TYPE_MISC, NULL,
                   2561:            xname, "RSTs");
                   2562:
1.58      msaitoh  2563: } /* ixv_add_stats_sysctls */
1.48      msaitoh  2564:
1.58      msaitoh  2565: /************************************************************************
                   2566:  * ixv_set_sysctl_value
                   2567:  ************************************************************************/
1.48      msaitoh  2568: static void
                   2569: ixv_set_sysctl_value(struct adapter *adapter, const char *name,
                   2570:        const char *description, int *limit, int value)
                   2571: {
                   2572:        device_t dev =  adapter->dev;
                   2573:        struct sysctllog **log;
                   2574:        const struct sysctlnode *rnode, *cnode;
                   2575:
                   2576:        log = &adapter->sysctllog;
                   2577:        if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
                   2578:                aprint_error_dev(dev, "could not create sysctl root\n");
                   2579:                return;
                   2580:        }
                   2581:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   2582:            CTLFLAG_READWRITE, CTLTYPE_INT,
                   2583:            name, SYSCTL_DESCR(description),
                   2584:            NULL, 0, limit, 0, CTL_CREATE, CTL_EOL) != 0)
                   2585:                aprint_error_dev(dev, "could not create sysctl\n");
                   2586:        *limit = value;
1.58      msaitoh  2587: } /* ixv_set_sysctl_value */
1.57      msaitoh  2588:
1.58      msaitoh  2589: /************************************************************************
                   2590:  * ixv_print_debug_info
1.57      msaitoh  2591:  *
1.58      msaitoh  2592:  *   Called only when em_display_debug_stats is enabled.
                   2593:  *   Provides a way to take a look at important statistics
                   2594:  *   maintained by the driver and hardware.
                   2595:  ************************************************************************/
1.57      msaitoh  2596: static void
                   2597: ixv_print_debug_info(struct adapter *adapter)
                   2598: {
1.58      msaitoh  2599:         device_t        dev = adapter->dev;
                   2600:         struct ixgbe_hw *hw = &adapter->hw;
                   2601:         struct ix_queue *que = adapter->queues;
                   2602:         struct rx_ring  *rxr;
                   2603:         struct tx_ring  *txr;
1.57      msaitoh  2604: #ifdef LRO
1.58      msaitoh  2605:         struct lro_ctrl *lro;
1.57      msaitoh  2606: #endif /* LRO */
                   2607:
1.63      msaitoh  2608:        device_printf(dev, "Error Byte Count = %u \n",
1.58      msaitoh  2609:            IXGBE_READ_REG(hw, IXGBE_ERRBC));
1.57      msaitoh  2610:
1.58      msaitoh  2611:        for (int i = 0; i < adapter->num_queues; i++, que++) {
                   2612:                txr = que->txr;
                   2613:                rxr = que->rxr;
1.57      msaitoh  2614: #ifdef LRO
1.58      msaitoh  2615:                lro = &rxr->lro;
1.57      msaitoh  2616: #endif /* LRO */
1.63      msaitoh  2617:                device_printf(dev, "QUE(%d) IRQs Handled: %lu\n",
1.58      msaitoh  2618:                    que->msix, (long)que->irqs.ev_count);
1.63      msaitoh  2619:                device_printf(dev, "RX(%d) Packets Received: %lld\n",
1.58      msaitoh  2620:                    rxr->me, (long long)rxr->rx_packets.ev_count);
1.63      msaitoh  2621:                device_printf(dev, "RX(%d) Bytes Received: %lu\n",
1.58      msaitoh  2622:                    rxr->me, (long)rxr->rx_bytes.ev_count);
1.57      msaitoh  2623: #ifdef LRO
1.63      msaitoh  2624:                device_printf(dev, "RX(%d) LRO Queued= %lld\n",
1.58      msaitoh  2625:                    rxr->me, (long long)lro->lro_queued);
1.63      msaitoh  2626:                device_printf(dev, "RX(%d) LRO Flushed= %lld\n",
1.58      msaitoh  2627:                    rxr->me, (long long)lro->lro_flushed);
1.57      msaitoh  2628: #endif /* LRO */
1.63      msaitoh  2629:                device_printf(dev, "TX(%d) Packets Sent: %lu\n",
1.58      msaitoh  2630:                    txr->me, (long)txr->total_packets.ev_count);
1.63      msaitoh  2631:                device_printf(dev, "TX(%d) NO Desc Avail: %lu\n",
1.58      msaitoh  2632:                    txr->me, (long)txr->no_desc_avail.ev_count);
                   2633:        }
1.57      msaitoh  2634:
1.58      msaitoh  2635:        device_printf(dev, "MBX IRQ Handled: %lu\n",
                   2636:            (long)adapter->link_irq.ev_count);
                   2637: } /* ixv_print_debug_info */
                   2638:
                   2639: /************************************************************************
                   2640:  * ixv_sysctl_debug
                   2641:  ************************************************************************/
1.57      msaitoh  2642: static int
                   2643: ixv_sysctl_debug(SYSCTLFN_ARGS)
                   2644: {
1.84.2.7  pgoyette 2645:        struct sysctlnode node = *rnode;
                   2646:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
1.58      msaitoh  2647:        int            error, result;
1.57      msaitoh  2648:
                   2649:        node.sysctl_data = &result;
                   2650:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   2651:
1.58      msaitoh  2652:        if (error || newp == NULL)
1.57      msaitoh  2653:                return error;
                   2654:
1.84.2.7  pgoyette 2655:        if (result == 1)
1.57      msaitoh  2656:                ixv_print_debug_info(adapter);
                   2657:
                   2658:        return 0;
1.58      msaitoh  2659: } /* ixv_sysctl_debug */
                   2660:
                   2661: /************************************************************************
                   2662:  * ixv_init_device_features
                   2663:  ************************************************************************/
                   2664: static void
                   2665: ixv_init_device_features(struct adapter *adapter)
                   2666: {
                   2667:        adapter->feat_cap = IXGBE_FEATURE_NETMAP
                   2668:                          | IXGBE_FEATURE_VF
                   2669:                          | IXGBE_FEATURE_RSS
                   2670:                          | IXGBE_FEATURE_LEGACY_TX;
                   2671:
                   2672:        /* A tad short on feature flags for VFs, atm. */
                   2673:        switch (adapter->hw.mac.type) {
                   2674:        case ixgbe_mac_82599_vf:
                   2675:                break;
                   2676:        case ixgbe_mac_X540_vf:
                   2677:                break;
                   2678:        case ixgbe_mac_X550_vf:
                   2679:        case ixgbe_mac_X550EM_x_vf:
                   2680:        case ixgbe_mac_X550EM_a_vf:
                   2681:                adapter->feat_cap |= IXGBE_FEATURE_NEEDS_CTXD;
                   2682:                break;
                   2683:        default:
                   2684:                break;
                   2685:        }
1.57      msaitoh  2686:
1.58      msaitoh  2687:        /* Enabled by default... */
                   2688:        /* Is a virtual function (VF) */
                   2689:        if (adapter->feat_cap & IXGBE_FEATURE_VF)
                   2690:                adapter->feat_en |= IXGBE_FEATURE_VF;
                   2691:        /* Netmap */
                   2692:        if (adapter->feat_cap & IXGBE_FEATURE_NETMAP)
                   2693:                adapter->feat_en |= IXGBE_FEATURE_NETMAP;
                   2694:        /* Receive-Side Scaling (RSS) */
                   2695:        if (adapter->feat_cap & IXGBE_FEATURE_RSS)
                   2696:                adapter->feat_en |= IXGBE_FEATURE_RSS;
                   2697:        /* Needs advanced context descriptor regardless of offloads req'd */
                   2698:        if (adapter->feat_cap & IXGBE_FEATURE_NEEDS_CTXD)
                   2699:                adapter->feat_en |= IXGBE_FEATURE_NEEDS_CTXD;
                   2700:
                   2701:        /* Enabled via sysctl... */
                   2702:        /* Legacy (single queue) transmit */
                   2703:        if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) &&
                   2704:            ixv_enable_legacy_tx)
                   2705:                adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX;
                   2706: } /* ixv_init_device_features */
                   2707:
                   2708: /************************************************************************
                   2709:  * ixv_shutdown - Shutdown entry point
                   2710:  ************************************************************************/
1.57      msaitoh  2711: #if 0 /* XXX NetBSD ought to register something like this through pmf(9) */
                   2712: static int
                   2713: ixv_shutdown(device_t dev)
                   2714: {
                   2715:        struct adapter *adapter = device_private(dev);
                   2716:        IXGBE_CORE_LOCK(adapter);
                   2717:        ixv_stop(adapter);
                   2718:        IXGBE_CORE_UNLOCK(adapter);
                   2719:
                   2720:        return (0);
1.58      msaitoh  2721: } /* ixv_shutdown */
1.57      msaitoh  2722: #endif
                   2723:
                   2724: static int
                   2725: ixv_ifflags_cb(struct ethercom *ec)
                   2726: {
                   2727:        struct ifnet *ifp = &ec->ec_if;
                   2728:        struct adapter *adapter = ifp->if_softc;
1.84.2.5  pgoyette 2729:        int change, rc = 0;
1.57      msaitoh  2730:
                   2731:        IXGBE_CORE_LOCK(adapter);
                   2732:
1.84.2.5  pgoyette 2733:        change = ifp->if_flags ^ adapter->if_flags;
1.57      msaitoh  2734:        if (change != 0)
                   2735:                adapter->if_flags = ifp->if_flags;
                   2736:
                   2737:        if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0)
                   2738:                rc = ENETRESET;
                   2739:
1.65      msaitoh  2740:        /* Set up VLAN support and filter */
                   2741:        ixv_setup_vlan_support(adapter);
                   2742:
1.57      msaitoh  2743:        IXGBE_CORE_UNLOCK(adapter);
                   2744:
                   2745:        return rc;
                   2746: }
                   2747:
1.58      msaitoh  2748:
                   2749: /************************************************************************
                   2750:  * ixv_ioctl - Ioctl entry point
1.57      msaitoh  2751:  *
1.58      msaitoh  2752:  *   Called when the user wants to configure the interface.
1.57      msaitoh  2753:  *
1.58      msaitoh  2754:  *   return 0 on success, positive on failure
                   2755:  ************************************************************************/
1.57      msaitoh  2756: static int
1.58      msaitoh  2757: ixv_ioctl(struct ifnet *ifp, u_long command, void *data)
1.57      msaitoh  2758: {
                   2759:        struct adapter  *adapter = ifp->if_softc;
                   2760:        struct ifcapreq *ifcr = data;
1.58      msaitoh  2761:        struct ifreq    *ifr = data;
1.57      msaitoh  2762:        int             error = 0;
                   2763:        int l4csum_en;
                   2764:        const int l4csum = IFCAP_CSUM_TCPv4_Rx|IFCAP_CSUM_UDPv4_Rx|
                   2765:             IFCAP_CSUM_TCPv6_Rx|IFCAP_CSUM_UDPv6_Rx;
                   2766:
                   2767:        switch (command) {
                   2768:        case SIOCSIFFLAGS:
                   2769:                IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
                   2770:                break;
                   2771:        case SIOCADDMULTI:
                   2772:        case SIOCDELMULTI:
                   2773:                IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
                   2774:                break;
                   2775:        case SIOCSIFMEDIA:
                   2776:        case SIOCGIFMEDIA:
                   2777:                IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
                   2778:                break;
                   2779:        case SIOCSIFCAP:
                   2780:                IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
                   2781:                break;
                   2782:        case SIOCSIFMTU:
                   2783:                IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
                   2784:                break;
                   2785:        default:
                   2786:                IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)", (int)command);
                   2787:                break;
                   2788:        }
                   2789:
                   2790:        switch (command) {
                   2791:        case SIOCSIFMEDIA:
                   2792:        case SIOCGIFMEDIA:
                   2793:                return ifmedia_ioctl(ifp, ifr, &adapter->media, command);
                   2794:        case SIOCSIFCAP:
                   2795:                /* Layer-4 Rx checksum offload has to be turned on and
                   2796:                 * off as a unit.
                   2797:                 */
                   2798:                l4csum_en = ifcr->ifcr_capenable & l4csum;
                   2799:                if (l4csum_en != l4csum && l4csum_en != 0)
                   2800:                        return EINVAL;
                   2801:                /*FALLTHROUGH*/
                   2802:        case SIOCADDMULTI:
                   2803:        case SIOCDELMULTI:
                   2804:        case SIOCSIFFLAGS:
                   2805:        case SIOCSIFMTU:
                   2806:        default:
                   2807:                if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
                   2808:                        return error;
                   2809:                if ((ifp->if_flags & IFF_RUNNING) == 0)
                   2810:                        ;
                   2811:                else if (command == SIOCSIFCAP || command == SIOCSIFMTU) {
                   2812:                        IXGBE_CORE_LOCK(adapter);
                   2813:                        ixv_init_locked(adapter);
                   2814:                        IXGBE_CORE_UNLOCK(adapter);
                   2815:                } else if (command == SIOCADDMULTI || command == SIOCDELMULTI) {
                   2816:                        /*
                   2817:                         * Multicast list has changed; set the hardware filter
                   2818:                         * accordingly.
                   2819:                         */
                   2820:                        IXGBE_CORE_LOCK(adapter);
                   2821:                        ixv_disable_intr(adapter);
                   2822:                        ixv_set_multi(adapter);
                   2823:                        ixv_enable_intr(adapter);
                   2824:                        IXGBE_CORE_UNLOCK(adapter);
                   2825:                }
                   2826:                return 0;
                   2827:        }
1.58      msaitoh  2828: } /* ixv_ioctl */
1.57      msaitoh  2829:
1.58      msaitoh  2830: /************************************************************************
                   2831:  * ixv_init
                   2832:  ************************************************************************/
1.57      msaitoh  2833: static int
                   2834: ixv_init(struct ifnet *ifp)
                   2835: {
                   2836:        struct adapter *adapter = ifp->if_softc;
                   2837:
                   2838:        IXGBE_CORE_LOCK(adapter);
                   2839:        ixv_init_locked(adapter);
                   2840:        IXGBE_CORE_UNLOCK(adapter);
                   2841:
                   2842:        return 0;
1.58      msaitoh  2843: } /* ixv_init */
1.57      msaitoh  2844:
1.58      msaitoh  2845: /************************************************************************
                   2846:  * ixv_handle_que
                   2847:  ************************************************************************/
1.57      msaitoh  2848: static void
                   2849: ixv_handle_que(void *context)
                   2850: {
                   2851:        struct ix_queue *que = context;
                   2852:        struct adapter  *adapter = que->adapter;
                   2853:        struct tx_ring  *txr = que->txr;
                   2854:        struct ifnet    *ifp = adapter->ifp;
                   2855:        bool            more;
                   2856:
1.84.2.1  pgoyette 2857:        que->handleq.ev_count++;
1.57      msaitoh  2858:
                   2859:        if (ifp->if_flags & IFF_RUNNING) {
                   2860:                more = ixgbe_rxeof(que);
                   2861:                IXGBE_TX_LOCK(txr);
1.81      msaitoh  2862:                more |= ixgbe_txeof(txr);
1.58      msaitoh  2863:                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
                   2864:                        if (!ixgbe_mq_ring_empty(ifp, txr->txr_interq))
                   2865:                                ixgbe_mq_start_locked(ifp, txr);
1.57      msaitoh  2866:                /* Only for queue 0 */
1.61      msaitoh  2867:                /* NetBSD still needs this for CBQ */
1.57      msaitoh  2868:                if ((&adapter->queues[0] == que)
1.58      msaitoh  2869:                    && (!ixgbe_legacy_ring_empty(ifp, NULL)))
                   2870:                        ixgbe_legacy_start_locked(ifp, txr);
1.57      msaitoh  2871:                IXGBE_TX_UNLOCK(txr);
                   2872:                if (more) {
1.84.2.1  pgoyette 2873:                        que->req.ev_count++;
1.84      knakahar 2874:                        if (adapter->txrx_use_workqueue) {
                   2875:                                /*
                   2876:                                 * "enqueued flag" is not required here
                   2877:                                 * the same as ixg(4). See ixgbe_msix_que().
                   2878:                                 */
                   2879:                                workqueue_enqueue(adapter->que_wq,
                   2880:                                    &que->wq_cookie, curcpu());
                   2881:                        } else
                   2882:                                  softint_schedule(que->que_si);
1.57      msaitoh  2883:                        return;
                   2884:                }
                   2885:        }
                   2886:
1.58      msaitoh  2887:        /* Re-enable this interrupt */
1.57      msaitoh  2888:        ixv_enable_queue(adapter, que->msix);
                   2889:
                   2890:        return;
1.58      msaitoh  2891: } /* ixv_handle_que */
1.57      msaitoh  2892:
1.58      msaitoh  2893: /************************************************************************
1.84      knakahar 2894:  * ixv_handle_que_work
                   2895:  ************************************************************************/
                   2896: static void
                   2897: ixv_handle_que_work(struct work *wk, void *context)
                   2898: {
                   2899:        struct ix_queue *que = container_of(wk, struct ix_queue, wq_cookie);
                   2900:
                   2901:        /*
                   2902:         * "enqueued flag" is not required here the same as ixg(4).
                   2903:         * See ixgbe_msix_que().
                   2904:         */
                   2905:        ixv_handle_que(que);
                   2906: }
                   2907:
                   2908: /************************************************************************
1.58      msaitoh  2909:  * ixv_allocate_msix - Setup MSI-X Interrupt resources and handlers
                   2910:  ************************************************************************/
1.57      msaitoh  2911: static int
                   2912: ixv_allocate_msix(struct adapter *adapter, const struct pci_attach_args *pa)
                   2913: {
                   2914:        device_t        dev = adapter->dev;
                   2915:        struct ix_queue *que = adapter->queues;
                   2916:        struct          tx_ring *txr = adapter->tx_rings;
1.58      msaitoh  2917:        int             error, msix_ctrl, rid, vector = 0;
1.57      msaitoh  2918:        pci_chipset_tag_t pc;
                   2919:        pcitag_t        tag;
                   2920:        char            intrbuf[PCI_INTRSTR_LEN];
1.84      knakahar 2921:        char            wqname[MAXCOMLEN];
1.57      msaitoh  2922:        char            intr_xname[32];
                   2923:        const char      *intrstr = NULL;
                   2924:        kcpuset_t       *affinity;
                   2925:        int             cpu_id = 0;
                   2926:
                   2927:        pc = adapter->osdep.pc;
                   2928:        tag = adapter->osdep.tag;
                   2929:
                   2930:        adapter->osdep.nintrs = adapter->num_queues + 1;
                   2931:        if (pci_msix_alloc_exact(pa, &adapter->osdep.intrs,
                   2932:            adapter->osdep.nintrs) != 0) {
                   2933:                aprint_error_dev(dev,
                   2934:                    "failed to allocate MSI-X interrupt\n");
                   2935:                return (ENXIO);
                   2936:        }
                   2937:
                   2938:        kcpuset_create(&affinity, false);
                   2939:        for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
                   2940:                snprintf(intr_xname, sizeof(intr_xname), "%s TXRX%d",
                   2941:                    device_xname(dev), i);
                   2942:                intrstr = pci_intr_string(pc, adapter->osdep.intrs[i], intrbuf,
                   2943:                    sizeof(intrbuf));
                   2944: #ifdef IXGBE_MPSAFE
                   2945:                pci_intr_setattr(pc, &adapter->osdep.intrs[i], PCI_INTR_MPSAFE,
                   2946:                    true);
                   2947: #endif
                   2948:                /* Set the handler function */
                   2949:                que->res = adapter->osdep.ihs[i] = pci_intr_establish_xname(pc,
                   2950:                    adapter->osdep.intrs[i], IPL_NET, ixv_msix_que, que,
                   2951:                    intr_xname);
                   2952:                if (que->res == NULL) {
                   2953:                        pci_intr_release(pc, adapter->osdep.intrs,
                   2954:                            adapter->osdep.nintrs);
                   2955:                        aprint_error_dev(dev,
                   2956:                            "Failed to register QUE handler\n");
                   2957:                        kcpuset_destroy(affinity);
                   2958:                        return (ENXIO);
                   2959:                }
                   2960:                que->msix = vector;
                   2961:                adapter->active_queues |= (u64)(1 << que->msix);
                   2962:
                   2963:                cpu_id = i;
                   2964:                /* Round-robin affinity */
                   2965:                kcpuset_zero(affinity);
                   2966:                kcpuset_set(affinity, cpu_id % ncpu);
                   2967:                error = interrupt_distribute(adapter->osdep.ihs[i], affinity,
                   2968:                    NULL);
                   2969:                aprint_normal_dev(dev, "for TX/RX, interrupting at %s",
                   2970:                    intrstr);
                   2971:                if (error == 0)
                   2972:                        aprint_normal(", bound queue %d to cpu %d\n",
                   2973:                            i, cpu_id % ncpu);
                   2974:                else
                   2975:                        aprint_normal("\n");
                   2976:
                   2977: #ifndef IXGBE_LEGACY_TX
                   2978:                txr->txr_si
                   2979:                    = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   2980:                        ixgbe_deferred_mq_start, txr);
                   2981: #endif
                   2982:                que->que_si
                   2983:                    = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   2984:                        ixv_handle_que, que);
                   2985:                if (que->que_si == NULL) {
                   2986:                        aprint_error_dev(dev,
                   2987:                            "could not establish software interrupt\n");
                   2988:                }
                   2989:        }
1.84      knakahar 2990:        snprintf(wqname, sizeof(wqname), "%sdeferTx", device_xname(dev));
                   2991:        error = workqueue_create(&adapter->txr_wq, wqname,
                   2992:            ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
                   2993:            IXGBE_WORKQUEUE_FLAGS);
                   2994:        if (error) {
                   2995:                aprint_error_dev(dev, "couldn't create workqueue for deferred Tx\n");
                   2996:        }
                   2997:        adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
                   2998:
                   2999:        snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(dev));
                   3000:        error = workqueue_create(&adapter->que_wq, wqname,
                   3001:            ixv_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
                   3002:            IXGBE_WORKQUEUE_FLAGS);
                   3003:        if (error) {
                   3004:                aprint_error_dev(dev,
                   3005:                    "couldn't create workqueue\n");
                   3006:        }
1.57      msaitoh  3007:
                   3008:        /* and Mailbox */
                   3009:        cpu_id++;
                   3010:        snprintf(intr_xname, sizeof(intr_xname), "%s link", device_xname(dev));
1.77      msaitoh  3011:        adapter->vector = vector;
1.57      msaitoh  3012:        intrstr = pci_intr_string(pc, adapter->osdep.intrs[vector], intrbuf,
                   3013:            sizeof(intrbuf));
                   3014: #ifdef IXGBE_MPSAFE
                   3015:        pci_intr_setattr(pc, &adapter->osdep.intrs[vector], PCI_INTR_MPSAFE,
                   3016:            true);
                   3017: #endif
                   3018:        /* Set the mbx handler function */
                   3019:        adapter->osdep.ihs[vector] = pci_intr_establish_xname(pc,
                   3020:            adapter->osdep.intrs[vector], IPL_NET, ixv_msix_mbx, adapter,
                   3021:            intr_xname);
                   3022:        if (adapter->osdep.ihs[vector] == NULL) {
                   3023:                aprint_error_dev(dev, "Failed to register LINK handler\n");
                   3024:                kcpuset_destroy(affinity);
                   3025:                return (ENXIO);
                   3026:        }
                   3027:        /* Round-robin affinity */
                   3028:        kcpuset_zero(affinity);
                   3029:        kcpuset_set(affinity, cpu_id % ncpu);
                   3030:        error = interrupt_distribute(adapter->osdep.ihs[vector], affinity,NULL);
                   3031:
                   3032:        aprint_normal_dev(dev,
                   3033:            "for link, interrupting at %s", intrstr);
                   3034:        if (error == 0)
                   3035:                aprint_normal(", affinity to cpu %d\n", cpu_id % ncpu);
                   3036:        else
                   3037:                aprint_normal("\n");
                   3038:
                   3039:        /* Tasklets for Mailbox */
                   3040:        adapter->link_si = softint_establish(SOFTINT_NET |IXGBE_SOFTINFT_FLAGS,
1.58      msaitoh  3041:            ixv_handle_link, adapter);
1.57      msaitoh  3042:        /*
1.58      msaitoh  3043:         * Due to a broken design QEMU will fail to properly
                   3044:         * enable the guest for MSI-X unless the vectors in
                   3045:         * the table are all set up, so we must rewrite the
                   3046:         * ENABLE in the MSI-X control register again at this
                   3047:         * point to cause it to successfully initialize us.
                   3048:         */
1.57      msaitoh  3049:        if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
                   3050:                pci_get_capability(pc, tag, PCI_CAP_MSIX, &rid, NULL);
                   3051:                rid += PCI_MSIX_CTL;
                   3052:                msix_ctrl = pci_conf_read(pc, tag, rid);
                   3053:                msix_ctrl |= PCI_MSIX_CTL_ENABLE;
                   3054:                pci_conf_write(pc, tag, rid, msix_ctrl);
                   3055:        }
                   3056:
                   3057:        kcpuset_destroy(affinity);
                   3058:        return (0);
1.58      msaitoh  3059: } /* ixv_allocate_msix */
1.57      msaitoh  3060:
1.58      msaitoh  3061: /************************************************************************
                   3062:  * ixv_configure_interrupts - Setup MSI-X resources
                   3063:  *
                   3064:  *   Note: The VF device MUST use MSI-X, there is no fallback.
                   3065:  ************************************************************************/
1.57      msaitoh  3066: static int
1.58      msaitoh  3067: ixv_configure_interrupts(struct adapter *adapter)
1.57      msaitoh  3068: {
                   3069:        device_t dev = adapter->dev;
                   3070:        int want, queues, msgs;
                   3071:
1.58      msaitoh  3072:        /* Must have at least 2 MSI-X vectors */
1.57      msaitoh  3073:        msgs = pci_msix_count(adapter->osdep.pc, adapter->osdep.tag);
                   3074:        if (msgs < 2) {
1.63      msaitoh  3075:                aprint_error_dev(dev, "MSIX config error\n");
1.57      msaitoh  3076:                return (ENXIO);
                   3077:        }
                   3078:        msgs = MIN(msgs, IXG_MAX_NINTR);
                   3079:
                   3080:        /* Figure out a reasonable auto config value */
                   3081:        queues = (ncpu > (msgs - 1)) ? (msgs - 1) : ncpu;
                   3082:
                   3083:        if (ixv_num_queues != 0)
                   3084:                queues = ixv_num_queues;
                   3085:        else if ((ixv_num_queues == 0) && (queues > IXGBE_VF_MAX_TX_QUEUES))
                   3086:                queues = IXGBE_VF_MAX_TX_QUEUES;
                   3087:
                   3088:        /*
1.58      msaitoh  3089:         * Want vectors for the queues,
                   3090:         * plus an additional for mailbox.
                   3091:         */
1.57      msaitoh  3092:        want = queues + 1;
                   3093:        if (msgs >= want)
                   3094:                msgs = want;
                   3095:        else {
                   3096:                        aprint_error_dev(dev,
1.58      msaitoh  3097:                    "MSI-X Configuration Problem, "
1.57      msaitoh  3098:                    "%d vectors but %d queues wanted!\n",
                   3099:                    msgs, want);
                   3100:                return -1;
                   3101:        }
                   3102:
                   3103:        adapter->msix_mem = (void *)1; /* XXX */
                   3104:        aprint_normal_dev(dev,
1.58      msaitoh  3105:            "Using MSI-X interrupts with %d vectors\n", msgs);
1.57      msaitoh  3106:        adapter->num_queues = queues;
                   3107:
1.58      msaitoh  3108:        return (0);
                   3109: } /* ixv_configure_interrupts */
                   3110:
                   3111:
                   3112: /************************************************************************
                   3113:  * ixv_handle_link - Tasklet handler for MSI-X MBX interrupts
                   3114:  *
                   3115:  *   Done outside of interrupt context since the driver might sleep
                   3116:  ************************************************************************/
1.57      msaitoh  3117: static void
1.58      msaitoh  3118: ixv_handle_link(void *context)
1.57      msaitoh  3119: {
1.58      msaitoh  3120:        struct adapter *adapter = context;
1.57      msaitoh  3121:
1.84.2.2  pgoyette 3122:        IXGBE_CORE_LOCK(adapter);
                   3123:
1.58      msaitoh  3124:        adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed,
                   3125:            &adapter->link_up, FALSE);
1.57      msaitoh  3126:        ixv_update_link_status(adapter);
1.84.2.2  pgoyette 3127:
                   3128:        IXGBE_CORE_UNLOCK(adapter);
1.58      msaitoh  3129: } /* ixv_handle_link */
1.57      msaitoh  3130:
1.58      msaitoh  3131: /************************************************************************
                   3132:  * ixv_check_link - Used in the local timer to poll for link changes
                   3133:  ************************************************************************/
1.57      msaitoh  3134: static void
1.58      msaitoh  3135: ixv_check_link(struct adapter *adapter)
1.57      msaitoh  3136: {
1.84.2.2  pgoyette 3137:
                   3138:        KASSERT(mutex_owned(&adapter->core_mtx));
                   3139:
1.58      msaitoh  3140:        adapter->hw.mac.get_link_status = TRUE;
1.57      msaitoh  3141:
1.58      msaitoh  3142:        adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed,
                   3143:            &adapter->link_up, FALSE);
                   3144:        ixv_update_link_status(adapter);
                   3145: } /* ixv_check_link */

CVSweb <webmaster@jp.NetBSD.org>