[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.120

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

CVSweb <webmaster@jp.NetBSD.org>