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

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

CVSweb <webmaster@jp.NetBSD.org>