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

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

1.149   ! msaitoh     1: /* $NetBSD: ixgbe.c,v 1.148 2018/04/17 08:38:05 msaitoh Exp $ */
1.99      msaitoh     2:
1.1       dyoung      3: /******************************************************************************
                      4:
1.99      msaitoh     5:   Copyright (c) 2001-2017, Intel Corporation
1.1       dyoung      6:   All rights reserved.
1.99      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.99      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.99      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.99      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.99      msaitoh    21:
1.1       dyoung     22:   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1.99      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.145     msaitoh    35: /*$FreeBSD: head/sys/dev/ixgbe/if_ix.c 331224 2018-03-19 20:55:05Z erj $*/
1.99      msaitoh    36:
1.1       dyoung     37: /*
                     38:  * Copyright (c) 2011 The NetBSD Foundation, Inc.
                     39:  * All rights reserved.
                     40:  *
                     41:  * This code is derived from software contributed to The NetBSD Foundation
                     42:  * by Coyote Point Systems, Inc.
                     43:  *
                     44:  * Redistribution and use in source and binary forms, with or without
                     45:  * modification, are permitted provided that the following conditions
                     46:  * are met:
                     47:  * 1. Redistributions of source code must retain the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer.
                     49:  * 2. Redistributions in binary form must reproduce the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer in the
                     51:  *    documentation and/or other materials provided with the distribution.
                     52:  *
                     53:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     54:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     55:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     56:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     57:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     58:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     59:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     60:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     61:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     62:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     63:  * POSSIBILITY OF SUCH DAMAGE.
                     64:  */
                     65:
1.80      msaitoh    66: #ifdef _KERNEL_OPT
1.1       dyoung     67: #include "opt_inet.h"
1.22      msaitoh    68: #include "opt_inet6.h"
1.80      msaitoh    69: #include "opt_net_mpsafe.h"
                     70: #endif
1.1       dyoung     71:
                     72: #include "ixgbe.h"
1.135     msaitoh    73: #include "ixgbe_sriov.h"
1.29      msaitoh    74: #include "vlan.h"
1.1       dyoung     75:
1.33      msaitoh    76: #include <sys/cprng.h>
1.95      msaitoh    77: #include <dev/mii/mii.h>
                     78: #include <dev/mii/miivar.h>
1.33      msaitoh    79:
1.99      msaitoh    80: /************************************************************************
                     81:  * Driver version
                     82:  ************************************************************************/
1.145     msaitoh    83: char ixgbe_driver_version[] = "4.0.1-k";
1.1       dyoung     84:
                     85:
1.99      msaitoh    86: /************************************************************************
                     87:  * PCI Device ID Table
1.1       dyoung     88:  *
1.99      msaitoh    89:  *   Used by probe to select devices to load on
                     90:  *   Last field stores an index into ixgbe_strings
                     91:  *   Last entry must be all 0s
1.1       dyoung     92:  *
1.99      msaitoh    93:  *   { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
                     94:  ************************************************************************/
1.1       dyoung     95: static ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
                     96: {
                     97:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_DUAL_PORT, 0, 0, 0},
                     98:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_SINGLE_PORT, 0, 0, 0},
                     99:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_CX4, 0, 0, 0},
                    100:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT, 0, 0, 0},
                    101:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT2, 0, 0, 0},
                    102:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598, 0, 0, 0},
                    103:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_DA_DUAL_PORT, 0, 0, 0},
                    104:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_CX4_DUAL_PORT, 0, 0, 0},
                    105:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_XF_LR, 0, 0, 0},
                    106:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM, 0, 0, 0},
                    107:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_SFP_LOM, 0, 0, 0},
                    108:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4, 0, 0, 0},
                    109:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4_MEZZ, 0, 0, 0},
                    110:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP, 0, 0, 0},
                    111:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_XAUI_LOM, 0, 0, 0},
                    112:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4, 0, 0, 0},
                    113:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_T3_LOM, 0, 0, 0},
                    114:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0},
                    115:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BACKPLANE_FCOE, 0, 0, 0},
1.21      msaitoh   116:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF2, 0, 0, 0},
1.1       dyoung    117:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
1.21      msaitoh   118:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
                    119:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP, 0, 0, 0},
1.43      msaitoh   120:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_QSFP_SF_QP, 0, 0, 0},
1.24      msaitoh   121:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
1.43      msaitoh   122:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0},
                    123:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T, 0, 0, 0},
1.48      msaitoh   124:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T1, 0, 0, 0},
1.43      msaitoh   125:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KR, 0, 0, 0},
                    126:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KX4, 0, 0, 0},
                    127:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_10G_T, 0, 0, 0},
1.99      msaitoh   128:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_1G_T, 0, 0, 0},
1.48      msaitoh   129:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_SFP, 0, 0, 0},
1.99      msaitoh   130:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR, 0, 0, 0},
                    131:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR_L, 0, 0, 0},
                    132:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP, 0, 0, 0},
                    133:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP_N, 0, 0, 0},
                    134:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII, 0, 0, 0},
                    135:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII_L, 0, 0, 0},
                    136:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_10G_T, 0, 0, 0},
                    137:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T, 0, 0, 0},
                    138:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T_L, 0, 0, 0},
                    139:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_BYPASS, 0, 0, 0},
                    140:        {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BYPASS, 0, 0, 0},
1.1       dyoung    141:        /* required last entry */
                    142:        {0, 0, 0, 0, 0}
                    143: };
                    144:
1.99      msaitoh   145: /************************************************************************
                    146:  * Table of branding strings
                    147:  ************************************************************************/
1.1       dyoung    148: static const char    *ixgbe_strings[] = {
                    149:        "Intel(R) PRO/10GbE PCI-Express Network Driver"
                    150: };
                    151:
1.99      msaitoh   152: /************************************************************************
                    153:  * Function prototypes
                    154:  ************************************************************************/
1.1       dyoung    155: static int      ixgbe_probe(device_t, cfdata_t, void *);
                    156: static void     ixgbe_attach(device_t, device_t, void *);
                    157: static int      ixgbe_detach(device_t, int);
                    158: #if 0
                    159: static int      ixgbe_shutdown(device_t);
                    160: #endif
1.44      msaitoh   161: static bool    ixgbe_suspend(device_t, const pmf_qual_t *);
                    162: static bool    ixgbe_resume(device_t, const pmf_qual_t *);
1.98      msaitoh   163: static int     ixgbe_ifflags_cb(struct ethercom *);
1.1       dyoung    164: static int      ixgbe_ioctl(struct ifnet *, u_long, void *);
                    165: static void    ixgbe_ifstop(struct ifnet *, int);
                    166: static int     ixgbe_init(struct ifnet *);
                    167: static void    ixgbe_init_locked(struct adapter *);
                    168: static void     ixgbe_stop(void *);
1.99      msaitoh   169: static void     ixgbe_init_device_features(struct adapter *);
                    170: static void     ixgbe_check_fan_failure(struct adapter *, u32, bool);
1.43      msaitoh   171: static void    ixgbe_add_media_types(struct adapter *);
1.1       dyoung    172: static void     ixgbe_media_status(struct ifnet *, struct ifmediareq *);
                    173: static int      ixgbe_media_change(struct ifnet *);
                    174: static int      ixgbe_allocate_pci_resources(struct adapter *,
                    175:                    const struct pci_attach_args *);
1.137     msaitoh   176: static void     ixgbe_free_softint(struct adapter *);
1.48      msaitoh   177: static void    ixgbe_get_slot_info(struct adapter *);
1.1       dyoung    178: static int      ixgbe_allocate_msix(struct adapter *,
                    179:                    const struct pci_attach_args *);
                    180: static int      ixgbe_allocate_legacy(struct adapter *,
                    181:                    const struct pci_attach_args *);
1.99      msaitoh   182: static int      ixgbe_configure_interrupts(struct adapter *);
1.119     msaitoh   183: static void    ixgbe_free_pciintr_resources(struct adapter *);
1.1       dyoung    184: static void    ixgbe_free_pci_resources(struct adapter *);
                    185: static void    ixgbe_local_timer(void *);
1.63      msaitoh   186: static void    ixgbe_local_timer1(void *);
1.1       dyoung    187: static int     ixgbe_setup_interface(device_t, struct adapter *);
1.45      msaitoh   188: static void    ixgbe_config_gpie(struct adapter *);
1.44      msaitoh   189: static void    ixgbe_config_dmac(struct adapter *);
                    190: static void    ixgbe_config_delay_values(struct adapter *);
1.1       dyoung    191: static void    ixgbe_config_link(struct adapter *);
1.44      msaitoh   192: static void    ixgbe_check_wol_support(struct adapter *);
                    193: static int     ixgbe_setup_low_power_mode(struct adapter *);
1.43      msaitoh   194: static void    ixgbe_rearm_queues(struct adapter *, u64);
1.1       dyoung    195:
                    196: static void     ixgbe_initialize_transmit_units(struct adapter *);
                    197: static void     ixgbe_initialize_receive_units(struct adapter *);
1.43      msaitoh   198: static void    ixgbe_enable_rx_drop(struct adapter *);
                    199: static void    ixgbe_disable_rx_drop(struct adapter *);
1.48      msaitoh   200: static void    ixgbe_initialize_rss_mapping(struct adapter *);
1.1       dyoung    201:
                    202: static void     ixgbe_enable_intr(struct adapter *);
                    203: static void     ixgbe_disable_intr(struct adapter *);
                    204: static void     ixgbe_update_stats_counters(struct adapter *);
                    205: static void     ixgbe_set_promisc(struct adapter *);
                    206: static void     ixgbe_set_multi(struct adapter *);
                    207: static void     ixgbe_update_link_status(struct adapter *);
                    208: static void    ixgbe_set_ivar(struct adapter *, u8, u8, s8);
                    209: static void    ixgbe_configure_ivars(struct adapter *);
                    210: static u8 *    ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
1.149   ! msaitoh   211: static void    ixgbe_eitr_write(struct adapter *, uint32_t, uint32_t);
1.1       dyoung    212:
                    213: static void    ixgbe_setup_vlan_hw_support(struct adapter *);
                    214: #if 0
                    215: static void    ixgbe_register_vlan(void *, struct ifnet *, u16);
                    216: static void    ixgbe_unregister_vlan(void *, struct ifnet *, u16);
                    217: #endif
                    218:
1.44      msaitoh   219: static void    ixgbe_add_device_sysctls(struct adapter *);
                    220: static void     ixgbe_add_hw_stats(struct adapter *);
1.85      msaitoh   221: static void    ixgbe_clear_evcnt(struct adapter *);
1.52      msaitoh   222: static int     ixgbe_set_flowcntl(struct adapter *, int);
                    223: static int     ixgbe_set_advertise(struct adapter *, int);
1.99      msaitoh   224: static int      ixgbe_get_advertise(struct adapter *);
1.44      msaitoh   225:
                    226: /* Sysctl handlers */
1.47      msaitoh   227: static void    ixgbe_set_sysctl_value(struct adapter *, const char *,
1.48      msaitoh   228:                     const char *, int *, int);
1.52      msaitoh   229: static int     ixgbe_sysctl_flowcntl(SYSCTLFN_PROTO);
                    230: static int     ixgbe_sysctl_advertise(SYSCTLFN_PROTO);
1.98      msaitoh   231: static int      ixgbe_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
1.44      msaitoh   232: static int     ixgbe_sysctl_dmac(SYSCTLFN_PROTO);
                    233: static int     ixgbe_sysctl_phy_temp(SYSCTLFN_PROTO);
                    234: static int     ixgbe_sysctl_phy_overtemp_occurred(SYSCTLFN_PROTO);
1.48      msaitoh   235: #ifdef IXGBE_DEBUG
                    236: static int     ixgbe_sysctl_power_state(SYSCTLFN_PROTO);
                    237: static int     ixgbe_sysctl_print_rss_config(SYSCTLFN_PROTO);
                    238: #endif
1.98      msaitoh   239: static int      ixgbe_sysctl_rdh_handler(SYSCTLFN_PROTO);
                    240: static int      ixgbe_sysctl_rdt_handler(SYSCTLFN_PROTO);
                    241: static int      ixgbe_sysctl_tdt_handler(SYSCTLFN_PROTO);
                    242: static int      ixgbe_sysctl_tdh_handler(SYSCTLFN_PROTO);
1.99      msaitoh   243: static int      ixgbe_sysctl_eee_state(SYSCTLFN_PROTO);
1.44      msaitoh   244: static int     ixgbe_sysctl_wol_enable(SYSCTLFN_PROTO);
                    245: static int     ixgbe_sysctl_wufc(SYSCTLFN_PROTO);
1.1       dyoung    246:
                    247: /* Support for pluggable optic modules */
                    248: static bool    ixgbe_sfp_probe(struct adapter *);
                    249:
1.99      msaitoh   250: /* Legacy (single vector) interrupt handler */
1.1       dyoung    251: static int     ixgbe_legacy_irq(void *);
                    252:
1.99      msaitoh   253: /* The MSI/MSI-X Interrupt handlers */
1.34      msaitoh   254: static int     ixgbe_msix_que(void *);
                    255: static int     ixgbe_msix_link(void *);
1.1       dyoung    256:
                    257: /* Software interrupts for deferred work */
                    258: static void    ixgbe_handle_que(void *);
                    259: static void    ixgbe_handle_link(void *);
                    260: static void    ixgbe_handle_msf(void *);
                    261: static void    ixgbe_handle_mod(void *);
1.44      msaitoh   262: static void    ixgbe_handle_phy(void *);
1.1       dyoung    263:
1.128     knakahar  264: /* Workqueue handler for deferred work */
                    265: static void    ixgbe_handle_que_work(struct work *, void *);
                    266:
1.1       dyoung    267: static ixgbe_vendor_info_t *ixgbe_lookup(const struct pci_attach_args *);
                    268:
1.99      msaitoh   269: /************************************************************************
                    270:  *  NetBSD Device Interface Entry Points
                    271:  ************************************************************************/
1.1       dyoung    272: CFATTACH_DECL3_NEW(ixg, sizeof(struct adapter),
                    273:     ixgbe_probe, ixgbe_attach, ixgbe_detach, NULL, NULL, NULL,
                    274:     DVF_DETACH_SHUTDOWN);
                    275:
                    276: #if 0
1.44      msaitoh   277: devclass_t ix_devclass;
                    278: DRIVER_MODULE(ix, pci, ix_driver, ix_devclass, 0, 0);
1.1       dyoung    279:
1.44      msaitoh   280: MODULE_DEPEND(ix, pci, 1, 1, 1);
                    281: MODULE_DEPEND(ix, ether, 1, 1, 1);
1.115     msaitoh   282: #ifdef DEV_NETMAP
                    283: MODULE_DEPEND(ix, netmap, 1, 1, 1);
                    284: #endif
1.1       dyoung    285: #endif
                    286:
                    287: /*
1.99      msaitoh   288:  * TUNEABLE PARAMETERS:
                    289:  */
1.1       dyoung    290:
                    291: /*
1.99      msaitoh   292:  * AIM: Adaptive Interrupt Moderation
                    293:  * which means that the interrupt rate
                    294:  * is varied over time based on the
                    295:  * traffic for that interrupt vector
                    296:  */
1.73      msaitoh   297: static bool ixgbe_enable_aim = true;
1.52      msaitoh   298: #define SYSCTL_INT(_a1, _a2, _a3, _a4, _a5, _a6, _a7)
1.99      msaitoh   299: SYSCTL_INT(_hw_ix, OID_AUTO, enable_aim, CTLFLAG_RDTUN, &ixgbe_enable_aim, 0,
1.52      msaitoh   300:     "Enable adaptive interrupt moderation");
1.1       dyoung    301:
1.22      msaitoh   302: static int ixgbe_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY);
1.52      msaitoh   303: SYSCTL_INT(_hw_ix, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN,
                    304:     &ixgbe_max_interrupt_rate, 0, "Maximum interrupts per second");
1.1       dyoung    305:
                    306: /* How many packets rxeof tries to clean at a time */
                    307: static int ixgbe_rx_process_limit = 256;
1.52      msaitoh   308: SYSCTL_INT(_hw_ix, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN,
1.99      msaitoh   309:     &ixgbe_rx_process_limit, 0, "Maximum number of received packets to process at a time, -1 means unlimited");
1.1       dyoung    310:
1.28      msaitoh   311: /* How many packets txeof tries to clean at a time */
                    312: static int ixgbe_tx_process_limit = 256;
1.52      msaitoh   313: SYSCTL_INT(_hw_ix, OID_AUTO, tx_process_limit, CTLFLAG_RDTUN,
                    314:     &ixgbe_tx_process_limit, 0,
1.99      msaitoh   315:     "Maximum number of sent packets to process at a time, -1 means unlimited");
1.52      msaitoh   316:
                    317: /* Flow control setting, default to full */
                    318: static int ixgbe_flow_control = ixgbe_fc_full;
                    319: SYSCTL_INT(_hw_ix, OID_AUTO, flow_control, CTLFLAG_RDTUN,
                    320:     &ixgbe_flow_control, 0, "Default flow control used for all adapters");
                    321:
1.128     knakahar  322: /* Which pakcet processing uses workqueue or softint */
                    323: static bool ixgbe_txrx_workqueue = false;
                    324:
1.1       dyoung    325: /*
1.99      msaitoh   326:  * Smart speed setting, default to on
                    327:  * this only works as a compile option
                    328:  * right now as its during attach, set
                    329:  * this to 'ixgbe_smart_speed_off' to
                    330:  * disable.
                    331:  */
1.1       dyoung    332: static int ixgbe_smart_speed = ixgbe_smart_speed_on;
                    333:
                    334: /*
1.99      msaitoh   335:  * MSI-X should be the default for best performance,
1.1       dyoung    336:  * but this allows it to be forced off for testing.
                    337:  */
                    338: static int ixgbe_enable_msix = 1;
1.52      msaitoh   339: SYSCTL_INT(_hw_ix, OID_AUTO, enable_msix, CTLFLAG_RDTUN, &ixgbe_enable_msix, 0,
                    340:     "Enable MSI-X interrupts");
1.1       dyoung    341:
                    342: /*
                    343:  * Number of Queues, can be set to 0,
                    344:  * it then autoconfigures based on the
                    345:  * number of cpus with a max of 8. This
                    346:  * can be overriden manually here.
                    347:  */
1.62      msaitoh   348: static int ixgbe_num_queues = 0;
1.52      msaitoh   349: SYSCTL_INT(_hw_ix, OID_AUTO, num_queues, CTLFLAG_RDTUN, &ixgbe_num_queues, 0,
                    350:     "Number of queues to configure, 0 indicates autoconfigure");
1.1       dyoung    351:
                    352: /*
1.99      msaitoh   353:  * Number of TX descriptors per ring,
                    354:  * setting higher than RX as this seems
                    355:  * the better performing choice.
                    356:  */
1.1       dyoung    357: static int ixgbe_txd = PERFORM_TXD;
1.52      msaitoh   358: SYSCTL_INT(_hw_ix, OID_AUTO, txd, CTLFLAG_RDTUN, &ixgbe_txd, 0,
                    359:     "Number of transmit descriptors per queue");
1.1       dyoung    360:
                    361: /* Number of RX descriptors per ring */
                    362: static int ixgbe_rxd = PERFORM_RXD;
1.52      msaitoh   363: SYSCTL_INT(_hw_ix, OID_AUTO, rxd, CTLFLAG_RDTUN, &ixgbe_rxd, 0,
                    364:     "Number of receive descriptors per queue");
1.33      msaitoh   365:
                    366: /*
1.99      msaitoh   367:  * Defining this on will allow the use
                    368:  * of unsupported SFP+ modules, note that
                    369:  * doing so you are on your own :)
                    370:  */
1.35      msaitoh   371: static int allow_unsupported_sfp = false;
1.52      msaitoh   372: #define TUNABLE_INT(__x, __y)
                    373: TUNABLE_INT("hw.ix.unsupported_sfp", &allow_unsupported_sfp);
1.1       dyoung    374:
1.99      msaitoh   375: /*
                    376:  * Not sure if Flow Director is fully baked,
                    377:  * so we'll default to turning it off.
                    378:  */
                    379: static int ixgbe_enable_fdir = 0;
                    380: SYSCTL_INT(_hw_ix, OID_AUTO, enable_fdir, CTLFLAG_RDTUN, &ixgbe_enable_fdir, 0,
                    381:     "Enable Flow Director");
                    382:
                    383: /* Legacy Transmit (single queue) */
                    384: static int ixgbe_enable_legacy_tx = 0;
                    385: SYSCTL_INT(_hw_ix, OID_AUTO, enable_legacy_tx, CTLFLAG_RDTUN,
                    386:     &ixgbe_enable_legacy_tx, 0, "Enable Legacy TX flow");
                    387:
                    388: /* Receive-Side Scaling */
                    389: static int ixgbe_enable_rss = 1;
                    390: SYSCTL_INT(_hw_ix, OID_AUTO, enable_rss, CTLFLAG_RDTUN, &ixgbe_enable_rss, 0,
                    391:     "Enable Receive-Side Scaling (RSS)");
                    392:
1.1       dyoung    393: /* Keep running tab on them for sanity check */
                    394: static int ixgbe_total_ports;
                    395:
1.99      msaitoh   396: #if 0
                    397: static int (*ixgbe_start_locked)(struct ifnet *, struct tx_ring *);
                    398: static int (*ixgbe_ring_empty)(struct ifnet *, pcq_t *);
1.1       dyoung    399: #endif
                    400:
1.80      msaitoh   401: #ifdef NET_MPSAFE
                    402: #define IXGBE_MPSAFE           1
                    403: #define IXGBE_CALLOUT_FLAGS    CALLOUT_MPSAFE
                    404: #define IXGBE_SOFTINFT_FLAGS   SOFTINT_MPSAFE
1.128     knakahar  405: #define IXGBE_WORKQUEUE_FLAGS  WQ_PERCPU | WQ_MPSAFE
1.80      msaitoh   406: #else
                    407: #define IXGBE_CALLOUT_FLAGS    0
                    408: #define IXGBE_SOFTINFT_FLAGS   0
1.128     knakahar  409: #define IXGBE_WORKQUEUE_FLAGS  WQ_PERCPU
1.80      msaitoh   410: #endif
1.128     knakahar  411: #define IXGBE_WORKQUEUE_PRI PRI_SOFTNET
1.80      msaitoh   412:
1.99      msaitoh   413: /************************************************************************
                    414:  * ixgbe_initialize_rss_mapping
                    415:  ************************************************************************/
1.98      msaitoh   416: static void
                    417: ixgbe_initialize_rss_mapping(struct adapter *adapter)
1.1       dyoung    418: {
1.98      msaitoh   419:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh   420:        u32             reta = 0, mrqc, rss_key[10];
                    421:        int             queue_id, table_size, index_mult;
                    422:        int             i, j;
                    423:        u32             rss_hash_config;
                    424:
1.122     knakahar  425:        /* force use default RSS key. */
                    426: #ifdef __NetBSD__
                    427:        rss_getkey((uint8_t *) &rss_key);
                    428: #else
1.99      msaitoh   429:        if (adapter->feat_en & IXGBE_FEATURE_RSS) {
                    430:                /* Fetch the configured RSS key */
                    431:                rss_getkey((uint8_t *) &rss_key);
                    432:        } else {
                    433:                /* set up random bits */
                    434:                cprng_fast(&rss_key, sizeof(rss_key));
                    435:        }
1.122     knakahar  436: #endif
1.1       dyoung    437:
1.98      msaitoh   438:        /* Set multiplier for RETA setup and table size based on MAC */
                    439:        index_mult = 0x1;
                    440:        table_size = 128;
                    441:        switch (adapter->hw.mac.type) {
                    442:        case ixgbe_mac_82598EB:
                    443:                index_mult = 0x11;
                    444:                break;
                    445:        case ixgbe_mac_X550:
                    446:        case ixgbe_mac_X550EM_x:
1.99      msaitoh   447:        case ixgbe_mac_X550EM_a:
1.98      msaitoh   448:                table_size = 512;
                    449:                break;
                    450:        default:
                    451:                break;
                    452:        }
1.1       dyoung    453:
1.98      msaitoh   454:        /* Set up the redirection table */
1.99      msaitoh   455:        for (i = 0, j = 0; i < table_size; i++, j++) {
                    456:                if (j == adapter->num_queues)
                    457:                        j = 0;
                    458:
                    459:                if (adapter->feat_en & IXGBE_FEATURE_RSS) {
                    460:                        /*
                    461:                         * Fetch the RSS bucket id for the given indirection
                    462:                         * entry. Cap it at the number of configured buckets
                    463:                         * (which is num_queues.)
                    464:                         */
                    465:                        queue_id = rss_get_indirection_to_bucket(i);
                    466:                        queue_id = queue_id % adapter->num_queues;
                    467:                } else
                    468:                        queue_id = (j * index_mult);
                    469:
1.98      msaitoh   470:                /*
                    471:                 * The low 8 bits are for hash value (n+0);
                    472:                 * The next 8 bits are for hash value (n+1), etc.
                    473:                 */
                    474:                reta = reta >> 8;
                    475:                reta = reta | (((uint32_t) queue_id) << 24);
                    476:                if ((i & 3) == 3) {
                    477:                        if (i < 128)
                    478:                                IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
                    479:                        else
1.99      msaitoh   480:                                IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32),
                    481:                                    reta);
1.98      msaitoh   482:                        reta = 0;
                    483:                }
                    484:        }
1.1       dyoung    485:
1.98      msaitoh   486:        /* Now fill our hash function seeds */
1.99      msaitoh   487:        for (i = 0; i < 10; i++)
1.98      msaitoh   488:                IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), rss_key[i]);
1.1       dyoung    489:
1.98      msaitoh   490:        /* Perform hash on these packet types */
1.99      msaitoh   491:        if (adapter->feat_en & IXGBE_FEATURE_RSS)
                    492:                rss_hash_config = rss_gethashconfig();
                    493:        else {
                    494:                /*
                    495:                 * Disable UDP - IP fragments aren't currently being handled
                    496:                 * and so we end up with a mix of 2-tuple and 4-tuple
                    497:                 * traffic.
                    498:                 */
                    499:                rss_hash_config = RSS_HASHTYPE_RSS_IPV4
                    500:                                | RSS_HASHTYPE_RSS_TCP_IPV4
                    501:                                | RSS_HASHTYPE_RSS_IPV6
                    502:                                | RSS_HASHTYPE_RSS_TCP_IPV6
                    503:                                | RSS_HASHTYPE_RSS_IPV6_EX
                    504:                                | RSS_HASHTYPE_RSS_TCP_IPV6_EX;
                    505:        }
                    506:
1.98      msaitoh   507:        mrqc = IXGBE_MRQC_RSSEN;
                    508:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
                    509:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4;
                    510:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
                    511:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP;
                    512:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
                    513:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6;
                    514:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
                    515:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
                    516:        if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
                    517:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX;
                    518:        if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX)
                    519:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP;
                    520:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
                    521:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
                    522:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
                    523:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
                    524:        if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX)
                    525:                mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
1.99      msaitoh   526:        mrqc |= ixgbe_get_mrqc(adapter->iov_mode);
1.98      msaitoh   527:        IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
1.99      msaitoh   528: } /* ixgbe_initialize_rss_mapping */
1.1       dyoung    529:
1.99      msaitoh   530: /************************************************************************
                    531:  * ixgbe_initialize_receive_units - Setup receive registers and features.
                    532:  ************************************************************************/
1.98      msaitoh   533: #define BSIZEPKT_ROUNDUP ((1<<IXGBE_SRRCTL_BSIZEPKT_SHIFT)-1)
                    534:
1.1       dyoung    535: static void
1.98      msaitoh   536: ixgbe_initialize_receive_units(struct adapter *adapter)
1.1       dyoung    537: {
1.98      msaitoh   538:        struct  rx_ring *rxr = adapter->rx_rings;
                    539:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh   540:        struct ifnet    *ifp = adapter->ifp;
                    541:        int             i, j;
1.98      msaitoh   542:        u32             bufsz, fctrl, srrctl, rxcsum;
                    543:        u32             hlreg;
                    544:
                    545:        /*
                    546:         * Make sure receives are disabled while
                    547:         * setting up the descriptor ring
                    548:         */
                    549:        ixgbe_disable_rx(hw);
1.1       dyoung    550:
1.98      msaitoh   551:        /* Enable broadcasts */
                    552:        fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
                    553:        fctrl |= IXGBE_FCTRL_BAM;
                    554:        if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
                    555:                fctrl |= IXGBE_FCTRL_DPF;
                    556:                fctrl |= IXGBE_FCTRL_PMCF;
                    557:        }
                    558:        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
1.1       dyoung    559:
1.98      msaitoh   560:        /* Set for Jumbo Frames? */
                    561:        hlreg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
                    562:        if (ifp->if_mtu > ETHERMTU)
                    563:                hlreg |= IXGBE_HLREG0_JUMBOEN;
                    564:        else
                    565:                hlreg &= ~IXGBE_HLREG0_JUMBOEN;
1.99      msaitoh   566:
1.98      msaitoh   567: #ifdef DEV_NETMAP
1.99      msaitoh   568:        /* CRC stripping is conditional in Netmap */
                    569:        if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) &&
                    570:            (ifp->if_capenable & IFCAP_NETMAP) &&
                    571:            !ix_crcstrip)
1.98      msaitoh   572:                hlreg &= ~IXGBE_HLREG0_RXCRCSTRP;
1.60      msaitoh   573:        else
1.99      msaitoh   574: #endif /* DEV_NETMAP */
1.98      msaitoh   575:                hlreg |= IXGBE_HLREG0_RXCRCSTRP;
1.99      msaitoh   576:
1.98      msaitoh   577:        IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg);
1.1       dyoung    578:
1.99      msaitoh   579:        bufsz = (adapter->rx_mbuf_sz + BSIZEPKT_ROUNDUP) >>
                    580:            IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1.1       dyoung    581:
1.98      msaitoh   582:        for (i = 0; i < adapter->num_queues; i++, rxr++) {
                    583:                u64 rdba = rxr->rxdma.dma_paddr;
                    584:                u32 tqsmreg, reg;
                    585:                int regnum = i / 4;     /* 1 register per 4 queues */
                    586:                int regshift = i % 4;   /* 4 bits per 1 queue */
1.99      msaitoh   587:                j = rxr->me;
1.1       dyoung    588:
1.98      msaitoh   589:                /* Setup the Base and Length of the Rx Descriptor Ring */
                    590:                IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j),
                    591:                    (rdba & 0x00000000ffffffffULL));
                    592:                IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
                    593:                IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j),
                    594:                    adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
1.1       dyoung    595:
1.98      msaitoh   596:                /* Set up the SRRCTL register */
                    597:                srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(j));
                    598:                srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
                    599:                srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
                    600:                srrctl |= bufsz;
                    601:                srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
1.47      msaitoh   602:
1.98      msaitoh   603:                /* Set RQSMR (Receive Queue Statistic Mapping) register */
                    604:                reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(regnum));
                    605:                reg &= ~(0x000000ff << (regshift * 8));
                    606:                reg |= i << (regshift * 8);
                    607:                IXGBE_WRITE_REG(hw, IXGBE_RQSMR(regnum), reg);
                    608:
                    609:                /*
                    610:                 * Set RQSMR (Receive Queue Statistic Mapping) register.
                    611:                 * Register location for queue 0...7 are different between
                    612:                 * 82598 and newer.
                    613:                 */
                    614:                if (adapter->hw.mac.type == ixgbe_mac_82598EB)
                    615:                        tqsmreg = IXGBE_TQSMR(regnum);
                    616:                else
                    617:                        tqsmreg = IXGBE_TQSM(regnum);
                    618:                reg = IXGBE_READ_REG(hw, tqsmreg);
                    619:                reg &= ~(0x000000ff << (regshift * 8));
                    620:                reg |= i << (regshift * 8);
                    621:                IXGBE_WRITE_REG(hw, tqsmreg, reg);
                    622:
                    623:                /*
                    624:                 * Set DROP_EN iff we have no flow control and >1 queue.
                    625:                 * Note that srrctl was cleared shortly before during reset,
                    626:                 * so we do not need to clear the bit, but do it just in case
                    627:                 * this code is moved elsewhere.
                    628:                 */
                    629:                if (adapter->num_queues > 1 &&
                    630:                    adapter->hw.fc.requested_mode == ixgbe_fc_none) {
                    631:                        srrctl |= IXGBE_SRRCTL_DROP_EN;
                    632:                } else {
                    633:                        srrctl &= ~IXGBE_SRRCTL_DROP_EN;
                    634:                }
                    635:
                    636:                IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(j), srrctl);
                    637:
                    638:                /* Setup the HW Rx Head and Tail Descriptor Pointers */
                    639:                IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
                    640:                IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
                    641:
                    642:                /* Set the driver rx tail address */
                    643:                rxr->tail =  IXGBE_RDT(rxr->me);
                    644:        }
                    645:
                    646:        if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
1.99      msaitoh   647:                u32 psrtype = IXGBE_PSRTYPE_TCPHDR
                    648:                            | IXGBE_PSRTYPE_UDPHDR
                    649:                            | IXGBE_PSRTYPE_IPV4HDR
                    650:                            | IXGBE_PSRTYPE_IPV6HDR;
1.98      msaitoh   651:                IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
                    652:        }
                    653:
                    654:        rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
                    655:
                    656:        ixgbe_initialize_rss_mapping(adapter);
                    657:
                    658:        if (adapter->num_queues > 1) {
                    659:                /* RSS and RX IPP Checksum are mutually exclusive */
                    660:                rxcsum |= IXGBE_RXCSUM_PCSD;
                    661:        }
                    662:
                    663:        if (ifp->if_capenable & IFCAP_RXCSUM)
                    664:                rxcsum |= IXGBE_RXCSUM_PCSD;
                    665:
                    666:        /* This is useful for calculating UDP/IP fragment checksums */
                    667:        if (!(rxcsum & IXGBE_RXCSUM_PCSD))
                    668:                rxcsum |= IXGBE_RXCSUM_IPPCSE;
                    669:
                    670:        IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
                    671:
1.99      msaitoh   672: } /* ixgbe_initialize_receive_units */
1.98      msaitoh   673:
1.99      msaitoh   674: /************************************************************************
                    675:  * ixgbe_initialize_transmit_units - Enable transmit units.
                    676:  ************************************************************************/
1.98      msaitoh   677: static void
                    678: ixgbe_initialize_transmit_units(struct adapter *adapter)
                    679: {
1.99      msaitoh   680:        struct tx_ring  *txr = adapter->tx_rings;
1.98      msaitoh   681:        struct ixgbe_hw *hw = &adapter->hw;
1.144     msaitoh   682:        int i;
1.98      msaitoh   683:
                    684:        /* Setup the Base and Length of the Tx Descriptor Ring */
1.144     msaitoh   685:        for (i = 0; i < adapter->num_queues; i++, txr++) {
1.99      msaitoh   686:                u64 tdba = txr->txdma.dma_paddr;
                    687:                u32 txctrl = 0;
                    688:                int j = txr->me;
1.98      msaitoh   689:
                    690:                IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
                    691:                    (tdba & 0x00000000ffffffffULL));
                    692:                IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
                    693:                IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j),
                    694:                    adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc));
                    695:
                    696:                /* Setup the HW Tx Head and Tail descriptor pointers */
                    697:                IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
                    698:                IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
                    699:
                    700:                /* Cache the tail address */
                    701:                txr->tail = IXGBE_TDT(j);
                    702:
                    703:                /* Disable Head Writeback */
                    704:                /*
                    705:                 * Note: for X550 series devices, these registers are actually
                    706:                 * prefixed with TPH_ isntead of DCA_, but the addresses and
                    707:                 * fields remain the same.
                    708:                 */
                    709:                switch (hw->mac.type) {
                    710:                case ixgbe_mac_82598EB:
                    711:                        txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
                    712:                        break;
                    713:                default:
                    714:                        txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
                    715:                        break;
                    716:                }
                    717:                txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
                    718:                switch (hw->mac.type) {
                    719:                case ixgbe_mac_82598EB:
                    720:                        IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
                    721:                        break;
                    722:                default:
                    723:                        IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
                    724:                        break;
                    725:                }
                    726:
                    727:        }
                    728:
                    729:        if (hw->mac.type != ixgbe_mac_82598EB) {
                    730:                u32 dmatxctl, rttdcs;
1.99      msaitoh   731:
1.98      msaitoh   732:                dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
                    733:                dmatxctl |= IXGBE_DMATXCTL_TE;
                    734:                IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
                    735:                /* Disable arbiter to set MTQC */
                    736:                rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
                    737:                rttdcs |= IXGBE_RTTDCS_ARBDIS;
                    738:                IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
1.99      msaitoh   739:                IXGBE_WRITE_REG(hw, IXGBE_MTQC,
                    740:                    ixgbe_get_mtqc(adapter->iov_mode));
1.98      msaitoh   741:                rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
                    742:                IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
                    743:        }
                    744:
                    745:        return;
1.99      msaitoh   746: } /* ixgbe_initialize_transmit_units */
1.98      msaitoh   747:
1.99      msaitoh   748: /************************************************************************
                    749:  * ixgbe_attach - Device initialization routine
1.98      msaitoh   750:  *
1.99      msaitoh   751:  *   Called when the driver is being loaded.
                    752:  *   Identifies the type of hardware, allocates all resources
                    753:  *   and initializes the hardware.
1.98      msaitoh   754:  *
1.99      msaitoh   755:  *   return 0 on success, positive on failure
                    756:  ************************************************************************/
1.98      msaitoh   757: static void
                    758: ixgbe_attach(device_t parent, device_t dev, void *aux)
                    759: {
1.99      msaitoh   760:        struct adapter  *adapter;
1.98      msaitoh   761:        struct ixgbe_hw *hw;
                    762:        int             error = -1;
                    763:        u32             ctrl_ext;
1.99      msaitoh   764:        u16             high, low, nvmreg;
                    765:        pcireg_t        id, subid;
1.98      msaitoh   766:        ixgbe_vendor_info_t *ent;
                    767:        struct pci_attach_args *pa = aux;
                    768:        const char *str;
1.99      msaitoh   769:        char buf[256];
1.98      msaitoh   770:
                    771:        INIT_DEBUGOUT("ixgbe_attach: begin");
                    772:
                    773:        /* Allocate, clear, and link in our adapter structure */
                    774:        adapter = device_private(dev);
1.99      msaitoh   775:        adapter->hw.back = adapter;
1.98      msaitoh   776:        adapter->dev = dev;
                    777:        hw = &adapter->hw;
                    778:        adapter->osdep.pc = pa->pa_pc;
                    779:        adapter->osdep.tag = pa->pa_tag;
                    780:        if (pci_dma64_available(pa))
                    781:                adapter->osdep.dmat = pa->pa_dmat64;
                    782:        else
                    783:                adapter->osdep.dmat = pa->pa_dmat;
                    784:        adapter->osdep.attached = false;
                    785:
                    786:        ent = ixgbe_lookup(pa);
                    787:
                    788:        KASSERT(ent != NULL);
                    789:
                    790:        aprint_normal(": %s, Version - %s\n",
                    791:            ixgbe_strings[ent->index], ixgbe_driver_version);
                    792:
                    793:        /* Core Lock Init*/
                    794:        IXGBE_CORE_LOCK_INIT(adapter, device_xname(dev));
1.1       dyoung    795:
                    796:        /* Set up the timer callout */
1.80      msaitoh   797:        callout_init(&adapter->timer, IXGBE_CALLOUT_FLAGS);
1.1       dyoung    798:
                    799:        /* Determine hardware revision */
1.99      msaitoh   800:        id = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
                    801:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                    802:
                    803:        hw->vendor_id = PCI_VENDOR(id);
                    804:        hw->device_id = PCI_PRODUCT(id);
                    805:        hw->revision_id =
                    806:            PCI_REVISION(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG));
                    807:        hw->subsystem_vendor_id = PCI_SUBSYS_VENDOR(subid);
                    808:        hw->subsystem_device_id = PCI_SUBSYS_ID(subid);
                    809:
                    810:        /*
                    811:         * Make sure BUSMASTER is set
                    812:         */
                    813:        ixgbe_pci_enable_busmaster(pa->pa_pc, pa->pa_tag);
                    814:
                    815:        /* Do base PCI setup - map BAR0 */
                    816:        if (ixgbe_allocate_pci_resources(adapter, pa)) {
                    817:                aprint_error_dev(dev, "Allocation of PCI resources failed\n");
                    818:                error = ENXIO;
                    819:                goto err_out;
                    820:        }
                    821:
                    822:        /* let hardware know driver is loaded */
                    823:        ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
                    824:        ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
                    825:        IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
                    826:
                    827:        /*
                    828:         * Initialize the shared code
                    829:         */
1.144     msaitoh   830:        if (ixgbe_init_shared_code(hw) != 0) {
1.99      msaitoh   831:                aprint_error_dev(dev, "Unable to initialize the shared code\n");
                    832:                error = ENXIO;
                    833:                goto err_out;
                    834:        }
1.1       dyoung    835:
1.79      msaitoh   836:        switch (hw->mac.type) {
                    837:        case ixgbe_mac_82598EB:
                    838:                str = "82598EB";
                    839:                break;
                    840:        case ixgbe_mac_82599EB:
                    841:                str = "82599EB";
                    842:                break;
                    843:        case ixgbe_mac_X540:
                    844:                str = "X540";
                    845:                break;
                    846:        case ixgbe_mac_X550:
                    847:                str = "X550";
                    848:                break;
                    849:        case ixgbe_mac_X550EM_x:
                    850:                str = "X550EM";
                    851:                break;
1.99      msaitoh   852:        case ixgbe_mac_X550EM_a:
                    853:                str = "X550EM A";
                    854:                break;
1.79      msaitoh   855:        default:
                    856:                str = "Unknown";
                    857:                break;
                    858:        }
                    859:        aprint_normal_dev(dev, "device %s\n", str);
                    860:
1.99      msaitoh   861:        if (hw->mbx.ops.init_params)
                    862:                hw->mbx.ops.init_params(hw);
                    863:
                    864:        hw->allow_unsupported_sfp = allow_unsupported_sfp;
                    865:
                    866:        /* Pick up the 82599 settings */
                    867:        if (hw->mac.type != ixgbe_mac_82598EB) {
                    868:                hw->phy.smart_speed = ixgbe_smart_speed;
                    869:                adapter->num_segs = IXGBE_82599_SCATTER;
                    870:        } else
                    871:                adapter->num_segs = IXGBE_82598_SCATTER;
                    872:
1.113     msaitoh   873:        hw->mac.ops.set_lan_id(hw);
1.99      msaitoh   874:        ixgbe_init_device_features(adapter);
                    875:
                    876:        if (ixgbe_configure_interrupts(adapter)) {
1.1       dyoung    877:                error = ENXIO;
                    878:                goto err_out;
                    879:        }
                    880:
1.99      msaitoh   881:        /* Allocate multicast array memory. */
                    882:        adapter->mta = malloc(sizeof(*adapter->mta) *
                    883:            MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
                    884:        if (adapter->mta == NULL) {
                    885:                aprint_error_dev(dev, "Cannot allocate multicast setup array\n");
                    886:                error = ENOMEM;
                    887:                goto err_out;
                    888:        }
                    889:
                    890:        /* Enable WoL (if supported) */
                    891:        ixgbe_check_wol_support(adapter);
                    892:
                    893:        /* Verify adapter fan is still functional (if applicable) */
                    894:        if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) {
                    895:                u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
                    896:                ixgbe_check_fan_failure(adapter, esdp, FALSE);
                    897:        }
                    898:
                    899:        /* Ensure SW/FW semaphore is free */
                    900:        ixgbe_init_swfw_semaphore(hw);
                    901:
                    902:        /* Enable EEE power saving */
                    903:        if (adapter->feat_en & IXGBE_FEATURE_EEE)
                    904:                hw->mac.ops.setup_eee(hw, TRUE);
                    905:
                    906:        /* Set an initial default flow control value */
                    907:        hw->fc.requested_mode = ixgbe_flow_control;
                    908:
1.47      msaitoh   909:        /* Sysctls for limiting the amount of work done in the taskqueues */
                    910:        ixgbe_set_sysctl_value(adapter, "rx_processing_limit",
                    911:            "max number of rx packets to process",
                    912:            &adapter->rx_process_limit, ixgbe_rx_process_limit);
                    913:
                    914:        ixgbe_set_sysctl_value(adapter, "tx_processing_limit",
                    915:            "max number of tx packets to process",
1.69      msaitoh   916:            &adapter->tx_process_limit, ixgbe_tx_process_limit);
1.47      msaitoh   917:
1.1       dyoung    918:        /* Do descriptor calc and sanity checks */
                    919:        if (((ixgbe_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
                    920:            ixgbe_txd < MIN_TXD || ixgbe_txd > MAX_TXD) {
                    921:                aprint_error_dev(dev, "TXD config issue, using default!\n");
                    922:                adapter->num_tx_desc = DEFAULT_TXD;
                    923:        } else
                    924:                adapter->num_tx_desc = ixgbe_txd;
                    925:
                    926:        /*
1.99      msaitoh   927:         * With many RX rings it is easy to exceed the
                    928:         * system mbuf allocation. Tuning nmbclusters
                    929:         * can alleviate this.
                    930:         */
1.43      msaitoh   931:        if (nmbclusters > 0) {
1.1       dyoung    932:                int s;
                    933:                s = (ixgbe_rxd * adapter->num_queues) * ixgbe_total_ports;
                    934:                if (s > nmbclusters) {
                    935:                        aprint_error_dev(dev, "RX Descriptors exceed "
                    936:                            "system mbuf max, using default instead!\n");
                    937:                        ixgbe_rxd = DEFAULT_RXD;
                    938:                }
                    939:        }
                    940:
                    941:        if (((ixgbe_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 ||
1.33      msaitoh   942:            ixgbe_rxd < MIN_RXD || ixgbe_rxd > MAX_RXD) {
1.1       dyoung    943:                aprint_error_dev(dev, "RXD config issue, using default!\n");
                    944:                adapter->num_rx_desc = DEFAULT_RXD;
                    945:        } else
                    946:                adapter->num_rx_desc = ixgbe_rxd;
                    947:
                    948:        /* Allocate our TX/RX Queues */
                    949:        if (ixgbe_allocate_queues(adapter)) {
                    950:                error = ENOMEM;
                    951:                goto err_out;
                    952:        }
                    953:
1.99      msaitoh   954:        hw->phy.reset_if_overtemp = TRUE;
                    955:        error = ixgbe_reset_hw(hw);
                    956:        hw->phy.reset_if_overtemp = FALSE;
1.1       dyoung    957:        if (error == IXGBE_ERR_SFP_NOT_PRESENT) {
                    958:                /*
1.99      msaitoh   959:                 * No optics in this port, set up
                    960:                 * so the timer routine will probe
                    961:                 * for later insertion.
                    962:                 */
1.1       dyoung    963:                adapter->sfp_probe = TRUE;
1.99      msaitoh   964:                error = IXGBE_SUCCESS;
1.35      msaitoh   965:        } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) {
1.48      msaitoh   966:                aprint_error_dev(dev, "Unsupported SFP+ module detected!\n");
1.1       dyoung    967:                error = EIO;
                    968:                goto err_late;
                    969:        } else if (error) {
1.99      msaitoh   970:                aprint_error_dev(dev, "Hardware initialization failed\n");
1.1       dyoung    971:                error = EIO;
                    972:                goto err_late;
                    973:        }
                    974:
                    975:        /* Make sure we have a good EEPROM before we read from it */
1.99      msaitoh   976:        if (ixgbe_validate_eeprom_checksum(&adapter->hw, NULL) < 0) {
1.48      msaitoh   977:                aprint_error_dev(dev, "The EEPROM Checksum Is Not Valid\n");
1.1       dyoung    978:                error = EIO;
                    979:                goto err_late;
                    980:        }
                    981:
1.88      msaitoh   982:        aprint_normal("%s:", device_xname(dev));
                    983:        /* NVM Image Version */
                    984:        switch (hw->mac.type) {
                    985:        case ixgbe_mac_X540:
1.99      msaitoh   986:        case ixgbe_mac_X550EM_a:
1.88      msaitoh   987:                hw->eeprom.ops.read(hw, IXGBE_NVM_IMAGE_VER, &nvmreg);
                    988:                if (nvmreg == 0xffff)
                    989:                        break;
                    990:                high = (nvmreg >> 12) & 0x0f;
                    991:                low = (nvmreg >> 4) & 0xff;
                    992:                id = nvmreg & 0x0f;
1.107     msaitoh   993:                aprint_normal(" NVM Image Version %u.", high);
                    994:                if (hw->mac.type == ixgbe_mac_X540)
                    995:                        str = "%x";
                    996:                else
                    997:                        str = "%02x";
                    998:                aprint_normal(str, low);
                    999:                aprint_normal(" ID 0x%x,", id);
1.88      msaitoh  1000:                break;
                   1001:        case ixgbe_mac_X550EM_x:
                   1002:        case ixgbe_mac_X550:
                   1003:                hw->eeprom.ops.read(hw, IXGBE_NVM_IMAGE_VER, &nvmreg);
                   1004:                if (nvmreg == 0xffff)
                   1005:                        break;
                   1006:                high = (nvmreg >> 12) & 0x0f;
                   1007:                low = nvmreg & 0xff;
1.107     msaitoh  1008:                aprint_normal(" NVM Image Version %u.%02x,", high, low);
1.88      msaitoh  1009:                break;
                   1010:        default:
                   1011:                break;
                   1012:        }
                   1013:
                   1014:        /* PHY firmware revision */
                   1015:        switch (hw->mac.type) {
                   1016:        case ixgbe_mac_X540:
                   1017:        case ixgbe_mac_X550:
                   1018:                hw->eeprom.ops.read(hw, IXGBE_PHYFW_REV, &nvmreg);
                   1019:                if (nvmreg == 0xffff)
                   1020:                        break;
                   1021:                high = (nvmreg >> 12) & 0x0f;
                   1022:                low = (nvmreg >> 4) & 0xff;
                   1023:                id = nvmreg & 0x000f;
1.114     msaitoh  1024:                aprint_normal(" PHY FW Revision %u.", high);
                   1025:                if (hw->mac.type == ixgbe_mac_X540)
                   1026:                        str = "%x";
                   1027:                else
                   1028:                        str = "%02x";
                   1029:                aprint_normal(str, low);
                   1030:                aprint_normal(" ID 0x%x,", id);
1.88      msaitoh  1031:                break;
                   1032:        default:
                   1033:                break;
                   1034:        }
                   1035:
                   1036:        /* NVM Map version & OEM NVM Image version */
                   1037:        switch (hw->mac.type) {
                   1038:        case ixgbe_mac_X550:
                   1039:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  1040:        case ixgbe_mac_X550EM_a:
1.88      msaitoh  1041:                hw->eeprom.ops.read(hw, IXGBE_NVM_MAP_VER, &nvmreg);
                   1042:                if (nvmreg != 0xffff) {
                   1043:                        high = (nvmreg >> 12) & 0x0f;
                   1044:                        low = nvmreg & 0x00ff;
                   1045:                        aprint_normal(" NVM Map version %u.%02x,", high, low);
                   1046:                }
                   1047:                hw->eeprom.ops.read(hw, IXGBE_OEM_NVM_IMAGE_VER, &nvmreg);
1.107     msaitoh  1048:                if (nvmreg != 0xffff) {
1.88      msaitoh  1049:                        high = (nvmreg >> 12) & 0x0f;
                   1050:                        low = nvmreg & 0x00ff;
                   1051:                        aprint_verbose(" OEM NVM Image version %u.%02x,", high,
                   1052:                            low);
                   1053:                }
                   1054:                break;
                   1055:        default:
                   1056:                break;
                   1057:        }
                   1058:
                   1059:        /* Print the ETrackID */
                   1060:        hw->eeprom.ops.read(hw, IXGBE_ETRACKID_H, &high);
                   1061:        hw->eeprom.ops.read(hw, IXGBE_ETRACKID_L, &low);
                   1062:        aprint_normal(" ETrackID %08x\n", ((uint32_t)high << 16) | low);
1.79      msaitoh  1063:
1.119     msaitoh  1064:        if (adapter->feat_en & IXGBE_FEATURE_MSIX) {
1.99      msaitoh  1065:                error = ixgbe_allocate_msix(adapter, pa);
1.119     msaitoh  1066:                if (error) {
                   1067:                        /* Free allocated queue structures first */
                   1068:                        ixgbe_free_transmit_structures(adapter);
                   1069:                        ixgbe_free_receive_structures(adapter);
                   1070:                        free(adapter->queues, M_DEVBUF);
                   1071:
                   1072:                        /* Fallback to legacy interrupt */
                   1073:                        adapter->feat_en &= ~IXGBE_FEATURE_MSIX;
                   1074:                        if (adapter->feat_cap & IXGBE_FEATURE_MSI)
                   1075:                                adapter->feat_en |= IXGBE_FEATURE_MSI;
                   1076:                        adapter->num_queues = 1;
                   1077:
                   1078:                        /* Allocate our TX/RX Queues again */
                   1079:                        if (ixgbe_allocate_queues(adapter)) {
                   1080:                                error = ENOMEM;
                   1081:                                goto err_out;
                   1082:                        }
                   1083:                }
                   1084:        }
                   1085:        if ((adapter->feat_en & IXGBE_FEATURE_MSIX) == 0)
1.99      msaitoh  1086:                error = ixgbe_allocate_legacy(adapter, pa);
                   1087:        if (error)
                   1088:                goto err_late;
                   1089:
1.119     msaitoh  1090:        /* Tasklets for Link, SFP, Multispeed Fiber and Flow Director */
                   1091:        adapter->link_si = softint_establish(SOFTINT_NET |IXGBE_SOFTINFT_FLAGS,
                   1092:            ixgbe_handle_link, adapter);
                   1093:        adapter->mod_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   1094:            ixgbe_handle_mod, adapter);
                   1095:        adapter->msf_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   1096:            ixgbe_handle_msf, adapter);
                   1097:        adapter->phy_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   1098:            ixgbe_handle_phy, adapter);
                   1099:        if (adapter->feat_en & IXGBE_FEATURE_FDIR)
                   1100:                adapter->fdir_si =
                   1101:                    softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   1102:                        ixgbe_reinit_fdir, adapter);
                   1103:        if ((adapter->link_si == NULL) || (adapter->mod_si == NULL)
                   1104:            || (adapter->msf_si == NULL) || (adapter->phy_si == NULL)
                   1105:            || ((adapter->feat_en & IXGBE_FEATURE_FDIR)
                   1106:                && (adapter->fdir_si == NULL))) {
                   1107:                aprint_error_dev(dev,
                   1108:                    "could not establish software interrupts ()\n");
                   1109:                goto err_out;
                   1110:        }
                   1111:
1.99      msaitoh  1112:        error = ixgbe_start_hw(hw);
1.25      msaitoh  1113:        switch (error) {
                   1114:        case IXGBE_ERR_EEPROM_VERSION:
1.1       dyoung   1115:                aprint_error_dev(dev, "This device is a pre-production adapter/"
                   1116:                    "LOM.  Please be aware there may be issues associated "
1.48      msaitoh  1117:                    "with your hardware.\nIf you are experiencing problems "
1.1       dyoung   1118:                    "please contact your Intel or hardware representative "
                   1119:                    "who provided you with this hardware.\n");
1.25      msaitoh  1120:                break;
                   1121:        case IXGBE_ERR_SFP_NOT_SUPPORTED:
1.48      msaitoh  1122:                aprint_error_dev(dev, "Unsupported SFP+ Module\n");
1.1       dyoung   1123:                error = EIO;
                   1124:                goto err_late;
1.25      msaitoh  1125:        case IXGBE_ERR_SFP_NOT_PRESENT:
1.48      msaitoh  1126:                aprint_error_dev(dev, "No SFP+ Module found\n");
1.25      msaitoh  1127:                /* falls thru */
                   1128:        default:
                   1129:                break;
1.1       dyoung   1130:        }
                   1131:
1.116     msaitoh  1132:        /* Setup OS specific network interface */
                   1133:        if (ixgbe_setup_interface(dev, adapter) != 0)
                   1134:                goto err_late;
                   1135:
1.110     msaitoh  1136:        /*
                   1137:         *  Print PHY ID only for copper PHY. On device which has SFP(+) cage
                   1138:         * and a module is inserted, phy.id is not MII PHY id but SFF 8024 ID.
                   1139:         */
                   1140:        if (hw->phy.media_type == ixgbe_media_type_copper) {
1.95      msaitoh  1141:                uint16_t id1, id2;
                   1142:                int oui, model, rev;
                   1143:                const char *descr;
                   1144:
                   1145:                id1 = hw->phy.id >> 16;
                   1146:                id2 = hw->phy.id & 0xffff;
                   1147:                oui = MII_OUI(id1, id2);
                   1148:                model = MII_MODEL(id2);
                   1149:                rev = MII_REV(id2);
                   1150:                if ((descr = mii_get_descr(oui, model)) != NULL)
                   1151:                        aprint_normal_dev(dev,
                   1152:                            "PHY: %s (OUI 0x%06x, model 0x%04x), rev. %d\n",
                   1153:                            descr, oui, model, rev);
                   1154:                else
                   1155:                        aprint_normal_dev(dev,
                   1156:                            "PHY OUI 0x%06x, model 0x%04x, rev. %d\n",
                   1157:                            oui, model, rev);
                   1158:        }
                   1159:
1.52      msaitoh  1160:        /* Enable the optics for 82599 SFP+ fiber */
                   1161:        ixgbe_enable_tx_laser(hw);
                   1162:
                   1163:        /* Enable power to the phy. */
                   1164:        ixgbe_set_phy_power(hw, TRUE);
                   1165:
1.1       dyoung   1166:        /* Initialize statistics */
                   1167:        ixgbe_update_stats_counters(adapter);
                   1168:
1.98      msaitoh  1169:        /* Check PCIE slot type/speed/width */
1.48      msaitoh  1170:        ixgbe_get_slot_info(adapter);
1.1       dyoung   1171:
1.99      msaitoh  1172:        /*
                   1173:         * Do time init and sysctl init here, but
                   1174:         * only on the first port of a bypass adapter.
                   1175:         */
                   1176:        ixgbe_bypass_init(adapter);
                   1177:
                   1178:        /* Set an initial dmac value */
1.48      msaitoh  1179:        adapter->dmac = 0;
1.99      msaitoh  1180:        /* Set initial advertised speeds (if applicable) */
                   1181:        adapter->advertise = ixgbe_get_advertise(adapter);
1.45      msaitoh  1182:
1.99      msaitoh  1183:        if (adapter->feat_cap & IXGBE_FEATURE_SRIOV)
                   1184:                ixgbe_define_iov_schemas(dev, &error);
1.44      msaitoh  1185:
                   1186:        /* Add sysctls */
                   1187:        ixgbe_add_device_sysctls(adapter);
                   1188:        ixgbe_add_hw_stats(adapter);
                   1189:
1.99      msaitoh  1190:        /* For Netmap */
                   1191:        adapter->init_locked = ixgbe_init_locked;
                   1192:        adapter->stop_locked = ixgbe_stop;
                   1193:
                   1194:        if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
                   1195:                ixgbe_netmap_attach(adapter);
1.1       dyoung   1196:
1.99      msaitoh  1197:        snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_cap);
                   1198:        aprint_verbose_dev(dev, "feature cap %s\n", buf);
                   1199:        snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_en);
                   1200:        aprint_verbose_dev(dev, "feature ena %s\n", buf);
1.44      msaitoh  1201:
                   1202:        if (pmf_device_register(dev, ixgbe_suspend, ixgbe_resume))
                   1203:                pmf_class_network_register(dev, adapter->ifp);
                   1204:        else
                   1205:                aprint_error_dev(dev, "couldn't establish power handler\n");
                   1206:
1.1       dyoung   1207:        INIT_DEBUGOUT("ixgbe_attach: end");
1.32      msaitoh  1208:        adapter->osdep.attached = true;
1.98      msaitoh  1209:
1.1       dyoung   1210:        return;
1.43      msaitoh  1211:
1.1       dyoung   1212: err_late:
                   1213:        ixgbe_free_transmit_structures(adapter);
                   1214:        ixgbe_free_receive_structures(adapter);
1.99      msaitoh  1215:        free(adapter->queues, M_DEVBUF);
1.1       dyoung   1216: err_out:
1.99      msaitoh  1217:        ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
                   1218:        ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD;
                   1219:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext);
1.119     msaitoh  1220:        ixgbe_free_softint(adapter);
1.1       dyoung   1221:        ixgbe_free_pci_resources(adapter);
                   1222:        if (adapter->mta != NULL)
                   1223:                free(adapter->mta, M_DEVBUF);
1.99      msaitoh  1224:        IXGBE_CORE_LOCK_DESTROY(adapter);
                   1225:
1.1       dyoung   1226:        return;
1.99      msaitoh  1227: } /* ixgbe_attach */
1.1       dyoung   1228:
1.99      msaitoh  1229: /************************************************************************
                   1230:  * ixgbe_check_wol_support
                   1231:  *
                   1232:  *   Checks whether the adapter's ports are capable of
                   1233:  *   Wake On LAN by reading the adapter's NVM.
1.1       dyoung   1234:  *
1.99      msaitoh  1235:  *   Sets each port's hw->wol_enabled value depending
                   1236:  *   on the value read here.
                   1237:  ************************************************************************/
1.98      msaitoh  1238: static void
                   1239: ixgbe_check_wol_support(struct adapter *adapter)
                   1240: {
                   1241:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  1242:        u16             dev_caps = 0;
1.1       dyoung   1243:
1.98      msaitoh  1244:        /* Find out WoL support for port */
                   1245:        adapter->wol_support = hw->wol_enabled = 0;
                   1246:        ixgbe_get_device_caps(hw, &dev_caps);
                   1247:        if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
                   1248:            ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) &&
1.99      msaitoh  1249:             hw->bus.func == 0))
1.98      msaitoh  1250:                adapter->wol_support = hw->wol_enabled = 1;
                   1251:
                   1252:        /* Save initial wake up filter configuration */
                   1253:        adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC);
                   1254:
                   1255:        return;
1.99      msaitoh  1256: } /* ixgbe_check_wol_support */
1.98      msaitoh  1257:
1.99      msaitoh  1258: /************************************************************************
                   1259:  * ixgbe_setup_interface
1.98      msaitoh  1260:  *
1.99      msaitoh  1261:  *   Setup networking device structure and register an interface.
                   1262:  ************************************************************************/
1.1       dyoung   1263: static int
1.98      msaitoh  1264: ixgbe_setup_interface(device_t dev, struct adapter *adapter)
1.1       dyoung   1265: {
1.98      msaitoh  1266:        struct ethercom *ec = &adapter->osdep.ec;
                   1267:        struct ifnet   *ifp;
1.106     msaitoh  1268:        int rv;
1.1       dyoung   1269:
1.98      msaitoh  1270:        INIT_DEBUGOUT("ixgbe_setup_interface: begin");
1.1       dyoung   1271:
1.98      msaitoh  1272:        ifp = adapter->ifp = &ec->ec_if;
                   1273:        strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ);
                   1274:        ifp->if_baudrate = IF_Gbps(10);
                   1275:        ifp->if_init = ixgbe_init;
                   1276:        ifp->if_stop = ixgbe_ifstop;
                   1277:        ifp->if_softc = adapter;
                   1278:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                   1279: #ifdef IXGBE_MPSAFE
1.112     ozaki-r  1280:        ifp->if_extflags = IFEF_MPSAFE;
1.98      msaitoh  1281: #endif
                   1282:        ifp->if_ioctl = ixgbe_ioctl;
                   1283: #if __FreeBSD_version >= 1100045
                   1284:        /* TSO parameters */
                   1285:        ifp->if_hw_tsomax = 65518;
                   1286:        ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER;
                   1287:        ifp->if_hw_tsomaxsegsize = 2048;
                   1288: #endif
1.99      msaitoh  1289:        if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) {
                   1290: #if 0
                   1291:                ixgbe_start_locked = ixgbe_legacy_start_locked;
                   1292: #endif
                   1293:        } else {
                   1294:                ifp->if_transmit = ixgbe_mq_start;
                   1295: #if 0
                   1296:                ixgbe_start_locked = ixgbe_mq_start_locked;
1.29      msaitoh  1297: #endif
1.99      msaitoh  1298:        }
                   1299:        ifp->if_start = ixgbe_legacy_start;
1.98      msaitoh  1300:        IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
                   1301:        IFQ_SET_READY(&ifp->if_snd);
                   1302:
1.106     msaitoh  1303:        rv = if_initialize(ifp);
                   1304:        if (rv != 0) {
                   1305:                aprint_error_dev(dev, "if_initialize failed(%d)\n", rv);
                   1306:                return rv;
                   1307:        }
1.98      msaitoh  1308:        adapter->ipq = if_percpuq_create(&adapter->osdep.ec.ec_if);
                   1309:        ether_ifattach(ifp, adapter->hw.mac.addr);
                   1310:        /*
                   1311:         * We use per TX queue softint, so if_deferred_start_init() isn't
                   1312:         * used.
                   1313:         */
                   1314:        if_register(ifp);
                   1315:        ether_set_ifflags_cb(ec, ixgbe_ifflags_cb);
                   1316:
1.99      msaitoh  1317:        adapter->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
1.98      msaitoh  1318:
                   1319:        /*
                   1320:         * Tell the upper layer(s) we support long frames.
                   1321:         */
                   1322:        ifp->if_hdrlen = sizeof(struct ether_vlan_header);
                   1323:
                   1324:        /* Set capability flags */
                   1325:        ifp->if_capabilities |= IFCAP_RXCSUM
                   1326:                             |  IFCAP_TXCSUM
                   1327:                             |  IFCAP_TSOv4
                   1328:                             |  IFCAP_TSOv6
                   1329:                             |  IFCAP_LRO;
                   1330:        ifp->if_capenable = 0;
                   1331:
                   1332:        ec->ec_capabilities |= ETHERCAP_VLAN_HWTAGGING
                   1333:                            |  ETHERCAP_VLAN_HWCSUM
                   1334:                            |  ETHERCAP_JUMBO_MTU
                   1335:                            |  ETHERCAP_VLAN_MTU;
                   1336:
                   1337:        /* Enable the above capabilities by default */
                   1338:        ec->ec_capenable = ec->ec_capabilities;
                   1339:
                   1340:        /*
1.99      msaitoh  1341:         * Don't turn this on by default, if vlans are
                   1342:         * created on another pseudo device (eg. lagg)
                   1343:         * then vlan events are not passed thru, breaking
                   1344:         * operation, but with HW FILTER off it works. If
                   1345:         * using vlans directly on the ixgbe driver you can
                   1346:         * enable this and get full hardware tag filtering.
                   1347:         */
1.98      msaitoh  1348:        ec->ec_capabilities |= ETHERCAP_VLAN_HWFILTER;
1.1       dyoung   1349:
1.98      msaitoh  1350:        /*
                   1351:         * Specify the media types supported by this adapter and register
                   1352:         * callbacks to update media and link information
                   1353:         */
                   1354:        ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change,
                   1355:            ixgbe_media_status);
1.45      msaitoh  1356:
1.98      msaitoh  1357:        adapter->phy_layer = ixgbe_get_supported_physical_layer(&adapter->hw);
                   1358:        ixgbe_add_media_types(adapter);
1.49      msaitoh  1359:
1.98      msaitoh  1360:        /* Set autoselect media by default */
                   1361:        ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1.1       dyoung   1362:
1.98      msaitoh  1363:        return (0);
1.99      msaitoh  1364: } /* ixgbe_setup_interface */
1.1       dyoung   1365:
1.99      msaitoh  1366: /************************************************************************
                   1367:  * ixgbe_add_media_types
                   1368:  ************************************************************************/
1.98      msaitoh  1369: static void
                   1370: ixgbe_add_media_types(struct adapter *adapter)
                   1371: {
                   1372:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  1373:        device_t        dev = adapter->dev;
                   1374:        u64             layer;
1.1       dyoung   1375:
1.98      msaitoh  1376:        layer = adapter->phy_layer;
1.1       dyoung   1377:
1.98      msaitoh  1378: #define        ADD(mm, dd)                                                     \
                   1379:        ifmedia_add(&adapter->media, IFM_ETHER | (mm), (dd), NULL);
1.1       dyoung   1380:
1.140     msaitoh  1381:        ADD(IFM_NONE, 0);
                   1382:
1.98      msaitoh  1383:        /* Media types with matching NetBSD media defines */
                   1384:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
                   1385:                ADD(IFM_10G_T | IFM_FDX, 0);
                   1386:        }
                   1387:        if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) {
                   1388:                ADD(IFM_1000_T | IFM_FDX, 0);
                   1389:        }
                   1390:        if (layer & IXGBE_PHYSICAL_LAYER_100BASE_TX) {
                   1391:                ADD(IFM_100_TX | IFM_FDX, 0);
                   1392:        }
1.99      msaitoh  1393:        if (layer & IXGBE_PHYSICAL_LAYER_10BASE_T) {
                   1394:                ADD(IFM_10_T | IFM_FDX, 0);
                   1395:        }
1.26      msaitoh  1396:
1.98      msaitoh  1397:        if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU ||
                   1398:            layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) {
                   1399:                ADD(IFM_10G_TWINAX | IFM_FDX, 0);
                   1400:        }
1.1       dyoung   1401:
1.98      msaitoh  1402:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) {
                   1403:                ADD(IFM_10G_LR | IFM_FDX, 0);
                   1404:                if (hw->phy.multispeed_fiber) {
                   1405:                        ADD(IFM_1000_LX | IFM_FDX, 0);
1.72      msaitoh  1406:                }
1.98      msaitoh  1407:        }
                   1408:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) {
                   1409:                ADD(IFM_10G_SR | IFM_FDX, 0);
                   1410:                if (hw->phy.multispeed_fiber) {
                   1411:                        ADD(IFM_1000_SX | IFM_FDX, 0);
1.1       dyoung   1412:                }
1.98      msaitoh  1413:        } else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) {
                   1414:                ADD(IFM_1000_SX | IFM_FDX, 0);
                   1415:        }
                   1416:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) {
                   1417:                ADD(IFM_10G_CX4 | IFM_FDX, 0);
                   1418:        }
1.1       dyoung   1419:
1.98      msaitoh  1420: #ifdef IFM_ETH_XTYPE
                   1421:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) {
                   1422:                ADD(IFM_10G_KR | IFM_FDX, 0);
                   1423:        }
                   1424:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) {
                   1425:                ADD(AIFM_10G_KX4 | IFM_FDX, 0);
                   1426:        }
                   1427: #else
                   1428:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) {
                   1429:                device_printf(dev, "Media supported: 10GbaseKR\n");
                   1430:                device_printf(dev, "10GbaseKR mapped to 10GbaseSR\n");
                   1431:                ADD(IFM_10G_SR | IFM_FDX, 0);
                   1432:        }
                   1433:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) {
                   1434:                device_printf(dev, "Media supported: 10GbaseKX4\n");
                   1435:                device_printf(dev, "10GbaseKX4 mapped to 10GbaseCX4\n");
                   1436:                ADD(IFM_10G_CX4 | IFM_FDX, 0);
                   1437:        }
                   1438: #endif
                   1439:        if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) {
                   1440:                ADD(IFM_1000_KX | IFM_FDX, 0);
                   1441:        }
1.99      msaitoh  1442:        if (layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX) {
                   1443:                ADD(IFM_2500_KX | IFM_FDX, 0);
                   1444:        }
1.103     msaitoh  1445:        if (layer & IXGBE_PHYSICAL_LAYER_2500BASE_T) {
                   1446:                ADD(IFM_2500_T | IFM_FDX, 0);
                   1447:        }
                   1448:        if (layer & IXGBE_PHYSICAL_LAYER_5GBASE_T) {
                   1449:                ADD(IFM_5000_T | IFM_FDX, 0);
                   1450:        }
1.98      msaitoh  1451:        if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX)
                   1452:                device_printf(dev, "Media supported: 1000baseBX\n");
                   1453:        /* XXX no ifmedia_set? */
                   1454:
                   1455:        ADD(IFM_AUTO, 0);
                   1456:
                   1457: #undef ADD
1.99      msaitoh  1458: } /* ixgbe_add_media_types */
1.1       dyoung   1459:
1.99      msaitoh  1460: /************************************************************************
                   1461:  * ixgbe_is_sfp
                   1462:  ************************************************************************/
                   1463: static inline bool
                   1464: ixgbe_is_sfp(struct ixgbe_hw *hw)
                   1465: {
                   1466:        switch (hw->mac.type) {
                   1467:        case ixgbe_mac_82598EB:
                   1468:                if (hw->phy.type == ixgbe_phy_nl)
1.144     msaitoh  1469:                        return (TRUE);
                   1470:                return (FALSE);
1.99      msaitoh  1471:        case ixgbe_mac_82599EB:
                   1472:                switch (hw->mac.ops.get_media_type(hw)) {
                   1473:                case ixgbe_media_type_fiber:
                   1474:                case ixgbe_media_type_fiber_qsfp:
1.144     msaitoh  1475:                        return (TRUE);
1.99      msaitoh  1476:                default:
1.144     msaitoh  1477:                        return (FALSE);
1.99      msaitoh  1478:                }
                   1479:        case ixgbe_mac_X550EM_x:
                   1480:        case ixgbe_mac_X550EM_a:
                   1481:                if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
1.144     msaitoh  1482:                        return (TRUE);
                   1483:                return (FALSE);
1.99      msaitoh  1484:        default:
1.144     msaitoh  1485:                return (FALSE);
1.99      msaitoh  1486:        }
                   1487: } /* ixgbe_is_sfp */
                   1488:
                   1489: /************************************************************************
                   1490:  * ixgbe_config_link
                   1491:  ************************************************************************/
1.98      msaitoh  1492: static void
                   1493: ixgbe_config_link(struct adapter *adapter)
                   1494: {
                   1495:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  1496:        u32             autoneg, err = 0;
                   1497:        bool            sfp, negotiate = false;
1.1       dyoung   1498:
1.98      msaitoh  1499:        sfp = ixgbe_is_sfp(hw);
1.1       dyoung   1500:
1.98      msaitoh  1501:        if (sfp) {
1.99      msaitoh  1502:                if (hw->phy.multispeed_fiber) {
                   1503:                        ixgbe_enable_tx_laser(hw);
                   1504:                        kpreempt_disable();
                   1505:                        softint_schedule(adapter->msf_si);
                   1506:                        kpreempt_enable();
                   1507:                }
1.144     msaitoh  1508:                kpreempt_disable();
                   1509:                softint_schedule(adapter->mod_si);
                   1510:                kpreempt_enable();
1.98      msaitoh  1511:        } else {
1.143     msaitoh  1512:                struct ifmedia  *ifm = &adapter->media;
                   1513:
1.98      msaitoh  1514:                if (hw->mac.ops.check_link)
                   1515:                        err = ixgbe_check_link(hw, &adapter->link_speed,
                   1516:                            &adapter->link_up, FALSE);
                   1517:                if (err)
1.144     msaitoh  1518:                        return;
1.143     msaitoh  1519:
                   1520:                /*
                   1521:                 * Check if it's the first call. If it's the first call,
                   1522:                 * get value for auto negotiation.
                   1523:                 */
1.98      msaitoh  1524:                autoneg = hw->phy.autoneg_advertised;
1.143     msaitoh  1525:                if ((IFM_SUBTYPE(ifm->ifm_cur->ifm_media) != IFM_NONE)
                   1526:                    && ((!autoneg) && (hw->mac.ops.get_link_capabilities)))
1.99      msaitoh  1527:                        err = hw->mac.ops.get_link_capabilities(hw, &autoneg,
                   1528:                            &negotiate);
1.98      msaitoh  1529:                if (err)
1.144     msaitoh  1530:                        return;
1.98      msaitoh  1531:                if (hw->mac.ops.setup_link)
1.99      msaitoh  1532:                        err = hw->mac.ops.setup_link(hw, autoneg,
                   1533:                            adapter->link_up);
1.98      msaitoh  1534:        }
1.99      msaitoh  1535:
                   1536: } /* ixgbe_config_link */
1.98      msaitoh  1537:
1.99      msaitoh  1538: /************************************************************************
                   1539:  * ixgbe_update_stats_counters - Update board statistics counters.
                   1540:  ************************************************************************/
1.98      msaitoh  1541: static void
                   1542: ixgbe_update_stats_counters(struct adapter *adapter)
1.1       dyoung   1543: {
1.99      msaitoh  1544:        struct ifnet          *ifp = adapter->ifp;
                   1545:        struct ixgbe_hw       *hw = &adapter->hw;
1.98      msaitoh  1546:        struct ixgbe_hw_stats *stats = &adapter->stats.pf;
1.99      msaitoh  1547:        u32                   missed_rx = 0, bprc, lxon, lxoff, total;
                   1548:        u64                   total_missed_rx = 0;
                   1549:        uint64_t              crcerrs, rlec;
1.44      msaitoh  1550:
1.98      msaitoh  1551:        crcerrs = IXGBE_READ_REG(hw, IXGBE_CRCERRS);
                   1552:        stats->crcerrs.ev_count += crcerrs;
                   1553:        stats->illerrc.ev_count += IXGBE_READ_REG(hw, IXGBE_ILLERRC);
                   1554:        stats->errbc.ev_count += IXGBE_READ_REG(hw, IXGBE_ERRBC);
                   1555:        stats->mspdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MSPDC);
                   1556:        if (hw->mac.type == ixgbe_mac_X550)
                   1557:                stats->mbsdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MBSDC);
1.44      msaitoh  1558:
1.98      msaitoh  1559:        for (int i = 0; i < __arraycount(stats->qprc); i++) {
                   1560:                int j = i % adapter->num_queues;
                   1561:                stats->qprc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
                   1562:                stats->qptc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
                   1563:                stats->qprdc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
                   1564:        }
                   1565:        for (int i = 0; i < __arraycount(stats->mpc); i++) {
                   1566:                uint32_t mp;
                   1567:                int j = i % adapter->num_queues;
1.44      msaitoh  1568:
1.98      msaitoh  1569:                mp = IXGBE_READ_REG(hw, IXGBE_MPC(i));
                   1570:                /* global total per queue */
                   1571:                stats->mpc[j].ev_count += mp;
                   1572:                /* running comprehensive total for stats display */
                   1573:                total_missed_rx += mp;
1.44      msaitoh  1574:
1.98      msaitoh  1575:                if (hw->mac.type == ixgbe_mac_82598EB)
                   1576:                        stats->rnbc[j].ev_count
                   1577:                            += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
                   1578:
                   1579:        }
                   1580:        stats->mpctotal.ev_count += total_missed_rx;
1.44      msaitoh  1581:
1.98      msaitoh  1582:        /* Document says M[LR]FC are valid when link is up and 10Gbps */
                   1583:        if ((adapter->link_active == TRUE)
                   1584:            && (adapter->link_speed == IXGBE_LINK_SPEED_10GB_FULL)) {
                   1585:                stats->mlfc.ev_count += IXGBE_READ_REG(hw, IXGBE_MLFC);
                   1586:                stats->mrfc.ev_count += IXGBE_READ_REG(hw, IXGBE_MRFC);
                   1587:        }
                   1588:        rlec = IXGBE_READ_REG(hw, IXGBE_RLEC);
                   1589:        stats->rlec.ev_count += rlec;
1.44      msaitoh  1590:
1.98      msaitoh  1591:        /* Hardware workaround, gprc counts missed packets */
                   1592:        stats->gprc.ev_count += IXGBE_READ_REG(hw, IXGBE_GPRC) - missed_rx;
1.44      msaitoh  1593:
1.98      msaitoh  1594:        lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
                   1595:        stats->lxontxc.ev_count += lxon;
                   1596:        lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
                   1597:        stats->lxofftxc.ev_count += lxoff;
                   1598:        total = lxon + lxoff;
1.44      msaitoh  1599:
1.98      msaitoh  1600:        if (hw->mac.type != ixgbe_mac_82598EB) {
                   1601:                stats->gorc.ev_count += IXGBE_READ_REG(hw, IXGBE_GORCL) +
                   1602:                    ((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32);
                   1603:                stats->gotc.ev_count += IXGBE_READ_REG(hw, IXGBE_GOTCL) +
                   1604:                    ((u64)IXGBE_READ_REG(hw, IXGBE_GOTCH) << 32) - total * ETHER_MIN_LEN;
                   1605:                stats->tor.ev_count += IXGBE_READ_REG(hw, IXGBE_TORL) +
                   1606:                    ((u64)IXGBE_READ_REG(hw, IXGBE_TORH) << 32);
                   1607:                stats->lxonrxc.ev_count += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
                   1608:                stats->lxoffrxc.ev_count += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
                   1609:        } else {
                   1610:                stats->lxonrxc.ev_count += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
                   1611:                stats->lxoffrxc.ev_count += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
                   1612:                /* 82598 only has a counter in the high register */
                   1613:                stats->gorc.ev_count += IXGBE_READ_REG(hw, IXGBE_GORCH);
                   1614:                stats->gotc.ev_count += IXGBE_READ_REG(hw, IXGBE_GOTCH) - total * ETHER_MIN_LEN;
                   1615:                stats->tor.ev_count += IXGBE_READ_REG(hw, IXGBE_TORH);
                   1616:        }
1.44      msaitoh  1617:
1.98      msaitoh  1618:        /*
                   1619:         * Workaround: mprc hardware is incorrectly counting
                   1620:         * broadcasts, so for now we subtract those.
                   1621:         */
                   1622:        bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
                   1623:        stats->bprc.ev_count += bprc;
1.99      msaitoh  1624:        stats->mprc.ev_count += IXGBE_READ_REG(hw, IXGBE_MPRC)
                   1625:            - ((hw->mac.type == ixgbe_mac_82598EB) ? bprc : 0);
1.44      msaitoh  1626:
1.98      msaitoh  1627:        stats->prc64.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC64);
                   1628:        stats->prc127.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC127);
                   1629:        stats->prc255.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC255);
                   1630:        stats->prc511.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC511);
                   1631:        stats->prc1023.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC1023);
                   1632:        stats->prc1522.ev_count += IXGBE_READ_REG(hw, IXGBE_PRC1522);
1.44      msaitoh  1633:
1.98      msaitoh  1634:        stats->gptc.ev_count += IXGBE_READ_REG(hw, IXGBE_GPTC) - total;
                   1635:        stats->mptc.ev_count += IXGBE_READ_REG(hw, IXGBE_MPTC) - total;
                   1636:        stats->ptc64.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC64) - total;
1.44      msaitoh  1637:
1.98      msaitoh  1638:        stats->ruc.ev_count += IXGBE_READ_REG(hw, IXGBE_RUC);
                   1639:        stats->rfc.ev_count += IXGBE_READ_REG(hw, IXGBE_RFC);
                   1640:        stats->roc.ev_count += IXGBE_READ_REG(hw, IXGBE_ROC);
                   1641:        stats->rjc.ev_count += IXGBE_READ_REG(hw, IXGBE_RJC);
                   1642:        stats->mngprc.ev_count += IXGBE_READ_REG(hw, IXGBE_MNGPRC);
                   1643:        stats->mngpdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MNGPDC);
                   1644:        stats->mngptc.ev_count += IXGBE_READ_REG(hw, IXGBE_MNGPTC);
                   1645:        stats->tpr.ev_count += IXGBE_READ_REG(hw, IXGBE_TPR);
                   1646:        stats->tpt.ev_count += IXGBE_READ_REG(hw, IXGBE_TPT);
                   1647:        stats->ptc127.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC127);
                   1648:        stats->ptc255.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC255);
                   1649:        stats->ptc511.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC511);
                   1650:        stats->ptc1023.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC1023);
                   1651:        stats->ptc1522.ev_count += IXGBE_READ_REG(hw, IXGBE_PTC1522);
                   1652:        stats->bptc.ev_count += IXGBE_READ_REG(hw, IXGBE_BPTC);
                   1653:        stats->xec.ev_count += IXGBE_READ_REG(hw, IXGBE_XEC);
                   1654:        stats->fccrc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCCRC);
                   1655:        stats->fclast.ev_count += IXGBE_READ_REG(hw, IXGBE_FCLAST);
                   1656:        /* Only read FCOE on 82599 */
                   1657:        if (hw->mac.type != ixgbe_mac_82598EB) {
                   1658:                stats->fcoerpdc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
                   1659:                stats->fcoeprc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
                   1660:                stats->fcoeptc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
                   1661:                stats->fcoedwrc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
                   1662:                stats->fcoedwtc.ev_count += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
                   1663:        }
1.44      msaitoh  1664:
1.98      msaitoh  1665:        /* Fill out the OS statistics structure */
1.44      msaitoh  1666:        /*
1.98      msaitoh  1667:         * NetBSD: Don't override if_{i|o}{packets|bytes|mcasts} with
                   1668:         * adapter->stats counters. It's required to make ifconfig -z
                   1669:         * (SOICZIFDATA) work.
1.44      msaitoh  1670:         */
1.98      msaitoh  1671:        ifp->if_collisions = 0;
1.44      msaitoh  1672:
1.98      msaitoh  1673:        /* Rx Errors */
                   1674:        ifp->if_iqdrops += total_missed_rx;
                   1675:        ifp->if_ierrors += crcerrs + rlec;
1.99      msaitoh  1676: } /* ixgbe_update_stats_counters */
1.1       dyoung   1677:
1.99      msaitoh  1678: /************************************************************************
                   1679:  * ixgbe_add_hw_stats
                   1680:  *
                   1681:  *   Add sysctl variables, one per statistic, to the system.
                   1682:  ************************************************************************/
1.98      msaitoh  1683: static void
                   1684: ixgbe_add_hw_stats(struct adapter *adapter)
1.1       dyoung   1685: {
1.98      msaitoh  1686:        device_t dev = adapter->dev;
                   1687:        const struct sysctlnode *rnode, *cnode;
                   1688:        struct sysctllog **log = &adapter->sysctllog;
                   1689:        struct tx_ring *txr = adapter->tx_rings;
                   1690:        struct rx_ring *rxr = adapter->rx_rings;
                   1691:        struct ixgbe_hw *hw = &adapter->hw;
                   1692:        struct ixgbe_hw_stats *stats = &adapter->stats.pf;
                   1693:        const char *xname = device_xname(dev);
1.144     msaitoh  1694:        int i;
1.1       dyoung   1695:
1.98      msaitoh  1696:        /* Driver Statistics */
                   1697:        evcnt_attach_dynamic(&adapter->efbig_tx_dma_setup, EVCNT_TYPE_MISC,
                   1698:            NULL, xname, "Driver tx dma soft fail EFBIG");
                   1699:        evcnt_attach_dynamic(&adapter->mbuf_defrag_failed, EVCNT_TYPE_MISC,
                   1700:            NULL, xname, "m_defrag() failed");
                   1701:        evcnt_attach_dynamic(&adapter->efbig2_tx_dma_setup, EVCNT_TYPE_MISC,
                   1702:            NULL, xname, "Driver tx dma hard fail EFBIG");
                   1703:        evcnt_attach_dynamic(&adapter->einval_tx_dma_setup, EVCNT_TYPE_MISC,
                   1704:            NULL, xname, "Driver tx dma hard fail EINVAL");
                   1705:        evcnt_attach_dynamic(&adapter->other_tx_dma_setup, EVCNT_TYPE_MISC,
                   1706:            NULL, xname, "Driver tx dma hard fail other");
                   1707:        evcnt_attach_dynamic(&adapter->eagain_tx_dma_setup, EVCNT_TYPE_MISC,
                   1708:            NULL, xname, "Driver tx dma soft fail EAGAIN");
                   1709:        evcnt_attach_dynamic(&adapter->enomem_tx_dma_setup, EVCNT_TYPE_MISC,
                   1710:            NULL, xname, "Driver tx dma soft fail ENOMEM");
                   1711:        evcnt_attach_dynamic(&adapter->watchdog_events, EVCNT_TYPE_MISC,
                   1712:            NULL, xname, "Watchdog timeouts");
                   1713:        evcnt_attach_dynamic(&adapter->tso_err, EVCNT_TYPE_MISC,
                   1714:            NULL, xname, "TSO errors");
                   1715:        evcnt_attach_dynamic(&adapter->link_irq, EVCNT_TYPE_INTR,
1.99      msaitoh  1716:            NULL, xname, "Link MSI-X IRQ Handled");
1.137     msaitoh  1717:        evcnt_attach_dynamic(&adapter->link_sicount, EVCNT_TYPE_INTR,
                   1718:            NULL, xname, "Link softint");
                   1719:        evcnt_attach_dynamic(&adapter->mod_sicount, EVCNT_TYPE_INTR,
                   1720:            NULL, xname, "module softint");
                   1721:        evcnt_attach_dynamic(&adapter->msf_sicount, EVCNT_TYPE_INTR,
                   1722:            NULL, xname, "multimode softint");
                   1723:        evcnt_attach_dynamic(&adapter->phy_sicount, EVCNT_TYPE_INTR,
                   1724:            NULL, xname, "external PHY softint");
1.1       dyoung   1725:
1.144     msaitoh  1726:        for (i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
1.135     msaitoh  1727: #ifdef LRO
                   1728:                struct lro_ctrl *lro = &rxr->lro;
                   1729: #endif /* LRO */
                   1730:
1.98      msaitoh  1731:                snprintf(adapter->queues[i].evnamebuf,
                   1732:                    sizeof(adapter->queues[i].evnamebuf), "%s q%d",
                   1733:                    xname, i);
                   1734:                snprintf(adapter->queues[i].namebuf,
                   1735:                    sizeof(adapter->queues[i].namebuf), "q%d", i);
1.1       dyoung   1736:
1.98      msaitoh  1737:                if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL) {
                   1738:                        aprint_error_dev(dev, "could not create sysctl root\n");
                   1739:                        break;
                   1740:                }
1.1       dyoung   1741:
1.98      msaitoh  1742:                if (sysctl_createv(log, 0, &rnode, &rnode,
                   1743:                    0, CTLTYPE_NODE,
                   1744:                    adapter->queues[i].namebuf, SYSCTL_DESCR("Queue Name"),
                   1745:                    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
                   1746:                        break;
1.23      msaitoh  1747:
1.98      msaitoh  1748:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   1749:                    CTLFLAG_READWRITE, CTLTYPE_INT,
                   1750:                    "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"),
                   1751:                    ixgbe_sysctl_interrupt_rate_handler, 0,
                   1752:                    (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0)
                   1753:                        break;
1.1       dyoung   1754:
1.98      msaitoh  1755:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   1756:                    CTLFLAG_READONLY, CTLTYPE_INT,
                   1757:                    "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"),
                   1758:                    ixgbe_sysctl_tdh_handler, 0, (void *)txr,
                   1759:                    0, CTL_CREATE, CTL_EOL) != 0)
                   1760:                        break;
1.1       dyoung   1761:
1.98      msaitoh  1762:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   1763:                    CTLFLAG_READONLY, CTLTYPE_INT,
                   1764:                    "txd_tail", SYSCTL_DESCR("Transmit Descriptor Tail"),
                   1765:                    ixgbe_sysctl_tdt_handler, 0, (void *)txr,
                   1766:                    0, CTL_CREATE, CTL_EOL) != 0)
                   1767:                        break;
1.1       dyoung   1768:
1.98      msaitoh  1769:                evcnt_attach_dynamic(&adapter->queues[i].irqs, EVCNT_TYPE_INTR,
                   1770:                    NULL, adapter->queues[i].evnamebuf, "IRQs on queue");
1.129     msaitoh  1771:                evcnt_attach_dynamic(&adapter->queues[i].handleq,
                   1772:                    EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1773:                    "Handled queue in softint");
                   1774:                evcnt_attach_dynamic(&adapter->queues[i].req, EVCNT_TYPE_MISC,
                   1775:                    NULL, adapter->queues[i].evnamebuf, "Requeued in softint");
1.98      msaitoh  1776:                evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC,
                   1777:                    NULL, adapter->queues[i].evnamebuf, "TSO");
                   1778:                evcnt_attach_dynamic(&txr->no_desc_avail, EVCNT_TYPE_MISC,
                   1779:                    NULL, adapter->queues[i].evnamebuf,
                   1780:                    "Queue No Descriptor Available");
                   1781:                evcnt_attach_dynamic(&txr->total_packets, EVCNT_TYPE_MISC,
                   1782:                    NULL, adapter->queues[i].evnamebuf,
                   1783:                    "Queue Packets Transmitted");
                   1784: #ifndef IXGBE_LEGACY_TX
                   1785:                evcnt_attach_dynamic(&txr->pcq_drops, EVCNT_TYPE_MISC,
                   1786:                    NULL, adapter->queues[i].evnamebuf,
                   1787:                    "Packets dropped in pcq");
1.67      msaitoh  1788: #endif
1.1       dyoung   1789:
1.98      msaitoh  1790:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   1791:                    CTLFLAG_READONLY,
                   1792:                    CTLTYPE_INT,
                   1793:                    "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"),
                   1794:                    ixgbe_sysctl_rdh_handler, 0, (void *)rxr, 0,
                   1795:                    CTL_CREATE, CTL_EOL) != 0)
1.33      msaitoh  1796:                        break;
1.98      msaitoh  1797:
                   1798:                if (sysctl_createv(log, 0, &rnode, &cnode,
                   1799:                    CTLFLAG_READONLY,
                   1800:                    CTLTYPE_INT,
                   1801:                    "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"),
                   1802:                    ixgbe_sysctl_rdt_handler, 0, (void *)rxr, 0,
                   1803:                    CTL_CREATE, CTL_EOL) != 0)
1.28      msaitoh  1804:                        break;
1.98      msaitoh  1805:
                   1806:                if (i < __arraycount(stats->mpc)) {
                   1807:                        evcnt_attach_dynamic(&stats->mpc[i],
                   1808:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
1.99      msaitoh  1809:                            "RX Missed Packet Count");
1.98      msaitoh  1810:                        if (hw->mac.type == ixgbe_mac_82598EB)
                   1811:                                evcnt_attach_dynamic(&stats->rnbc[i],
                   1812:                                    EVCNT_TYPE_MISC, NULL,
                   1813:                                    adapter->queues[i].evnamebuf,
                   1814:                                    "Receive No Buffers");
                   1815:                }
                   1816:                if (i < __arraycount(stats->pxontxc)) {
                   1817:                        evcnt_attach_dynamic(&stats->pxontxc[i],
                   1818:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1819:                            "pxontxc");
                   1820:                        evcnt_attach_dynamic(&stats->pxonrxc[i],
                   1821:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1822:                            "pxonrxc");
                   1823:                        evcnt_attach_dynamic(&stats->pxofftxc[i],
                   1824:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1825:                            "pxofftxc");
                   1826:                        evcnt_attach_dynamic(&stats->pxoffrxc[i],
                   1827:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1828:                            "pxoffrxc");
                   1829:                        evcnt_attach_dynamic(&stats->pxon2offc[i],
                   1830:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1831:                            "pxon2offc");
1.33      msaitoh  1832:                }
1.98      msaitoh  1833:                if (i < __arraycount(stats->qprc)) {
                   1834:                        evcnt_attach_dynamic(&stats->qprc[i],
                   1835:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1836:                            "qprc");
                   1837:                        evcnt_attach_dynamic(&stats->qptc[i],
                   1838:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1839:                            "qptc");
                   1840:                        evcnt_attach_dynamic(&stats->qbrc[i],
                   1841:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1842:                            "qbrc");
                   1843:                        evcnt_attach_dynamic(&stats->qbtc[i],
                   1844:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1845:                            "qbtc");
                   1846:                        evcnt_attach_dynamic(&stats->qprdc[i],
                   1847:                            EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
                   1848:                            "qprdc");
1.28      msaitoh  1849:                }
1.33      msaitoh  1850:
1.98      msaitoh  1851:                evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC,
                   1852:                    NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");
                   1853:                evcnt_attach_dynamic(&rxr->rx_bytes, EVCNT_TYPE_MISC,
                   1854:                    NULL, adapter->queues[i].evnamebuf, "Queue Bytes Received");
                   1855:                evcnt_attach_dynamic(&rxr->rx_copies, EVCNT_TYPE_MISC,
                   1856:                    NULL, adapter->queues[i].evnamebuf, "Copied RX Frames");
                   1857:                evcnt_attach_dynamic(&rxr->no_jmbuf, EVCNT_TYPE_MISC,
                   1858:                    NULL, adapter->queues[i].evnamebuf, "Rx no jumbo mbuf");
                   1859:                evcnt_attach_dynamic(&rxr->rx_discarded, EVCNT_TYPE_MISC,
                   1860:                    NULL, adapter->queues[i].evnamebuf, "Rx discarded");
                   1861: #ifdef LRO
                   1862:                SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_queued",
                   1863:                                CTLFLAG_RD, &lro->lro_queued, 0,
                   1864:                                "LRO Queued");
                   1865:                SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_flushed",
                   1866:                                CTLFLAG_RD, &lro->lro_flushed, 0,
                   1867:                                "LRO Flushed");
                   1868: #endif /* LRO */
1.1       dyoung   1869:        }
1.28      msaitoh  1870:
1.99      msaitoh  1871:        /* MAC stats get their own sub node */
1.98      msaitoh  1872:
                   1873:        snprintf(stats->namebuf,
                   1874:            sizeof(stats->namebuf), "%s MAC Statistics", xname);
                   1875:
                   1876:        evcnt_attach_dynamic(&stats->ipcs, EVCNT_TYPE_MISC, NULL,
                   1877:            stats->namebuf, "rx csum offload - IP");
                   1878:        evcnt_attach_dynamic(&stats->l4cs, EVCNT_TYPE_MISC, NULL,
                   1879:            stats->namebuf, "rx csum offload - L4");
                   1880:        evcnt_attach_dynamic(&stats->ipcs_bad, EVCNT_TYPE_MISC, NULL,
                   1881:            stats->namebuf, "rx csum offload - IP bad");
                   1882:        evcnt_attach_dynamic(&stats->l4cs_bad, EVCNT_TYPE_MISC, NULL,
                   1883:            stats->namebuf, "rx csum offload - L4 bad");
                   1884:        evcnt_attach_dynamic(&stats->intzero, EVCNT_TYPE_MISC, NULL,
                   1885:            stats->namebuf, "Interrupt conditions zero");
                   1886:        evcnt_attach_dynamic(&stats->legint, EVCNT_TYPE_MISC, NULL,
                   1887:            stats->namebuf, "Legacy interrupts");
1.99      msaitoh  1888:
1.98      msaitoh  1889:        evcnt_attach_dynamic(&stats->crcerrs, EVCNT_TYPE_MISC, NULL,
                   1890:            stats->namebuf, "CRC Errors");
                   1891:        evcnt_attach_dynamic(&stats->illerrc, EVCNT_TYPE_MISC, NULL,
                   1892:            stats->namebuf, "Illegal Byte Errors");
                   1893:        evcnt_attach_dynamic(&stats->errbc, EVCNT_TYPE_MISC, NULL,
                   1894:            stats->namebuf, "Byte Errors");
                   1895:        evcnt_attach_dynamic(&stats->mspdc, EVCNT_TYPE_MISC, NULL,
                   1896:            stats->namebuf, "MAC Short Packets Discarded");
                   1897:        if (hw->mac.type >= ixgbe_mac_X550)
                   1898:                evcnt_attach_dynamic(&stats->mbsdc, EVCNT_TYPE_MISC, NULL,
                   1899:                    stats->namebuf, "Bad SFD");
                   1900:        evcnt_attach_dynamic(&stats->mpctotal, EVCNT_TYPE_MISC, NULL,
                   1901:            stats->namebuf, "Total Packets Missed");
                   1902:        evcnt_attach_dynamic(&stats->mlfc, EVCNT_TYPE_MISC, NULL,
                   1903:            stats->namebuf, "MAC Local Faults");
                   1904:        evcnt_attach_dynamic(&stats->mrfc, EVCNT_TYPE_MISC, NULL,
                   1905:            stats->namebuf, "MAC Remote Faults");
                   1906:        evcnt_attach_dynamic(&stats->rlec, EVCNT_TYPE_MISC, NULL,
                   1907:            stats->namebuf, "Receive Length Errors");
                   1908:        evcnt_attach_dynamic(&stats->lxontxc, EVCNT_TYPE_MISC, NULL,
                   1909:            stats->namebuf, "Link XON Transmitted");
                   1910:        evcnt_attach_dynamic(&stats->lxonrxc, EVCNT_TYPE_MISC, NULL,
                   1911:            stats->namebuf, "Link XON Received");
                   1912:        evcnt_attach_dynamic(&stats->lxofftxc, EVCNT_TYPE_MISC, NULL,
                   1913:            stats->namebuf, "Link XOFF Transmitted");
                   1914:        evcnt_attach_dynamic(&stats->lxoffrxc, EVCNT_TYPE_MISC, NULL,
                   1915:            stats->namebuf, "Link XOFF Received");
                   1916:
                   1917:        /* Packet Reception Stats */
                   1918:        evcnt_attach_dynamic(&stats->tor, EVCNT_TYPE_MISC, NULL,
                   1919:            stats->namebuf, "Total Octets Received");
                   1920:        evcnt_attach_dynamic(&stats->gorc, EVCNT_TYPE_MISC, NULL,
                   1921:            stats->namebuf, "Good Octets Received");
                   1922:        evcnt_attach_dynamic(&stats->tpr, EVCNT_TYPE_MISC, NULL,
                   1923:            stats->namebuf, "Total Packets Received");
                   1924:        evcnt_attach_dynamic(&stats->gprc, EVCNT_TYPE_MISC, NULL,
                   1925:            stats->namebuf, "Good Packets Received");
                   1926:        evcnt_attach_dynamic(&stats->mprc, EVCNT_TYPE_MISC, NULL,
                   1927:            stats->namebuf, "Multicast Packets Received");
                   1928:        evcnt_attach_dynamic(&stats->bprc, EVCNT_TYPE_MISC, NULL,
                   1929:            stats->namebuf, "Broadcast Packets Received");
                   1930:        evcnt_attach_dynamic(&stats->prc64, EVCNT_TYPE_MISC, NULL,
                   1931:            stats->namebuf, "64 byte frames received ");
                   1932:        evcnt_attach_dynamic(&stats->prc127, EVCNT_TYPE_MISC, NULL,
                   1933:            stats->namebuf, "65-127 byte frames received");
                   1934:        evcnt_attach_dynamic(&stats->prc255, EVCNT_TYPE_MISC, NULL,
                   1935:            stats->namebuf, "128-255 byte frames received");
                   1936:        evcnt_attach_dynamic(&stats->prc511, EVCNT_TYPE_MISC, NULL,
                   1937:            stats->namebuf, "256-511 byte frames received");
                   1938:        evcnt_attach_dynamic(&stats->prc1023, EVCNT_TYPE_MISC, NULL,
                   1939:            stats->namebuf, "512-1023 byte frames received");
                   1940:        evcnt_attach_dynamic(&stats->prc1522, EVCNT_TYPE_MISC, NULL,
                   1941:            stats->namebuf, "1023-1522 byte frames received");
                   1942:        evcnt_attach_dynamic(&stats->ruc, EVCNT_TYPE_MISC, NULL,
                   1943:            stats->namebuf, "Receive Undersized");
                   1944:        evcnt_attach_dynamic(&stats->rfc, EVCNT_TYPE_MISC, NULL,
                   1945:            stats->namebuf, "Fragmented Packets Received ");
                   1946:        evcnt_attach_dynamic(&stats->roc, EVCNT_TYPE_MISC, NULL,
                   1947:            stats->namebuf, "Oversized Packets Received");
                   1948:        evcnt_attach_dynamic(&stats->rjc, EVCNT_TYPE_MISC, NULL,
                   1949:            stats->namebuf, "Received Jabber");
                   1950:        evcnt_attach_dynamic(&stats->mngprc, EVCNT_TYPE_MISC, NULL,
                   1951:            stats->namebuf, "Management Packets Received");
                   1952:        evcnt_attach_dynamic(&stats->mngpdc, EVCNT_TYPE_MISC, NULL,
                   1953:            stats->namebuf, "Management Packets Dropped");
                   1954:        evcnt_attach_dynamic(&stats->xec, EVCNT_TYPE_MISC, NULL,
                   1955:            stats->namebuf, "Checksum Errors");
1.1       dyoung   1956:
1.98      msaitoh  1957:        /* Packet Transmission Stats */
                   1958:        evcnt_attach_dynamic(&stats->gotc, EVCNT_TYPE_MISC, NULL,
                   1959:            stats->namebuf, "Good Octets Transmitted");
                   1960:        evcnt_attach_dynamic(&stats->tpt, EVCNT_TYPE_MISC, NULL,
                   1961:            stats->namebuf, "Total Packets Transmitted");
                   1962:        evcnt_attach_dynamic(&stats->gptc, EVCNT_TYPE_MISC, NULL,
                   1963:            stats->namebuf, "Good Packets Transmitted");
                   1964:        evcnt_attach_dynamic(&stats->bptc, EVCNT_TYPE_MISC, NULL,
                   1965:            stats->namebuf, "Broadcast Packets Transmitted");
                   1966:        evcnt_attach_dynamic(&stats->mptc, EVCNT_TYPE_MISC, NULL,
                   1967:            stats->namebuf, "Multicast Packets Transmitted");
                   1968:        evcnt_attach_dynamic(&stats->mngptc, EVCNT_TYPE_MISC, NULL,
                   1969:            stats->namebuf, "Management Packets Transmitted");
                   1970:        evcnt_attach_dynamic(&stats->ptc64, EVCNT_TYPE_MISC, NULL,
                   1971:            stats->namebuf, "64 byte frames transmitted ");
                   1972:        evcnt_attach_dynamic(&stats->ptc127, EVCNT_TYPE_MISC, NULL,
                   1973:            stats->namebuf, "65-127 byte frames transmitted");
                   1974:        evcnt_attach_dynamic(&stats->ptc255, EVCNT_TYPE_MISC, NULL,
                   1975:            stats->namebuf, "128-255 byte frames transmitted");
                   1976:        evcnt_attach_dynamic(&stats->ptc511, EVCNT_TYPE_MISC, NULL,
                   1977:            stats->namebuf, "256-511 byte frames transmitted");
                   1978:        evcnt_attach_dynamic(&stats->ptc1023, EVCNT_TYPE_MISC, NULL,
                   1979:            stats->namebuf, "512-1023 byte frames transmitted");
                   1980:        evcnt_attach_dynamic(&stats->ptc1522, EVCNT_TYPE_MISC, NULL,
                   1981:            stats->namebuf, "1024-1522 byte frames transmitted");
1.99      msaitoh  1982: } /* ixgbe_add_hw_stats */
1.48      msaitoh  1983:
1.1       dyoung   1984: static void
1.98      msaitoh  1985: ixgbe_clear_evcnt(struct adapter *adapter)
1.1       dyoung   1986: {
1.98      msaitoh  1987:        struct tx_ring *txr = adapter->tx_rings;
                   1988:        struct rx_ring *rxr = adapter->rx_rings;
1.1       dyoung   1989:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  1990:        struct ixgbe_hw_stats *stats = &adapter->stats.pf;
                   1991:
                   1992:        adapter->efbig_tx_dma_setup.ev_count = 0;
                   1993:        adapter->mbuf_defrag_failed.ev_count = 0;
                   1994:        adapter->efbig2_tx_dma_setup.ev_count = 0;
                   1995:        adapter->einval_tx_dma_setup.ev_count = 0;
                   1996:        adapter->other_tx_dma_setup.ev_count = 0;
                   1997:        adapter->eagain_tx_dma_setup.ev_count = 0;
                   1998:        adapter->enomem_tx_dma_setup.ev_count = 0;
1.134     msaitoh  1999:        adapter->tso_err.ev_count = 0;
1.98      msaitoh  2000:        adapter->watchdog_events.ev_count = 0;
                   2001:        adapter->link_irq.ev_count = 0;
1.137     msaitoh  2002:        adapter->link_sicount.ev_count = 0;
                   2003:        adapter->mod_sicount.ev_count = 0;
                   2004:        adapter->msf_sicount.ev_count = 0;
                   2005:        adapter->phy_sicount.ev_count = 0;
1.98      msaitoh  2006:
                   2007:        txr = adapter->tx_rings;
                   2008:        for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
                   2009:                adapter->queues[i].irqs.ev_count = 0;
1.129     msaitoh  2010:                adapter->queues[i].handleq.ev_count = 0;
                   2011:                adapter->queues[i].req.ev_count = 0;
1.98      msaitoh  2012:                txr->no_desc_avail.ev_count = 0;
                   2013:                txr->total_packets.ev_count = 0;
                   2014:                txr->tso_tx.ev_count = 0;
                   2015: #ifndef IXGBE_LEGACY_TX
                   2016:                txr->pcq_drops.ev_count = 0;
1.45      msaitoh  2017: #endif
1.134     msaitoh  2018:                txr->q_efbig_tx_dma_setup = 0;
                   2019:                txr->q_mbuf_defrag_failed = 0;
                   2020:                txr->q_efbig2_tx_dma_setup = 0;
                   2021:                txr->q_einval_tx_dma_setup = 0;
                   2022:                txr->q_other_tx_dma_setup = 0;
                   2023:                txr->q_eagain_tx_dma_setup = 0;
                   2024:                txr->q_enomem_tx_dma_setup = 0;
                   2025:                txr->q_tso_err = 0;
1.1       dyoung   2026:
1.98      msaitoh  2027:                if (i < __arraycount(stats->mpc)) {
                   2028:                        stats->mpc[i].ev_count = 0;
                   2029:                        if (hw->mac.type == ixgbe_mac_82598EB)
                   2030:                                stats->rnbc[i].ev_count = 0;
                   2031:                }
                   2032:                if (i < __arraycount(stats->pxontxc)) {
                   2033:                        stats->pxontxc[i].ev_count = 0;
                   2034:                        stats->pxonrxc[i].ev_count = 0;
                   2035:                        stats->pxofftxc[i].ev_count = 0;
                   2036:                        stats->pxoffrxc[i].ev_count = 0;
                   2037:                        stats->pxon2offc[i].ev_count = 0;
                   2038:                }
                   2039:                if (i < __arraycount(stats->qprc)) {
                   2040:                        stats->qprc[i].ev_count = 0;
                   2041:                        stats->qptc[i].ev_count = 0;
                   2042:                        stats->qbrc[i].ev_count = 0;
                   2043:                        stats->qbtc[i].ev_count = 0;
                   2044:                        stats->qprdc[i].ev_count = 0;
                   2045:                }
                   2046:
                   2047:                rxr->rx_packets.ev_count = 0;
                   2048:                rxr->rx_bytes.ev_count = 0;
                   2049:                rxr->rx_copies.ev_count = 0;
                   2050:                rxr->no_jmbuf.ev_count = 0;
                   2051:                rxr->rx_discarded.ev_count = 0;
                   2052:        }
                   2053:        stats->ipcs.ev_count = 0;
                   2054:        stats->l4cs.ev_count = 0;
                   2055:        stats->ipcs_bad.ev_count = 0;
                   2056:        stats->l4cs_bad.ev_count = 0;
                   2057:        stats->intzero.ev_count = 0;
                   2058:        stats->legint.ev_count = 0;
                   2059:        stats->crcerrs.ev_count = 0;
                   2060:        stats->illerrc.ev_count = 0;
                   2061:        stats->errbc.ev_count = 0;
                   2062:        stats->mspdc.ev_count = 0;
                   2063:        stats->mbsdc.ev_count = 0;
                   2064:        stats->mpctotal.ev_count = 0;
                   2065:        stats->mlfc.ev_count = 0;
                   2066:        stats->mrfc.ev_count = 0;
                   2067:        stats->rlec.ev_count = 0;
                   2068:        stats->lxontxc.ev_count = 0;
                   2069:        stats->lxonrxc.ev_count = 0;
                   2070:        stats->lxofftxc.ev_count = 0;
                   2071:        stats->lxoffrxc.ev_count = 0;
                   2072:
                   2073:        /* Packet Reception Stats */
                   2074:        stats->tor.ev_count = 0;
                   2075:        stats->gorc.ev_count = 0;
                   2076:        stats->tpr.ev_count = 0;
                   2077:        stats->gprc.ev_count = 0;
                   2078:        stats->mprc.ev_count = 0;
                   2079:        stats->bprc.ev_count = 0;
                   2080:        stats->prc64.ev_count = 0;
                   2081:        stats->prc127.ev_count = 0;
                   2082:        stats->prc255.ev_count = 0;
                   2083:        stats->prc511.ev_count = 0;
                   2084:        stats->prc1023.ev_count = 0;
                   2085:        stats->prc1522.ev_count = 0;
                   2086:        stats->ruc.ev_count = 0;
                   2087:        stats->rfc.ev_count = 0;
                   2088:        stats->roc.ev_count = 0;
                   2089:        stats->rjc.ev_count = 0;
                   2090:        stats->mngprc.ev_count = 0;
                   2091:        stats->mngpdc.ev_count = 0;
                   2092:        stats->xec.ev_count = 0;
                   2093:
                   2094:        /* Packet Transmission Stats */
                   2095:        stats->gotc.ev_count = 0;
                   2096:        stats->tpt.ev_count = 0;
                   2097:        stats->gptc.ev_count = 0;
                   2098:        stats->bptc.ev_count = 0;
                   2099:        stats->mptc.ev_count = 0;
                   2100:        stats->mngptc.ev_count = 0;
                   2101:        stats->ptc64.ev_count = 0;
                   2102:        stats->ptc127.ev_count = 0;
                   2103:        stats->ptc255.ev_count = 0;
                   2104:        stats->ptc511.ev_count = 0;
                   2105:        stats->ptc1023.ev_count = 0;
                   2106:        stats->ptc1522.ev_count = 0;
                   2107: }
                   2108:
1.99      msaitoh  2109: /************************************************************************
                   2110:  * ixgbe_sysctl_tdh_handler - Transmit Descriptor Head handler function
                   2111:  *
                   2112:  *   Retrieves the TDH value from the hardware
                   2113:  ************************************************************************/
1.98      msaitoh  2114: static int
                   2115: ixgbe_sysctl_tdh_handler(SYSCTLFN_ARGS)
                   2116: {
                   2117:        struct sysctlnode node = *rnode;
1.99      msaitoh  2118:        struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
1.98      msaitoh  2119:        uint32_t val;
                   2120:
1.99      msaitoh  2121:        if (!txr)
                   2122:                return (0);
                   2123:
1.98      msaitoh  2124:        val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDH(txr->me));
                   2125:        node.sysctl_data = &val;
                   2126:        return sysctl_lookup(SYSCTLFN_CALL(&node));
1.99      msaitoh  2127: } /* ixgbe_sysctl_tdh_handler */
1.98      msaitoh  2128:
1.99      msaitoh  2129: /************************************************************************
                   2130:  * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function
                   2131:  *
                   2132:  *   Retrieves the TDT value from the hardware
                   2133:  ************************************************************************/
1.98      msaitoh  2134: static int
                   2135: ixgbe_sysctl_tdt_handler(SYSCTLFN_ARGS)
                   2136: {
                   2137:        struct sysctlnode node = *rnode;
1.99      msaitoh  2138:        struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
1.98      msaitoh  2139:        uint32_t val;
1.1       dyoung   2140:
1.99      msaitoh  2141:        if (!txr)
                   2142:                return (0);
                   2143:
1.98      msaitoh  2144:        val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_TDT(txr->me));
                   2145:        node.sysctl_data = &val;
                   2146:        return sysctl_lookup(SYSCTLFN_CALL(&node));
1.99      msaitoh  2147: } /* ixgbe_sysctl_tdt_handler */
1.45      msaitoh  2148:
1.99      msaitoh  2149: /************************************************************************
                   2150:  * ixgbe_sysctl_rdh_handler - Receive Descriptor Head handler function
                   2151:  *
                   2152:  *   Retrieves the RDH value from the hardware
                   2153:  ************************************************************************/
1.98      msaitoh  2154: static int
                   2155: ixgbe_sysctl_rdh_handler(SYSCTLFN_ARGS)
                   2156: {
                   2157:        struct sysctlnode node = *rnode;
1.99      msaitoh  2158:        struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
1.98      msaitoh  2159:        uint32_t val;
1.1       dyoung   2160:
1.99      msaitoh  2161:        if (!rxr)
                   2162:                return (0);
                   2163:
1.98      msaitoh  2164:        val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDH(rxr->me));
                   2165:        node.sysctl_data = &val;
                   2166:        return sysctl_lookup(SYSCTLFN_CALL(&node));
1.99      msaitoh  2167: } /* ixgbe_sysctl_rdh_handler */
1.1       dyoung   2168:
1.99      msaitoh  2169: /************************************************************************
                   2170:  * ixgbe_sysctl_rdt_handler - Receive Descriptor Tail handler function
                   2171:  *
                   2172:  *   Retrieves the RDT value from the hardware
                   2173:  ************************************************************************/
1.98      msaitoh  2174: static int
                   2175: ixgbe_sysctl_rdt_handler(SYSCTLFN_ARGS)
                   2176: {
                   2177:        struct sysctlnode node = *rnode;
1.99      msaitoh  2178:        struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
1.98      msaitoh  2179:        uint32_t val;
1.1       dyoung   2180:
1.99      msaitoh  2181:        if (!rxr)
                   2182:                return (0);
                   2183:
1.98      msaitoh  2184:        val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_RDT(rxr->me));
                   2185:        node.sysctl_data = &val;
                   2186:        return sysctl_lookup(SYSCTLFN_CALL(&node));
1.99      msaitoh  2187: } /* ixgbe_sysctl_rdt_handler */
1.1       dyoung   2188:
1.98      msaitoh  2189: #if 0  /* XXX Badly need to overhaul vlan(4) on NetBSD. */
1.99      msaitoh  2190: /************************************************************************
                   2191:  * ixgbe_register_vlan
                   2192:  *
                   2193:  *   Run via vlan config EVENT, it enables us to use the
                   2194:  *   HW Filter table since we can get the vlan id. This
                   2195:  *   just creates the entry in the soft version of the
                   2196:  *   VFTA, init will repopulate the real table.
                   2197:  ************************************************************************/
1.98      msaitoh  2198: static void
                   2199: ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
                   2200: {
                   2201:        struct adapter  *adapter = ifp->if_softc;
                   2202:        u16             index, bit;
1.48      msaitoh  2203:
1.98      msaitoh  2204:        if (ifp->if_softc != arg)   /* Not our event */
1.1       dyoung   2205:                return;
                   2206:
1.98      msaitoh  2207:        if ((vtag == 0) || (vtag > 4095))       /* Invalid */
                   2208:                return;
1.1       dyoung   2209:
1.98      msaitoh  2210:        IXGBE_CORE_LOCK(adapter);
                   2211:        index = (vtag >> 5) & 0x7F;
                   2212:        bit = vtag & 0x1F;
                   2213:        adapter->shadow_vfta[index] |= (1 << bit);
                   2214:        ixgbe_setup_vlan_hw_support(adapter);
                   2215:        IXGBE_CORE_UNLOCK(adapter);
1.99      msaitoh  2216: } /* ixgbe_register_vlan */
1.1       dyoung   2217:
1.99      msaitoh  2218: /************************************************************************
                   2219:  * ixgbe_unregister_vlan
                   2220:  *
                   2221:  *   Run via vlan unconfig EVENT, remove our entry in the soft vfta.
                   2222:  ************************************************************************/
1.98      msaitoh  2223: static void
                   2224: ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
                   2225: {
                   2226:        struct adapter  *adapter = ifp->if_softc;
                   2227:        u16             index, bit;
1.1       dyoung   2228:
1.98      msaitoh  2229:        if (ifp->if_softc != arg)
1.1       dyoung   2230:                return;
                   2231:
1.98      msaitoh  2232:        if ((vtag == 0) || (vtag > 4095))       /* Invalid */
                   2233:                return;
1.1       dyoung   2234:
1.98      msaitoh  2235:        IXGBE_CORE_LOCK(adapter);
                   2236:        index = (vtag >> 5) & 0x7F;
                   2237:        bit = vtag & 0x1F;
                   2238:        adapter->shadow_vfta[index] &= ~(1 << bit);
                   2239:        /* Re-init to load the changes */
                   2240:        ixgbe_setup_vlan_hw_support(adapter);
                   2241:        IXGBE_CORE_UNLOCK(adapter);
1.99      msaitoh  2242: } /* ixgbe_unregister_vlan */
1.98      msaitoh  2243: #endif
                   2244:
                   2245: static void
                   2246: ixgbe_setup_vlan_hw_support(struct adapter *adapter)
                   2247: {
                   2248:        struct ethercom *ec = &adapter->osdep.ec;
                   2249:        struct ixgbe_hw *hw = &adapter->hw;
                   2250:        struct rx_ring  *rxr;
1.99      msaitoh  2251:        int             i;
1.98      msaitoh  2252:        u32             ctrl;
                   2253:
                   2254:
                   2255:        /*
1.99      msaitoh  2256:         * We get here thru init_locked, meaning
                   2257:         * a soft reset, this has already cleared
                   2258:         * the VFTA and other state, so if there
                   2259:         * have been no vlan's registered do nothing.
                   2260:         */
1.98      msaitoh  2261:        if (!VLAN_ATTACHED(&adapter->osdep.ec))
                   2262:                return;
1.1       dyoung   2263:
1.98      msaitoh  2264:        /* Setup the queues for vlans */
1.115     msaitoh  2265:        if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
                   2266:                for (i = 0; i < adapter->num_queues; i++) {
                   2267:                        rxr = &adapter->rx_rings[i];
                   2268:                        /* On 82599 the VLAN enable is per/queue in RXDCTL */
                   2269:                        if (hw->mac.type != ixgbe_mac_82598EB) {
                   2270:                                ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me));
                   2271:                                ctrl |= IXGBE_RXDCTL_VME;
                   2272:                                IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl);
                   2273:                        }
                   2274:                        rxr->vtag_strip = TRUE;
1.98      msaitoh  2275:                }
1.1       dyoung   2276:        }
                   2277:
1.98      msaitoh  2278:        if ((ec->ec_capenable & ETHERCAP_VLAN_HWFILTER) == 0)
                   2279:                return;
                   2280:        /*
1.99      msaitoh  2281:         * A soft reset zero's out the VFTA, so
                   2282:         * we need to repopulate it now.
                   2283:         */
                   2284:        for (i = 0; i < IXGBE_VFTA_SIZE; i++)
1.98      msaitoh  2285:                if (adapter->shadow_vfta[i] != 0)
                   2286:                        IXGBE_WRITE_REG(hw, IXGBE_VFTA(i),
                   2287:                            adapter->shadow_vfta[i]);
1.22      msaitoh  2288:
1.98      msaitoh  2289:        ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
                   2290:        /* Enable the Filter Table if enabled */
                   2291:        if (ec->ec_capenable & ETHERCAP_VLAN_HWFILTER) {
                   2292:                ctrl &= ~IXGBE_VLNCTRL_CFIEN;
                   2293:                ctrl |= IXGBE_VLNCTRL_VFE;
1.1       dyoung   2294:        }
                   2295:        if (hw->mac.type == ixgbe_mac_82598EB)
1.98      msaitoh  2296:                ctrl |= IXGBE_VLNCTRL_VME;
                   2297:        IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
1.99      msaitoh  2298: } /* ixgbe_setup_vlan_hw_support */
1.1       dyoung   2299:
1.99      msaitoh  2300: /************************************************************************
                   2301:  * ixgbe_get_slot_info
                   2302:  *
                   2303:  *   Get the width and transaction speed of
                   2304:  *   the slot this adapter is plugged into.
                   2305:  ************************************************************************/
1.98      msaitoh  2306: static void
                   2307: ixgbe_get_slot_info(struct adapter *adapter)
                   2308: {
                   2309:        device_t                dev = adapter->dev;
                   2310:        struct ixgbe_hw         *hw = &adapter->hw;
1.99      msaitoh  2311:        u32                   offset;
1.98      msaitoh  2312:        u16                     link;
1.99      msaitoh  2313:        int                   bus_info_valid = TRUE;
                   2314:
                   2315:        /* Some devices are behind an internal bridge */
                   2316:        switch (hw->device_id) {
                   2317:        case IXGBE_DEV_ID_82599_SFP_SF_QP:
                   2318:        case IXGBE_DEV_ID_82599_QSFP_SF_QP:
                   2319:                goto get_parent_info;
                   2320:        default:
                   2321:                break;
                   2322:        }
1.1       dyoung   2323:
1.99      msaitoh  2324:        ixgbe_get_bus_info(hw);
                   2325:
                   2326:        /*
                   2327:         * Some devices don't use PCI-E, but there is no need
                   2328:         * to display "Unknown" for bus speed and width.
                   2329:         */
                   2330:        switch (hw->mac.type) {
                   2331:        case ixgbe_mac_X550EM_x:
                   2332:        case ixgbe_mac_X550EM_a:
                   2333:                return;
                   2334:        default:
                   2335:                goto display;
1.1       dyoung   2336:        }
                   2337:
1.99      msaitoh  2338: get_parent_info:
1.98      msaitoh  2339:        /*
1.99      msaitoh  2340:         * For the Quad port adapter we need to parse back
                   2341:         * up the PCI tree to find the speed of the expansion
                   2342:         * slot into which this adapter is plugged. A bit more work.
                   2343:         */
1.98      msaitoh  2344:        dev = device_parent(device_parent(dev));
1.99      msaitoh  2345: #if 0
1.98      msaitoh  2346: #ifdef IXGBE_DEBUG
1.99      msaitoh  2347:        device_printf(dev, "parent pcib = %x,%x,%x\n", pci_get_bus(dev),
                   2348:            pci_get_slot(dev), pci_get_function(dev));
1.98      msaitoh  2349: #endif
                   2350:        dev = device_parent(device_parent(dev));
                   2351: #ifdef IXGBE_DEBUG
1.99      msaitoh  2352:        device_printf(dev, "slot pcib = %x,%x,%x\n", pci_get_bus(dev),
                   2353:            pci_get_slot(dev), pci_get_function(dev));
                   2354: #endif
1.1       dyoung   2355: #endif
1.98      msaitoh  2356:        /* Now get the PCI Express Capabilities offset */
1.99      msaitoh  2357:        if (pci_get_capability(adapter->osdep.pc, adapter->osdep.tag,
                   2358:            PCI_CAP_PCIEXPRESS, &offset, NULL)) {
                   2359:                /*
                   2360:                 * Hmm...can't get PCI-Express capabilities.
                   2361:                 * Falling back to default method.
                   2362:                 */
                   2363:                bus_info_valid = FALSE;
                   2364:                ixgbe_get_bus_info(hw);
                   2365:                goto display;
                   2366:        }
1.98      msaitoh  2367:        /* ...and read the Link Status Register */
1.99      msaitoh  2368:        link = pci_conf_read(adapter->osdep.pc, adapter->osdep.tag,
1.120     msaitoh  2369:            offset + PCIE_LCSR) >> 16;
                   2370:        ixgbe_set_pci_config_data_generic(hw, link);
1.52      msaitoh  2371:
1.98      msaitoh  2372: display:
1.99      msaitoh  2373:        device_printf(dev, "PCI Express Bus: Speed %s Width %s\n",
                   2374:            ((hw->bus.speed == ixgbe_bus_speed_8000)    ? "8.0GT/s" :
                   2375:             (hw->bus.speed == ixgbe_bus_speed_5000)    ? "5.0GT/s" :
                   2376:             (hw->bus.speed == ixgbe_bus_speed_2500)    ? "2.5GT/s" :
                   2377:             "Unknown"),
                   2378:            ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "x8" :
                   2379:             (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "x4" :
                   2380:             (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "x1" :
                   2381:             "Unknown"));
                   2382:
                   2383:        if (bus_info_valid) {
                   2384:                if ((hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) &&
                   2385:                    ((hw->bus.width <= ixgbe_bus_width_pcie_x4) &&
                   2386:                        (hw->bus.speed == ixgbe_bus_speed_2500))) {
                   2387:                        device_printf(dev, "PCI-Express bandwidth available"
                   2388:                            " for this card\n     is not sufficient for"
                   2389:                            " optimal performance.\n");
                   2390:                        device_printf(dev, "For optimal performance a x8 "
                   2391:                            "PCIE, or x4 PCIE Gen2 slot is required.\n");
                   2392:                }
                   2393:                if ((hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP) &&
                   2394:                    ((hw->bus.width <= ixgbe_bus_width_pcie_x8) &&
                   2395:                        (hw->bus.speed < ixgbe_bus_speed_8000))) {
                   2396:                        device_printf(dev, "PCI-Express bandwidth available"
                   2397:                            " for this card\n     is not sufficient for"
                   2398:                            " optimal performance.\n");
                   2399:                        device_printf(dev, "For optimal performance a x8 "
                   2400:                            "PCIE Gen3 slot is required.\n");
                   2401:                }
                   2402:        } else
                   2403:                device_printf(dev, "Unable to determine slot speed/width. The speed/width reported are that of the internal switch.\n");
1.45      msaitoh  2404:
                   2405:        return;
1.99      msaitoh  2406: } /* ixgbe_get_slot_info */
1.1       dyoung   2407:
1.99      msaitoh  2408: /************************************************************************
                   2409:  * ixgbe_enable_queue - MSI-X Interrupt Handlers and Tasklets
                   2410:  ************************************************************************/
1.1       dyoung   2411: static inline void
                   2412: ixgbe_enable_queue(struct adapter *adapter, u32 vector)
                   2413: {
                   2414:        struct ixgbe_hw *hw = &adapter->hw;
1.127     knakahar 2415:        struct ix_queue *que = &adapter->queues[vector];
1.99      msaitoh  2416:        u64             queue = (u64)(1ULL << vector);
                   2417:        u32             mask;
1.1       dyoung   2418:
1.139     knakahar 2419:        mutex_enter(&que->dc_mtx);
                   2420:        if (que->disabled_count > 0 && --que->disabled_count > 0)
1.127     knakahar 2421:                goto out;
                   2422:
1.1       dyoung   2423:        if (hw->mac.type == ixgbe_mac_82598EB) {
1.98      msaitoh  2424:                mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                   2425:                IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
1.1       dyoung   2426:        } else {
1.98      msaitoh  2427:                mask = (queue & 0xFFFFFFFF);
                   2428:                if (mask)
                   2429:                        IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
                   2430:                mask = (queue >> 32);
                   2431:                if (mask)
                   2432:                        IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
1.1       dyoung   2433:        }
1.127     knakahar 2434: out:
1.139     knakahar 2435:        mutex_exit(&que->dc_mtx);
1.99      msaitoh  2436: } /* ixgbe_enable_queue */
1.1       dyoung   2437:
1.99      msaitoh  2438: /************************************************************************
1.139     knakahar 2439:  * ixgbe_disable_queue_internal
1.99      msaitoh  2440:  ************************************************************************/
1.82      msaitoh  2441: static inline void
1.139     knakahar 2442: ixgbe_disable_queue_internal(struct adapter *adapter, u32 vector, bool nestok)
1.1       dyoung   2443: {
                   2444:        struct ixgbe_hw *hw = &adapter->hw;
1.127     knakahar 2445:        struct ix_queue *que = &adapter->queues[vector];
1.99      msaitoh  2446:        u64             queue = (u64)(1ULL << vector);
                   2447:        u32             mask;
1.1       dyoung   2448:
1.139     knakahar 2449:        mutex_enter(&que->dc_mtx);
                   2450:
                   2451:        if (que->disabled_count > 0) {
                   2452:                if (nestok)
                   2453:                        que->disabled_count++;
                   2454:                goto out;
                   2455:        }
                   2456:        que->disabled_count++;
1.127     knakahar 2457:
1.1       dyoung   2458:        if (hw->mac.type == ixgbe_mac_82598EB) {
1.98      msaitoh  2459:                mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                   2460:                IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
1.1       dyoung   2461:        } else {
1.98      msaitoh  2462:                mask = (queue & 0xFFFFFFFF);
                   2463:                if (mask)
                   2464:                        IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
                   2465:                mask = (queue >> 32);
                   2466:                if (mask)
                   2467:                        IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
1.1       dyoung   2468:        }
1.127     knakahar 2469: out:
1.139     knakahar 2470:        mutex_exit(&que->dc_mtx);
                   2471: } /* ixgbe_disable_queue_internal */
                   2472:
                   2473: /************************************************************************
                   2474:  * ixgbe_disable_queue
                   2475:  ************************************************************************/
                   2476: static inline void
                   2477: ixgbe_disable_queue(struct adapter *adapter, u32 vector)
                   2478: {
                   2479:
                   2480:        ixgbe_disable_queue_internal(adapter, vector, true);
1.99      msaitoh  2481: } /* ixgbe_disable_queue */
1.1       dyoung   2482:
1.99      msaitoh  2483: /************************************************************************
1.133     knakahar 2484:  * ixgbe_sched_handle_que - schedule deferred packet processing
                   2485:  ************************************************************************/
                   2486: static inline void
                   2487: ixgbe_sched_handle_que(struct adapter *adapter, struct ix_queue *que)
                   2488: {
                   2489:
1.147     knakahar 2490:        if(que->txrx_use_workqueue) {
1.133     knakahar 2491:                /*
                   2492:                 * adapter->que_wq is bound to each CPU instead of
                   2493:                 * each NIC queue to reduce workqueue kthread. As we
                   2494:                 * should consider about interrupt affinity in this
                   2495:                 * function, the workqueue kthread must be WQ_PERCPU.
                   2496:                 * If create WQ_PERCPU workqueue kthread for each NIC
                   2497:                 * queue, that number of created workqueue kthread is
                   2498:                 * (number of used NIC queue) * (number of CPUs) =
                   2499:                 * (number of CPUs) ^ 2 most often.
                   2500:                 *
                   2501:                 * The same NIC queue's interrupts are avoided by
                   2502:                 * masking the queue's interrupt. And different
                   2503:                 * NIC queue's interrupts use different struct work
                   2504:                 * (que->wq_cookie). So, "enqueued flag" to avoid
                   2505:                 * twice workqueue_enqueue() is not required .
                   2506:                 */
                   2507:                workqueue_enqueue(adapter->que_wq, &que->wq_cookie, curcpu());
                   2508:        } else {
                   2509:                softint_schedule(que->que_si);
                   2510:        }
                   2511: }
                   2512:
                   2513: /************************************************************************
1.99      msaitoh  2514:  * ixgbe_msix_que - MSI-X Queue Interrupt Service routine
                   2515:  ************************************************************************/
1.34      msaitoh  2516: static int
1.1       dyoung   2517: ixgbe_msix_que(void *arg)
                   2518: {
                   2519:        struct ix_queue *que = arg;
                   2520:        struct adapter  *adapter = que->adapter;
1.33      msaitoh  2521:        struct ifnet    *ifp = adapter->ifp;
1.1       dyoung   2522:        struct tx_ring  *txr = que->txr;
                   2523:        struct rx_ring  *rxr = que->rxr;
1.33      msaitoh  2524:        bool            more;
1.1       dyoung   2525:        u32             newitr = 0;
                   2526:
1.33      msaitoh  2527:        /* Protect against spurious interrupts */
                   2528:        if ((ifp->if_flags & IFF_RUNNING) == 0)
1.34      msaitoh  2529:                return 0;
1.33      msaitoh  2530:
1.24      msaitoh  2531:        ixgbe_disable_queue(adapter, que->msix);
1.43      msaitoh  2532:        ++que->irqs.ev_count;
1.1       dyoung   2533:
1.147     knakahar 2534:        /*
                   2535:         * Don't change "que->txrx_use_workqueue" from this point to avoid
                   2536:         * flip-flopping softint/workqueue mode in one deferred processing.
                   2537:         */
                   2538:        que->txrx_use_workqueue = adapter->txrx_use_workqueue;
                   2539:
1.37      ozaki-r  2540: #ifdef __NetBSD__
                   2541:        /* Don't run ixgbe_rxeof in interrupt context */
                   2542:        more = true;
                   2543: #else
1.33      msaitoh  2544:        more = ixgbe_rxeof(que);
1.37      ozaki-r  2545: #endif
1.1       dyoung   2546:
                   2547:        IXGBE_TX_LOCK(txr);
1.33      msaitoh  2548:        ixgbe_txeof(txr);
1.1       dyoung   2549:        IXGBE_TX_UNLOCK(txr);
                   2550:
                   2551:        /* Do AIM now? */
                   2552:
1.73      msaitoh  2553:        if (adapter->enable_aim == false)
1.1       dyoung   2554:                goto no_calc;
                   2555:        /*
1.99      msaitoh  2556:         * Do Adaptive Interrupt Moderation:
                   2557:         *  - Write out last calculated setting
                   2558:         *  - Calculate based on average size over
                   2559:         *    the last interval.
                   2560:         */
                   2561:        if (que->eitr_setting)
1.149   ! msaitoh  2562:                ixgbe_eitr_write(adapter, que->msix, que->eitr_setting);
1.99      msaitoh  2563:
1.98      msaitoh  2564:        que->eitr_setting = 0;
1.1       dyoung   2565:
1.98      msaitoh  2566:        /* Idle, do nothing */
1.99      msaitoh  2567:         if ((txr->bytes == 0) && (rxr->bytes == 0))
                   2568:                 goto no_calc;
1.1       dyoung   2569:
                   2570:        if ((txr->bytes) && (txr->packets))
1.98      msaitoh  2571:                newitr = txr->bytes/txr->packets;
1.1       dyoung   2572:        if ((rxr->bytes) && (rxr->packets))
1.99      msaitoh  2573:                newitr = max(newitr, (rxr->bytes / rxr->packets));
1.1       dyoung   2574:        newitr += 24; /* account for hardware frame, crc */
                   2575:
                   2576:        /* set an upper boundary */
                   2577:        newitr = min(newitr, 3000);
                   2578:
                   2579:        /* Be nice to the mid range */
                   2580:        if ((newitr > 300) && (newitr < 1200))
                   2581:                newitr = (newitr / 3);
                   2582:        else
                   2583:                newitr = (newitr / 2);
                   2584:
1.124     msaitoh  2585:        /*
                   2586:         * When RSC is used, ITR interval must be larger than RSC_DELAY.
                   2587:         * Currently, we use 2us for RSC_DELAY. The minimum value is always
                   2588:         * greater than 2us on 100M (and 10M?(not documented)), but it's not
                   2589:         * on 1G and higher.
                   2590:         */
                   2591:        if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
                   2592:            && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
                   2593:                if (newitr < IXGBE_MIN_RSC_EITR_10G1G)
                   2594:                        newitr = IXGBE_MIN_RSC_EITR_10G1G;
                   2595:        }
                   2596:
1.1       dyoung   2597:         /* save for next interrupt */
                   2598:         que->eitr_setting = newitr;
                   2599:
1.98      msaitoh  2600:        /* Reset state */
                   2601:        txr->bytes = 0;
                   2602:        txr->packets = 0;
                   2603:        rxr->bytes = 0;
                   2604:        rxr->packets = 0;
1.1       dyoung   2605:
                   2606: no_calc:
1.133     knakahar 2607:        if (more)
                   2608:                ixgbe_sched_handle_que(adapter, que);
                   2609:        else
1.1       dyoung   2610:                ixgbe_enable_queue(adapter, que->msix);
1.99      msaitoh  2611:
1.34      msaitoh  2612:        return 1;
1.99      msaitoh  2613: } /* ixgbe_msix_que */
1.1       dyoung   2614:
1.99      msaitoh  2615: /************************************************************************
                   2616:  * ixgbe_media_status - Media Ioctl callback
1.98      msaitoh  2617:  *
1.99      msaitoh  2618:  *   Called whenever the user queries the status of
                   2619:  *   the interface using ifconfig.
                   2620:  ************************************************************************/
1.98      msaitoh  2621: static void
                   2622: ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1       dyoung   2623: {
1.98      msaitoh  2624:        struct adapter *adapter = ifp->if_softc;
1.1       dyoung   2625:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  2626:        int layer;
1.1       dyoung   2627:
1.98      msaitoh  2628:        INIT_DEBUGOUT("ixgbe_media_status: begin");
                   2629:        IXGBE_CORE_LOCK(adapter);
                   2630:        ixgbe_update_link_status(adapter);
1.1       dyoung   2631:
                   2632:        ifmr->ifm_status = IFM_AVALID;
                   2633:        ifmr->ifm_active = IFM_ETHER;
                   2634:
                   2635:        if (!adapter->link_active) {
1.68      msaitoh  2636:                ifmr->ifm_active |= IFM_NONE;
1.1       dyoung   2637:                IXGBE_CORE_UNLOCK(adapter);
                   2638:                return;
                   2639:        }
                   2640:
                   2641:        ifmr->ifm_status |= IFM_ACTIVE;
1.45      msaitoh  2642:        layer = adapter->phy_layer;
1.1       dyoung   2643:
1.43      msaitoh  2644:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T ||
1.103     msaitoh  2645:            layer & IXGBE_PHYSICAL_LAYER_5GBASE_T ||
                   2646:            layer & IXGBE_PHYSICAL_LAYER_2500BASE_T ||
1.43      msaitoh  2647:            layer & IXGBE_PHYSICAL_LAYER_1000BASE_T ||
1.99      msaitoh  2648:            layer & IXGBE_PHYSICAL_LAYER_100BASE_TX ||
                   2649:            layer & IXGBE_PHYSICAL_LAYER_10BASE_T)
1.43      msaitoh  2650:                switch (adapter->link_speed) {
                   2651:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2652:                        ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
                   2653:                        break;
1.103     msaitoh  2654:                case IXGBE_LINK_SPEED_5GB_FULL:
                   2655:                        ifmr->ifm_active |= IFM_5000_T | IFM_FDX;
                   2656:                        break;
                   2657:                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   2658:                        ifmr->ifm_active |= IFM_2500_T | IFM_FDX;
                   2659:                        break;
1.43      msaitoh  2660:                case IXGBE_LINK_SPEED_1GB_FULL:
1.33      msaitoh  2661:                        ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
1.43      msaitoh  2662:                        break;
                   2663:                case IXGBE_LINK_SPEED_100_FULL:
1.24      msaitoh  2664:                        ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
1.43      msaitoh  2665:                        break;
1.99      msaitoh  2666:                case IXGBE_LINK_SPEED_10_FULL:
                   2667:                        ifmr->ifm_active |= IFM_10_T | IFM_FDX;
                   2668:                        break;
1.43      msaitoh  2669:                }
                   2670:        if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU ||
                   2671:            layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA)
                   2672:                switch (adapter->link_speed) {
                   2673:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2674:                        ifmr->ifm_active |= IFM_10G_TWINAX | IFM_FDX;
                   2675:                        break;
                   2676:                }
                   2677:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR)
                   2678:                switch (adapter->link_speed) {
                   2679:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2680:                        ifmr->ifm_active |= IFM_10G_LR | IFM_FDX;
                   2681:                        break;
                   2682:                case IXGBE_LINK_SPEED_1GB_FULL:
                   2683:                        ifmr->ifm_active |= IFM_1000_LX | IFM_FDX;
                   2684:                        break;
                   2685:                }
                   2686:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LRM)
                   2687:                switch (adapter->link_speed) {
                   2688:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2689:                        ifmr->ifm_active |= IFM_10G_LRM | IFM_FDX;
                   2690:                        break;
                   2691:                case IXGBE_LINK_SPEED_1GB_FULL:
                   2692:                        ifmr->ifm_active |= IFM_1000_LX | IFM_FDX;
                   2693:                        break;
                   2694:                }
                   2695:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR ||
                   2696:            layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX)
                   2697:                switch (adapter->link_speed) {
                   2698:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2699:                        ifmr->ifm_active |= IFM_10G_SR | IFM_FDX;
                   2700:                        break;
                   2701:                case IXGBE_LINK_SPEED_1GB_FULL:
1.28      msaitoh  2702:                        ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
1.43      msaitoh  2703:                        break;
                   2704:                }
                   2705:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4)
                   2706:                switch (adapter->link_speed) {
                   2707:                case IXGBE_LINK_SPEED_10GB_FULL:
                   2708:                        ifmr->ifm_active |= IFM_10G_CX4 | IFM_FDX;
                   2709:                        break;
                   2710:                }
                   2711:        /*
1.99      msaitoh  2712:         * XXX: These need to use the proper media types once
                   2713:         * they're added.
                   2714:         */
1.43      msaitoh  2715:        if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR)
                   2716:                switch (adapter->link_speed) {
                   2717:                case IXGBE_LINK_SPEED_10GB_FULL:
1.89      msaitoh  2718: #ifndef IFM_ETH_XTYPE
1.44      msaitoh  2719:                        ifmr->ifm_active |= IFM_10G_SR | IFM_FDX;
1.48      msaitoh  2720: #else
                   2721:                        ifmr->ifm_active |= IFM_10G_KR | IFM_FDX;
1.89      msaitoh  2722: #endif
1.48      msaitoh  2723:                        break;
                   2724:                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   2725:                        ifmr->ifm_active |= IFM_2500_KX | IFM_FDX;
                   2726:                        break;
                   2727:                case IXGBE_LINK_SPEED_1GB_FULL:
                   2728:                        ifmr->ifm_active |= IFM_1000_KX | IFM_FDX;
                   2729:                        break;
                   2730:                }
1.99      msaitoh  2731:        else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 ||
                   2732:            layer & IXGBE_PHYSICAL_LAYER_2500BASE_KX ||
                   2733:            layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX)
1.48      msaitoh  2734:                switch (adapter->link_speed) {
                   2735:                case IXGBE_LINK_SPEED_10GB_FULL:
1.89      msaitoh  2736: #ifndef IFM_ETH_XTYPE
                   2737:                        ifmr->ifm_active |= IFM_10G_CX4 | IFM_FDX;
                   2738: #else
1.48      msaitoh  2739:                        ifmr->ifm_active |= IFM_10G_KX4 | IFM_FDX;
1.89      msaitoh  2740: #endif
1.48      msaitoh  2741:                        break;
                   2742:                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   2743:                        ifmr->ifm_active |= IFM_2500_KX | IFM_FDX;
                   2744:                        break;
                   2745:                case IXGBE_LINK_SPEED_1GB_FULL:
                   2746:                        ifmr->ifm_active |= IFM_1000_KX | IFM_FDX;
                   2747:                        break;
                   2748:                }
1.98      msaitoh  2749:
1.43      msaitoh  2750:        /* If nothing is recognized... */
                   2751: #if 0
                   2752:        if (IFM_SUBTYPE(ifmr->ifm_active) == 0)
                   2753:                ifmr->ifm_active |= IFM_UNKNOWN;
                   2754: #endif
1.98      msaitoh  2755:
1.104     msaitoh  2756:        ifp->if_baudrate = ifmedia_baudrate(ifmr->ifm_active);
                   2757:
1.44      msaitoh  2758:        /* Display current flow control setting used on link */
                   2759:        if (hw->fc.current_mode == ixgbe_fc_rx_pause ||
                   2760:            hw->fc.current_mode == ixgbe_fc_full)
1.43      msaitoh  2761:                ifmr->ifm_active |= IFM_ETH_RXPAUSE;
1.44      msaitoh  2762:        if (hw->fc.current_mode == ixgbe_fc_tx_pause ||
                   2763:            hw->fc.current_mode == ixgbe_fc_full)
1.43      msaitoh  2764:                ifmr->ifm_active |= IFM_ETH_TXPAUSE;
1.1       dyoung   2765:
                   2766:        IXGBE_CORE_UNLOCK(adapter);
                   2767:
                   2768:        return;
1.99      msaitoh  2769: } /* ixgbe_media_status */
1.1       dyoung   2770:
1.99      msaitoh  2771: /************************************************************************
                   2772:  * ixgbe_media_change - Media Ioctl callback
1.1       dyoung   2773:  *
1.99      msaitoh  2774:  *   Called when the user changes speed/duplex using
                   2775:  *   media/mediopt option with ifconfig.
                   2776:  ************************************************************************/
1.1       dyoung   2777: static int
1.98      msaitoh  2778: ixgbe_media_change(struct ifnet *ifp)
1.1       dyoung   2779: {
1.99      msaitoh  2780:        struct adapter   *adapter = ifp->if_softc;
                   2781:        struct ifmedia   *ifm = &adapter->media;
                   2782:        struct ixgbe_hw  *hw = &adapter->hw;
1.43      msaitoh  2783:        ixgbe_link_speed speed = 0;
1.94      msaitoh  2784:        ixgbe_link_speed link_caps = 0;
                   2785:        bool negotiate = false;
                   2786:        s32 err = IXGBE_NOT_IMPLEMENTED;
1.1       dyoung   2787:
                   2788:        INIT_DEBUGOUT("ixgbe_media_change: begin");
                   2789:
                   2790:        if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
                   2791:                return (EINVAL);
                   2792:
1.44      msaitoh  2793:        if (hw->phy.media_type == ixgbe_media_type_backplane)
1.144     msaitoh  2794:                return (EPERM);
1.44      msaitoh  2795:
1.43      msaitoh  2796:        /*
1.99      msaitoh  2797:         * We don't actually need to check against the supported
                   2798:         * media types of the adapter; ifmedia will take care of
                   2799:         * that for us.
                   2800:         */
1.43      msaitoh  2801:        switch (IFM_SUBTYPE(ifm->ifm_media)) {
1.98      msaitoh  2802:        case IFM_AUTO:
                   2803:                err = hw->mac.ops.get_link_capabilities(hw, &link_caps,
                   2804:                    &negotiate);
                   2805:                if (err != IXGBE_SUCCESS) {
                   2806:                        device_printf(adapter->dev, "Unable to determine "
                   2807:                            "supported advertise speeds\n");
                   2808:                        return (ENODEV);
                   2809:                }
                   2810:                speed |= link_caps;
                   2811:                break;
                   2812:        case IFM_10G_T:
                   2813:        case IFM_10G_LRM:
                   2814:        case IFM_10G_LR:
                   2815:        case IFM_10G_TWINAX:
1.90      msaitoh  2816: #ifndef IFM_ETH_XTYPE
1.98      msaitoh  2817:        case IFM_10G_SR: /* KR, too */
                   2818:        case IFM_10G_CX4: /* KX4 */
1.48      msaitoh  2819: #else
1.98      msaitoh  2820:        case IFM_10G_KR:
                   2821:        case IFM_10G_KX4:
1.90      msaitoh  2822: #endif
1.98      msaitoh  2823:                speed |= IXGBE_LINK_SPEED_10GB_FULL;
                   2824:                break;
1.103     msaitoh  2825:        case IFM_5000_T:
                   2826:                speed |= IXGBE_LINK_SPEED_5GB_FULL;
                   2827:                break;
                   2828:        case IFM_2500_T:
1.99      msaitoh  2829:        case IFM_2500_KX:
                   2830:                speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
                   2831:                break;
1.98      msaitoh  2832:        case IFM_1000_T:
                   2833:        case IFM_1000_LX:
                   2834:        case IFM_1000_SX:
                   2835:        case IFM_1000_KX:
                   2836:                speed |= IXGBE_LINK_SPEED_1GB_FULL;
                   2837:                break;
                   2838:        case IFM_100_TX:
                   2839:                speed |= IXGBE_LINK_SPEED_100_FULL;
                   2840:                break;
1.99      msaitoh  2841:        case IFM_10_T:
                   2842:                speed |= IXGBE_LINK_SPEED_10_FULL;
                   2843:                break;
1.140     msaitoh  2844:        case IFM_NONE:
                   2845:                break;
1.98      msaitoh  2846:        default:
                   2847:                goto invalid;
1.48      msaitoh  2848:        }
1.43      msaitoh  2849:
                   2850:        hw->mac.autotry_restart = TRUE;
                   2851:        hw->mac.ops.setup_link(hw, speed, TRUE);
1.109     msaitoh  2852:        adapter->advertise = 0;
                   2853:        if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
1.51      msaitoh  2854:                if ((speed & IXGBE_LINK_SPEED_10GB_FULL) != 0)
                   2855:                        adapter->advertise |= 1 << 2;
                   2856:                if ((speed & IXGBE_LINK_SPEED_1GB_FULL) != 0)
                   2857:                        adapter->advertise |= 1 << 1;
                   2858:                if ((speed & IXGBE_LINK_SPEED_100_FULL) != 0)
                   2859:                        adapter->advertise |= 1 << 0;
1.99      msaitoh  2860:                if ((speed & IXGBE_LINK_SPEED_10_FULL) != 0)
1.102     msaitoh  2861:                        adapter->advertise |= 1 << 3;
1.103     msaitoh  2862:                if ((speed & IXGBE_LINK_SPEED_2_5GB_FULL) != 0)
                   2863:                        adapter->advertise |= 1 << 4;
                   2864:                if ((speed & IXGBE_LINK_SPEED_5GB_FULL) != 0)
                   2865:                        adapter->advertise |= 1 << 5;
1.51      msaitoh  2866:        }
1.1       dyoung   2867:
                   2868:        return (0);
1.43      msaitoh  2869:
                   2870: invalid:
1.44      msaitoh  2871:        device_printf(adapter->dev, "Invalid media type!\n");
1.98      msaitoh  2872:
1.43      msaitoh  2873:        return (EINVAL);
1.99      msaitoh  2874: } /* ixgbe_media_change */
1.1       dyoung   2875:
1.99      msaitoh  2876: /************************************************************************
                   2877:  * ixgbe_set_promisc
                   2878:  ************************************************************************/
1.1       dyoung   2879: static void
                   2880: ixgbe_set_promisc(struct adapter *adapter)
                   2881: {
1.99      msaitoh  2882:        struct ifnet *ifp = adapter->ifp;
                   2883:        int          mcnt = 0;
                   2884:        u32          rctl;
1.28      msaitoh  2885:        struct ether_multi *enm;
                   2886:        struct ether_multistep step;
                   2887:        struct ethercom *ec = &adapter->osdep.ec;
1.1       dyoung   2888:
1.105     msaitoh  2889:        KASSERT(mutex_owned(&adapter->core_mtx));
1.99      msaitoh  2890:        rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
                   2891:        rctl &= (~IXGBE_FCTRL_UPE);
1.28      msaitoh  2892:        if (ifp->if_flags & IFF_ALLMULTI)
                   2893:                mcnt = MAX_NUM_MULTICAST_ADDRESSES;
                   2894:        else {
1.105     msaitoh  2895:                ETHER_LOCK(ec);
1.28      msaitoh  2896:                ETHER_FIRST_MULTI(step, ec, enm);
                   2897:                while (enm != NULL) {
                   2898:                        if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
                   2899:                                break;
                   2900:                        mcnt++;
                   2901:                        ETHER_NEXT_MULTI(step, enm);
                   2902:                }
1.105     msaitoh  2903:                ETHER_UNLOCK(ec);
1.28      msaitoh  2904:        }
                   2905:        if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
1.99      msaitoh  2906:                rctl &= (~IXGBE_FCTRL_MPE);
                   2907:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
1.1       dyoung   2908:
                   2909:        if (ifp->if_flags & IFF_PROMISC) {
1.99      msaitoh  2910:                rctl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
                   2911:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
1.1       dyoung   2912:        } else if (ifp->if_flags & IFF_ALLMULTI) {
1.99      msaitoh  2913:                rctl |= IXGBE_FCTRL_MPE;
                   2914:                rctl &= ~IXGBE_FCTRL_UPE;
                   2915:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, rctl);
                   2916:        }
                   2917: } /* ixgbe_set_promisc */
                   2918:
                   2919: /************************************************************************
                   2920:  * ixgbe_msix_link - Link status change ISR (MSI/MSI-X)
                   2921:  ************************************************************************/
1.98      msaitoh  2922: static int
                   2923: ixgbe_msix_link(void *arg)
                   2924: {
                   2925:        struct adapter  *adapter = arg;
                   2926:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  2927:        u32             eicr, eicr_mask;
                   2928:        s32             retval;
1.98      msaitoh  2929:
                   2930:        ++adapter->link_irq.ev_count;
                   2931:
                   2932:        /* Pause other interrupts */
                   2933:        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_OTHER);
1.1       dyoung   2934:
1.98      msaitoh  2935:        /* First get the cause */
1.125     knakahar 2936:        /*
                   2937:         * The specifications of 82598, 82599, X540 and X550 say EICS register
                   2938:         * is write only. However, Linux says it is a workaround for silicon
                   2939:         * errata to read EICS instead of EICR to get interrupt cause. It seems
                   2940:         * there is a problem about read clear mechanism for EICR register.
                   2941:         */
1.99      msaitoh  2942:        eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
1.98      msaitoh  2943:        /* Be sure the queue bits are not cleared */
1.99      msaitoh  2944:        eicr &= ~IXGBE_EICR_RTX_QUEUE;
1.98      msaitoh  2945:        /* Clear interrupt with write */
1.99      msaitoh  2946:        IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
1.1       dyoung   2947:
1.98      msaitoh  2948:        /* Link status change */
1.99      msaitoh  2949:        if (eicr & IXGBE_EICR_LSC) {
1.98      msaitoh  2950:                IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
                   2951:                softint_schedule(adapter->link_si);
                   2952:        }
1.1       dyoung   2953:
1.98      msaitoh  2954:        if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
1.99      msaitoh  2955:                if ((adapter->feat_en & IXGBE_FEATURE_FDIR) &&
                   2956:                    (eicr & IXGBE_EICR_FLOW_DIR)) {
1.98      msaitoh  2957:                        /* This is probably overkill :) */
1.99      msaitoh  2958:                        if (!atomic_cas_uint(&adapter->fdir_reinit, 0, 1))
1.98      msaitoh  2959:                                return 1;
                   2960:                        /* Disable the interrupt */
1.99      msaitoh  2961:                        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
1.98      msaitoh  2962:                        softint_schedule(adapter->fdir_si);
1.99      msaitoh  2963:                }
                   2964:
                   2965:                if (eicr & IXGBE_EICR_ECC) {
                   2966:                        device_printf(adapter->dev,
                   2967:                            "CRITICAL: ECC ERROR!! Please Reboot!!\n");
1.98      msaitoh  2968:                        IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
                   2969:                }
1.1       dyoung   2970:
1.98      msaitoh  2971:                /* Check for over temp condition */
1.99      msaitoh  2972:                if (adapter->feat_en & IXGBE_FEATURE_TEMP_SENSOR) {
                   2973:                        switch (adapter->hw.mac.type) {
                   2974:                        case ixgbe_mac_X550EM_a:
                   2975:                                if (!(eicr & IXGBE_EICR_GPI_SDP0_X550EM_a))
                   2976:                                        break;
                   2977:                                IXGBE_WRITE_REG(hw, IXGBE_EIMC,
                   2978:                                    IXGBE_EICR_GPI_SDP0_X550EM_a);
                   2979:                                IXGBE_WRITE_REG(hw, IXGBE_EICR,
                   2980:                                    IXGBE_EICR_GPI_SDP0_X550EM_a);
                   2981:                                retval = hw->phy.ops.check_overtemp(hw);
                   2982:                                if (retval != IXGBE_ERR_OVERTEMP)
                   2983:                                        break;
                   2984:                                device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n");
                   2985:                                device_printf(adapter->dev, "System shutdown required!\n");
                   2986:                                break;
                   2987:                        default:
                   2988:                                if (!(eicr & IXGBE_EICR_TS))
                   2989:                                        break;
                   2990:                                retval = hw->phy.ops.check_overtemp(hw);
                   2991:                                if (retval != IXGBE_ERR_OVERTEMP)
                   2992:                                        break;
                   2993:                                device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n");
                   2994:                                device_printf(adapter->dev, "System shutdown required!\n");
                   2995:                                IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
                   2996:                                break;
                   2997:                        }
1.1       dyoung   2998:                }
1.99      msaitoh  2999:
                   3000:                /* Check for VF message */
                   3001:                if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) &&
                   3002:                    (eicr & IXGBE_EICR_MAILBOX))
                   3003:                        softint_schedule(adapter->mbx_si);
1.1       dyoung   3004:        }
                   3005:
1.99      msaitoh  3006:        if (ixgbe_is_sfp(hw)) {
                   3007:                /* Pluggable optics-related interrupt */
                   3008:                if (hw->mac.type >= ixgbe_mac_X540)
                   3009:                        eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
                   3010:                else
                   3011:                        eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
1.98      msaitoh  3012:
1.99      msaitoh  3013:                if (eicr & eicr_mask) {
                   3014:                        IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
1.98      msaitoh  3015:                        softint_schedule(adapter->mod_si);
1.99      msaitoh  3016:                }
                   3017:
                   3018:                if ((hw->mac.type == ixgbe_mac_82599EB) &&
                   3019:                    (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
                   3020:                        IXGBE_WRITE_REG(hw, IXGBE_EICR,
                   3021:                            IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
1.98      msaitoh  3022:                        softint_schedule(adapter->msf_si);
                   3023:                }
1.28      msaitoh  3024:        }
                   3025:
1.98      msaitoh  3026:        /* Check for fan failure */
1.99      msaitoh  3027:        if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) {
                   3028:                ixgbe_check_fan_failure(adapter, eicr, TRUE);
                   3029:                IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
1.28      msaitoh  3030:        }
1.1       dyoung   3031:
1.98      msaitoh  3032:        /* External PHY interrupt */
1.99      msaitoh  3033:        if ((hw->phy.type == ixgbe_phy_x550em_ext_t) &&
                   3034:            (eicr & IXGBE_EICR_GPI_SDP0_X540)) {
1.98      msaitoh  3035:                IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540);
                   3036:                softint_schedule(adapter->phy_si);
                   3037:        }
                   3038:
                   3039:        /* Re-enable other interrupts */
1.99      msaitoh  3040:        IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
1.98      msaitoh  3041:        return 1;
1.99      msaitoh  3042: } /* ixgbe_msix_link */
1.1       dyoung   3043:
1.124     msaitoh  3044: static void
1.149   ! msaitoh  3045: ixgbe_eitr_write(struct adapter *adapter, uint32_t index, uint32_t itr)
1.124     msaitoh  3046: {
                   3047:
                   3048:         if (adapter->hw.mac.type == ixgbe_mac_82598EB)
                   3049:                 itr |= itr << 16;
                   3050:         else
                   3051:                 itr |= IXGBE_EITR_CNT_WDIS;
                   3052:
1.149   ! msaitoh  3053:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(index), itr);
1.124     msaitoh  3054: }
                   3055:
                   3056:
1.99      msaitoh  3057: /************************************************************************
                   3058:  * ixgbe_sysctl_interrupt_rate_handler
                   3059:  ************************************************************************/
1.98      msaitoh  3060: static int
                   3061: ixgbe_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS)
1.1       dyoung   3062: {
1.98      msaitoh  3063:        struct sysctlnode node = *rnode;
1.99      msaitoh  3064:        struct ix_queue *que = (struct ix_queue *)node.sysctl_data;
1.124     msaitoh  3065:        struct adapter  *adapter = que->adapter;
1.98      msaitoh  3066:        uint32_t reg, usec, rate;
                   3067:        int error;
1.45      msaitoh  3068:
1.98      msaitoh  3069:        if (que == NULL)
                   3070:                return 0;
                   3071:        reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_EITR(que->msix));
                   3072:        usec = ((reg & 0x0FF8) >> 3);
                   3073:        if (usec > 0)
                   3074:                rate = 500000 / usec;
                   3075:        else
                   3076:                rate = 0;
                   3077:        node.sysctl_data = &rate;
                   3078:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   3079:        if (error || newp == NULL)
                   3080:                return error;
                   3081:        reg &= ~0xfff; /* default, no limitation */
                   3082:        if (rate > 0 && rate < 500000) {
                   3083:                if (rate < 1000)
                   3084:                        rate = 1000;
1.124     msaitoh  3085:                reg |= ((4000000/rate) & 0xff8);
                   3086:                /*
                   3087:                 * When RSC is used, ITR interval must be larger than
                   3088:                 * RSC_DELAY. Currently, we use 2us for RSC_DELAY.
                   3089:                 * The minimum value is always greater than 2us on 100M
                   3090:                 * (and 10M?(not documented)), but it's not on 1G and higher.
                   3091:                 */
                   3092:                if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
                   3093:                    && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
                   3094:                        if ((adapter->num_queues > 1)
                   3095:                            && (reg < IXGBE_MIN_RSC_EITR_10G1G))
                   3096:                                return EINVAL;
                   3097:                }
1.98      msaitoh  3098:                ixgbe_max_interrupt_rate = rate;
1.124     msaitoh  3099:        } else
                   3100:                ixgbe_max_interrupt_rate = 0;
1.149   ! msaitoh  3101:        ixgbe_eitr_write(adapter, que->msix, reg);
1.99      msaitoh  3102:
                   3103:        return (0);
                   3104: } /* ixgbe_sysctl_interrupt_rate_handler */
1.45      msaitoh  3105:
1.98      msaitoh  3106: const struct sysctlnode *
                   3107: ixgbe_sysctl_instance(struct adapter *adapter)
                   3108: {
                   3109:        const char *dvname;
                   3110:        struct sysctllog **log;
                   3111:        int rc;
                   3112:        const struct sysctlnode *rnode;
1.1       dyoung   3113:
1.98      msaitoh  3114:        if (adapter->sysctltop != NULL)
                   3115:                return adapter->sysctltop;
1.1       dyoung   3116:
1.98      msaitoh  3117:        log = &adapter->sysctllog;
                   3118:        dvname = device_xname(adapter->dev);
1.1       dyoung   3119:
1.98      msaitoh  3120:        if ((rc = sysctl_createv(log, 0, NULL, &rnode,
                   3121:            0, CTLTYPE_NODE, dvname,
                   3122:            SYSCTL_DESCR("ixgbe information and settings"),
                   3123:            NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
                   3124:                goto err;
1.63      msaitoh  3125:
1.98      msaitoh  3126:        return rnode;
                   3127: err:
                   3128:        printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
                   3129:        return NULL;
1.63      msaitoh  3130: }
                   3131:
1.99      msaitoh  3132: /************************************************************************
                   3133:  * ixgbe_add_device_sysctls
                   3134:  ************************************************************************/
1.63      msaitoh  3135: static void
1.98      msaitoh  3136: ixgbe_add_device_sysctls(struct adapter *adapter)
1.1       dyoung   3137: {
1.99      msaitoh  3138:        device_t               dev = adapter->dev;
                   3139:        struct ixgbe_hw        *hw = &adapter->hw;
1.98      msaitoh  3140:        struct sysctllog **log;
                   3141:        const struct sysctlnode *rnode, *cnode;
1.1       dyoung   3142:
1.98      msaitoh  3143:        log = &adapter->sysctllog;
1.1       dyoung   3144:
1.98      msaitoh  3145:        if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL) {
                   3146:                aprint_error_dev(dev, "could not create sysctl root\n");
                   3147:                return;
                   3148:        }
1.1       dyoung   3149:
1.98      msaitoh  3150:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   3151:            CTLFLAG_READONLY, CTLTYPE_INT,
                   3152:            "num_rx_desc", SYSCTL_DESCR("Number of rx descriptors"),
                   3153:            NULL, 0, &adapter->num_rx_desc, 0, CTL_CREATE, CTL_EOL) != 0)
                   3154:                aprint_error_dev(dev, "could not create sysctl\n");
1.1       dyoung   3155:
1.98      msaitoh  3156:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   3157:            CTLFLAG_READONLY, CTLTYPE_INT,
                   3158:            "num_queues", SYSCTL_DESCR("Number of queues"),
                   3159:            NULL, 0, &adapter->num_queues, 0, CTL_CREATE, CTL_EOL) != 0)
                   3160:                aprint_error_dev(dev, "could not create sysctl\n");
1.43      msaitoh  3161:
1.98      msaitoh  3162:        /* Sysctls for all devices */
1.99      msaitoh  3163:        if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3164:            CTLTYPE_INT, "fc", SYSCTL_DESCR(IXGBE_SYSCTL_DESC_SET_FC),
                   3165:            ixgbe_sysctl_flowcntl, 0, (void *)adapter, 0, CTL_CREATE,
                   3166:            CTL_EOL) != 0)
1.98      msaitoh  3167:                aprint_error_dev(dev, "could not create sysctl\n");
1.63      msaitoh  3168:
1.99      msaitoh  3169:        adapter->enable_aim = ixgbe_enable_aim;
                   3170:        if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3171:            CTLTYPE_BOOL, "enable_aim", SYSCTL_DESCR("Interrupt Moderation"),
1.98      msaitoh  3172:            NULL, 0, &adapter->enable_aim, 0, CTL_CREATE, CTL_EOL) != 0)
                   3173:                aprint_error_dev(dev, "could not create sysctl\n");
1.1       dyoung   3174:
1.98      msaitoh  3175:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   3176:            CTLFLAG_READWRITE, CTLTYPE_INT,
                   3177:            "advertise_speed", SYSCTL_DESCR(IXGBE_SYSCTL_DESC_ADV_SPEED),
1.99      msaitoh  3178:            ixgbe_sysctl_advertise, 0, (void *)adapter, 0, CTL_CREATE,
                   3179:            CTL_EOL) != 0)
1.98      msaitoh  3180:                aprint_error_dev(dev, "could not create sysctl\n");
1.1       dyoung   3181:
1.147     knakahar 3182:        /*
                   3183:         * If each "que->txrx_use_workqueue" is changed in sysctl handler,
                   3184:         * it causesflip-flopping softint/workqueue mode in one deferred
                   3185:         * processing. Therefore, preempt_disable()/preempt_enable() are
                   3186:         * required in ixgbe_sched_handle_que() to avoid
                   3187:         * KASSERT(ixgbe_sched_handle_que()) in softint_schedule().
                   3188:         * I think changing "que->txrx_use_workqueue" in interrupt handler
                   3189:         * is lighter than doing preempt_disable()/preempt_enable() in every
                   3190:         * ixgbe_sched_handle_que().
                   3191:         */
1.128     knakahar 3192:        adapter->txrx_use_workqueue = ixgbe_txrx_workqueue;
                   3193:        if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3194:            CTLTYPE_BOOL, "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"),
                   3195:            NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL) != 0)
                   3196:                aprint_error_dev(dev, "could not create sysctl\n");
                   3197:
1.98      msaitoh  3198: #ifdef IXGBE_DEBUG
                   3199:        /* testing sysctls (for all devices) */
1.99      msaitoh  3200:        if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3201:            CTLTYPE_INT, "power_state", SYSCTL_DESCR("PCI Power State"),
                   3202:            ixgbe_sysctl_power_state, 0, (void *)adapter, 0, CTL_CREATE,
                   3203:            CTL_EOL) != 0)
1.98      msaitoh  3204:                aprint_error_dev(dev, "could not create sysctl\n");
1.45      msaitoh  3205:
1.99      msaitoh  3206:        if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY,
                   3207:            CTLTYPE_STRING, "print_rss_config",
                   3208:            SYSCTL_DESCR("Prints RSS Configuration"),
                   3209:            ixgbe_sysctl_print_rss_config, 0, (void *)adapter, 0, CTL_CREATE,
                   3210:            CTL_EOL) != 0)
1.98      msaitoh  3211:                aprint_error_dev(dev, "could not create sysctl\n");
                   3212: #endif
                   3213:        /* for X550 series devices */
                   3214:        if (hw->mac.type >= ixgbe_mac_X550)
1.99      msaitoh  3215:                if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3216:                    CTLTYPE_INT, "dmac", SYSCTL_DESCR("DMA Coalesce"),
                   3217:                    ixgbe_sysctl_dmac, 0, (void *)adapter, 0, CTL_CREATE,
                   3218:                    CTL_EOL) != 0)
1.98      msaitoh  3219:                        aprint_error_dev(dev, "could not create sysctl\n");
1.1       dyoung   3220:
1.98      msaitoh  3221:        /* for WoL-capable devices */
                   3222:        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
1.99      msaitoh  3223:                if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3224:                    CTLTYPE_BOOL, "wol_enable",
                   3225:                    SYSCTL_DESCR("Enable/Disable Wake on LAN"),
                   3226:                    ixgbe_sysctl_wol_enable, 0, (void *)adapter, 0, CTL_CREATE,
                   3227:                    CTL_EOL) != 0)
1.98      msaitoh  3228:                        aprint_error_dev(dev, "could not create sysctl\n");
1.1       dyoung   3229:
1.99      msaitoh  3230:                if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3231:                    CTLTYPE_INT, "wufc",
                   3232:                    SYSCTL_DESCR("Enable/Disable Wake Up Filters"),
                   3233:                    ixgbe_sysctl_wufc, 0, (void *)adapter, 0, CTL_CREATE,
                   3234:                    CTL_EOL) != 0)
1.98      msaitoh  3235:                        aprint_error_dev(dev, "could not create sysctl\n");
                   3236:        }
1.1       dyoung   3237:
1.98      msaitoh  3238:        /* for X552/X557-AT devices */
                   3239:        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
                   3240:                const struct sysctlnode *phy_node;
1.1       dyoung   3241:
1.99      msaitoh  3242:                if (sysctl_createv(log, 0, &rnode, &phy_node, 0, CTLTYPE_NODE,
1.98      msaitoh  3243:                    "phy", SYSCTL_DESCR("External PHY sysctls"),
                   3244:                    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0) {
                   3245:                        aprint_error_dev(dev, "could not create sysctl\n");
                   3246:                        return;
                   3247:                }
1.1       dyoung   3248:
1.99      msaitoh  3249:                if (sysctl_createv(log, 0, &phy_node, &cnode, CTLFLAG_READONLY,
                   3250:                    CTLTYPE_INT, "temp",
                   3251:                    SYSCTL_DESCR("Current External PHY Temperature (Celsius)"),
                   3252:                    ixgbe_sysctl_phy_temp, 0, (void *)adapter, 0, CTL_CREATE,
                   3253:                    CTL_EOL) != 0)
                   3254:                        aprint_error_dev(dev, "could not create sysctl\n");
                   3255:
                   3256:                if (sysctl_createv(log, 0, &phy_node, &cnode, CTLFLAG_READONLY,
                   3257:                    CTLTYPE_INT, "overtemp_occurred",
                   3258:                    SYSCTL_DESCR("External PHY High Temperature Event Occurred"),
                   3259:                    ixgbe_sysctl_phy_overtemp_occurred, 0, (void *)adapter, 0,
                   3260:                    CTL_CREATE, CTL_EOL) != 0)
1.98      msaitoh  3261:                        aprint_error_dev(dev, "could not create sysctl\n");
1.99      msaitoh  3262:        }
1.33      msaitoh  3263:
1.99      msaitoh  3264:        if (adapter->feat_cap & IXGBE_FEATURE_EEE) {
                   3265:                if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE,
                   3266:                    CTLTYPE_INT, "eee_state",
                   3267:                    SYSCTL_DESCR("EEE Power Save State"),
                   3268:                    ixgbe_sysctl_eee_state, 0, (void *)adapter, 0, CTL_CREATE,
                   3269:                    CTL_EOL) != 0)
1.98      msaitoh  3270:                        aprint_error_dev(dev, "could not create sysctl\n");
                   3271:        }
1.99      msaitoh  3272: } /* ixgbe_add_device_sysctls */
1.1       dyoung   3273:
1.99      msaitoh  3274: /************************************************************************
                   3275:  * ixgbe_allocate_pci_resources
                   3276:  ************************************************************************/
1.98      msaitoh  3277: static int
                   3278: ixgbe_allocate_pci_resources(struct adapter *adapter,
                   3279:     const struct pci_attach_args *pa)
1.1       dyoung   3280: {
1.98      msaitoh  3281:        pcireg_t        memtype;
1.99      msaitoh  3282:        device_t dev = adapter->dev;
1.98      msaitoh  3283:        bus_addr_t addr;
                   3284:        int flags;
1.1       dyoung   3285:
1.98      msaitoh  3286:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR(0));
                   3287:        switch (memtype) {
                   3288:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
                   3289:        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                   3290:                adapter->osdep.mem_bus_space_tag = pa->pa_memt;
                   3291:                if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_BAR(0),
                   3292:                      memtype, &addr, &adapter->osdep.mem_size, &flags) != 0)
                   3293:                        goto map_err;
                   3294:                if ((flags & BUS_SPACE_MAP_PREFETCHABLE) != 0) {
                   3295:                        aprint_normal_dev(dev, "clearing prefetchable bit\n");
                   3296:                        flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
                   3297:                }
                   3298:                if (bus_space_map(adapter->osdep.mem_bus_space_tag, addr,
                   3299:                     adapter->osdep.mem_size, flags,
                   3300:                     &adapter->osdep.mem_bus_space_handle) != 0) {
                   3301: map_err:
                   3302:                        adapter->osdep.mem_size = 0;
                   3303:                        aprint_error_dev(dev, "unable to map BAR0\n");
                   3304:                        return ENXIO;
                   3305:                }
                   3306:                break;
                   3307:        default:
                   3308:                aprint_error_dev(dev, "unexpected type on BAR0\n");
                   3309:                return ENXIO;
                   3310:        }
1.1       dyoung   3311:
1.98      msaitoh  3312:        return (0);
1.99      msaitoh  3313: } /* ixgbe_allocate_pci_resources */
1.1       dyoung   3314:
1.119     msaitoh  3315: static void
                   3316: ixgbe_free_softint(struct adapter *adapter)
                   3317: {
                   3318:        struct ix_queue *que = adapter->queues;
                   3319:        struct tx_ring *txr = adapter->tx_rings;
                   3320:        int i;
                   3321:
                   3322:        for (i = 0; i < adapter->num_queues; i++, que++, txr++) {
                   3323:                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) {
                   3324:                        if (txr->txr_si != NULL)
                   3325:                                softint_disestablish(txr->txr_si);
                   3326:                }
                   3327:                if (que->que_si != NULL)
                   3328:                        softint_disestablish(que->que_si);
                   3329:        }
1.128     knakahar 3330:        if (adapter->txr_wq != NULL)
                   3331:                workqueue_destroy(adapter->txr_wq);
                   3332:        if (adapter->txr_wq_enqueued != NULL)
                   3333:                percpu_free(adapter->txr_wq_enqueued, sizeof(u_int));
                   3334:        if (adapter->que_wq != NULL)
                   3335:                workqueue_destroy(adapter->que_wq);
1.119     msaitoh  3336:
                   3337:        /* Drain the Link queue */
                   3338:        if (adapter->link_si != NULL) {
                   3339:                softint_disestablish(adapter->link_si);
                   3340:                adapter->link_si = NULL;
                   3341:        }
                   3342:        if (adapter->mod_si != NULL) {
                   3343:                softint_disestablish(adapter->mod_si);
                   3344:                adapter->mod_si = NULL;
                   3345:        }
                   3346:        if (adapter->msf_si != NULL) {
                   3347:                softint_disestablish(adapter->msf_si);
                   3348:                adapter->msf_si = NULL;
                   3349:        }
                   3350:        if (adapter->phy_si != NULL) {
                   3351:                softint_disestablish(adapter->phy_si);
                   3352:                adapter->phy_si = NULL;
                   3353:        }
                   3354:        if (adapter->feat_en & IXGBE_FEATURE_FDIR) {
                   3355:                if (adapter->fdir_si != NULL) {
                   3356:                        softint_disestablish(adapter->fdir_si);
                   3357:                        adapter->fdir_si = NULL;
                   3358:                }
                   3359:        }
                   3360:        if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) {
                   3361:                if (adapter->mbx_si != NULL) {
                   3362:                        softint_disestablish(adapter->mbx_si);
                   3363:                        adapter->mbx_si = NULL;
                   3364:                }
                   3365:        }
                   3366: } /* ixgbe_free_softint */
                   3367:
1.99      msaitoh  3368: /************************************************************************
                   3369:  * ixgbe_detach - Device removal routine
1.1       dyoung   3370:  *
1.99      msaitoh  3371:  *   Called when the driver is being removed.
                   3372:  *   Stops the adapter and deallocates all the resources
                   3373:  *   that were allocated for driver operation.
1.1       dyoung   3374:  *
1.99      msaitoh  3375:  *   return 0 on success, positive on failure
                   3376:  ************************************************************************/
1.98      msaitoh  3377: static int
                   3378: ixgbe_detach(device_t dev, int flags)
1.1       dyoung   3379: {
1.98      msaitoh  3380:        struct adapter *adapter = device_private(dev);
                   3381:        struct rx_ring *rxr = adapter->rx_rings;
                   3382:        struct tx_ring *txr = adapter->tx_rings;
1.1       dyoung   3383:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  3384:        struct ixgbe_hw_stats *stats = &adapter->stats.pf;
                   3385:        u32     ctrl_ext;
1.28      msaitoh  3386:
1.98      msaitoh  3387:        INIT_DEBUGOUT("ixgbe_detach: begin");
                   3388:        if (adapter->osdep.attached == false)
                   3389:                return 0;
1.26      msaitoh  3390:
1.99      msaitoh  3391:        if (ixgbe_pci_iov_detach(dev) != 0) {
                   3392:                device_printf(dev, "SR-IOV in use; detach first.\n");
                   3393:                return (EBUSY);
                   3394:        }
                   3395:
1.98      msaitoh  3396:        /* Stop the interface. Callouts are stopped in it. */
                   3397:        ixgbe_ifstop(adapter->ifp, 1);
                   3398: #if NVLAN > 0
                   3399:        /* Make sure VLANs are not using driver */
                   3400:        if (!VLAN_ATTACHED(&adapter->osdep.ec))
                   3401:                ;       /* nothing to do: no VLANs */
                   3402:        else if ((flags & (DETACH_SHUTDOWN|DETACH_FORCE)) != 0)
                   3403:                vlan_ifdetach(adapter->ifp);
                   3404:        else {
1.99      msaitoh  3405:                aprint_error_dev(dev, "VLANs in use, detach first\n");
                   3406:                return (EBUSY);
1.26      msaitoh  3407:        }
1.98      msaitoh  3408: #endif
1.24      msaitoh  3409:
1.98      msaitoh  3410:        pmf_device_deregister(dev);
1.26      msaitoh  3411:
1.98      msaitoh  3412:        ether_ifdetach(adapter->ifp);
                   3413:        /* Stop the adapter */
                   3414:        IXGBE_CORE_LOCK(adapter);
                   3415:        ixgbe_setup_low_power_mode(adapter);
                   3416:        IXGBE_CORE_UNLOCK(adapter);
1.24      msaitoh  3417:
1.119     msaitoh  3418:        ixgbe_free_softint(adapter);
                   3419:
1.98      msaitoh  3420:        /* let hardware know driver is unloading */
                   3421:        ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
                   3422:        ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD;
                   3423:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext);
1.24      msaitoh  3424:
1.98      msaitoh  3425:        callout_halt(&adapter->timer, NULL);
1.99      msaitoh  3426:
                   3427:        if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
                   3428:                netmap_detach(adapter->ifp);
                   3429:
1.98      msaitoh  3430:        ixgbe_free_pci_resources(adapter);
                   3431: #if 0  /* XXX the NetBSD port is probably missing something here */
                   3432:        bus_generic_detach(dev);
                   3433: #endif
                   3434:        if_detach(adapter->ifp);
                   3435:        if_percpuq_destroy(adapter->ipq);
1.24      msaitoh  3436:
1.98      msaitoh  3437:        sysctl_teardown(&adapter->sysctllog);
                   3438:        evcnt_detach(&adapter->efbig_tx_dma_setup);
                   3439:        evcnt_detach(&adapter->mbuf_defrag_failed);
                   3440:        evcnt_detach(&adapter->efbig2_tx_dma_setup);
                   3441:        evcnt_detach(&adapter->einval_tx_dma_setup);
                   3442:        evcnt_detach(&adapter->other_tx_dma_setup);
                   3443:        evcnt_detach(&adapter->eagain_tx_dma_setup);
                   3444:        evcnt_detach(&adapter->enomem_tx_dma_setup);
                   3445:        evcnt_detach(&adapter->watchdog_events);
                   3446:        evcnt_detach(&adapter->tso_err);
                   3447:        evcnt_detach(&adapter->link_irq);
1.137     msaitoh  3448:        evcnt_detach(&adapter->link_sicount);
                   3449:        evcnt_detach(&adapter->mod_sicount);
                   3450:        evcnt_detach(&adapter->msf_sicount);
                   3451:        evcnt_detach(&adapter->phy_sicount);
1.1       dyoung   3452:
1.98      msaitoh  3453:        txr = adapter->tx_rings;
                   3454:        for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
                   3455:                evcnt_detach(&adapter->queues[i].irqs);
1.129     msaitoh  3456:                evcnt_detach(&adapter->queues[i].handleq);
                   3457:                evcnt_detach(&adapter->queues[i].req);
1.98      msaitoh  3458:                evcnt_detach(&txr->no_desc_avail);
                   3459:                evcnt_detach(&txr->total_packets);
                   3460:                evcnt_detach(&txr->tso_tx);
1.28      msaitoh  3461: #ifndef IXGBE_LEGACY_TX
1.98      msaitoh  3462:                evcnt_detach(&txr->pcq_drops);
1.26      msaitoh  3463: #endif
1.34      msaitoh  3464:
1.98      msaitoh  3465:                if (i < __arraycount(stats->mpc)) {
                   3466:                        evcnt_detach(&stats->mpc[i]);
                   3467:                        if (hw->mac.type == ixgbe_mac_82598EB)
                   3468:                                evcnt_detach(&stats->rnbc[i]);
                   3469:                }
                   3470:                if (i < __arraycount(stats->pxontxc)) {
                   3471:                        evcnt_detach(&stats->pxontxc[i]);
                   3472:                        evcnt_detach(&stats->pxonrxc[i]);
                   3473:                        evcnt_detach(&stats->pxofftxc[i]);
                   3474:                        evcnt_detach(&stats->pxoffrxc[i]);
                   3475:                        evcnt_detach(&stats->pxon2offc[i]);
                   3476:                }
                   3477:                if (i < __arraycount(stats->qprc)) {
                   3478:                        evcnt_detach(&stats->qprc[i]);
                   3479:                        evcnt_detach(&stats->qptc[i]);
                   3480:                        evcnt_detach(&stats->qbrc[i]);
                   3481:                        evcnt_detach(&stats->qbtc[i]);
                   3482:                        evcnt_detach(&stats->qprdc[i]);
1.34      msaitoh  3483:                }
1.98      msaitoh  3484:
                   3485:                evcnt_detach(&rxr->rx_packets);
                   3486:                evcnt_detach(&rxr->rx_bytes);
                   3487:                evcnt_detach(&rxr->rx_copies);
                   3488:                evcnt_detach(&rxr->no_jmbuf);
                   3489:                evcnt_detach(&rxr->rx_discarded);
1.1       dyoung   3490:        }
1.98      msaitoh  3491:        evcnt_detach(&stats->ipcs);
                   3492:        evcnt_detach(&stats->l4cs);
                   3493:        evcnt_detach(&stats->ipcs_bad);
                   3494:        evcnt_detach(&stats->l4cs_bad);
                   3495:        evcnt_detach(&stats->intzero);
                   3496:        evcnt_detach(&stats->legint);
                   3497:        evcnt_detach(&stats->crcerrs);
                   3498:        evcnt_detach(&stats->illerrc);
                   3499:        evcnt_detach(&stats->errbc);
                   3500:        evcnt_detach(&stats->mspdc);
                   3501:        if (hw->mac.type >= ixgbe_mac_X550)
                   3502:                evcnt_detach(&stats->mbsdc);
                   3503:        evcnt_detach(&stats->mpctotal);
                   3504:        evcnt_detach(&stats->mlfc);
                   3505:        evcnt_detach(&stats->mrfc);
                   3506:        evcnt_detach(&stats->rlec);
                   3507:        evcnt_detach(&stats->lxontxc);
                   3508:        evcnt_detach(&stats->lxonrxc);
                   3509:        evcnt_detach(&stats->lxofftxc);
                   3510:        evcnt_detach(&stats->lxoffrxc);
                   3511:
                   3512:        /* Packet Reception Stats */
                   3513:        evcnt_detach(&stats->tor);
                   3514:        evcnt_detach(&stats->gorc);
                   3515:        evcnt_detach(&stats->tpr);
                   3516:        evcnt_detach(&stats->gprc);
                   3517:        evcnt_detach(&stats->mprc);
                   3518:        evcnt_detach(&stats->bprc);
                   3519:        evcnt_detach(&stats->prc64);
                   3520:        evcnt_detach(&stats->prc127);
                   3521:        evcnt_detach(&stats->prc255);
                   3522:        evcnt_detach(&stats->prc511);
                   3523:        evcnt_detach(&stats->prc1023);
                   3524:        evcnt_detach(&stats->prc1522);
                   3525:        evcnt_detach(&stats->ruc);
                   3526:        evcnt_detach(&stats->rfc);
                   3527:        evcnt_detach(&stats->roc);
                   3528:        evcnt_detach(&stats->rjc);
                   3529:        evcnt_detach(&stats->mngprc);
                   3530:        evcnt_detach(&stats->mngpdc);
                   3531:        evcnt_detach(&stats->xec);
1.1       dyoung   3532:
1.98      msaitoh  3533:        /* Packet Transmission Stats */
                   3534:        evcnt_detach(&stats->gotc);
                   3535:        evcnt_detach(&stats->tpt);
                   3536:        evcnt_detach(&stats->gptc);
                   3537:        evcnt_detach(&stats->bptc);
                   3538:        evcnt_detach(&stats->mptc);
                   3539:        evcnt_detach(&stats->mngptc);
                   3540:        evcnt_detach(&stats->ptc64);
                   3541:        evcnt_detach(&stats->ptc127);
                   3542:        evcnt_detach(&stats->ptc255);
                   3543:        evcnt_detach(&stats->ptc511);
                   3544:        evcnt_detach(&stats->ptc1023);
                   3545:        evcnt_detach(&stats->ptc1522);
1.1       dyoung   3546:
1.98      msaitoh  3547:        ixgbe_free_transmit_structures(adapter);
                   3548:        ixgbe_free_receive_structures(adapter);
1.127     knakahar 3549:        for (int i = 0; i < adapter->num_queues; i++) {
                   3550:                struct ix_queue * que = &adapter->queues[i];
1.139     knakahar 3551:                mutex_destroy(&que->dc_mtx);
1.127     knakahar 3552:        }
1.99      msaitoh  3553:        free(adapter->queues, M_DEVBUF);
1.98      msaitoh  3554:        free(adapter->mta, M_DEVBUF);
1.1       dyoung   3555:
1.98      msaitoh  3556:        IXGBE_CORE_LOCK_DESTROY(adapter);
1.1       dyoung   3557:
                   3558:        return (0);
1.99      msaitoh  3559: } /* ixgbe_detach */
1.1       dyoung   3560:
1.99      msaitoh  3561: /************************************************************************
                   3562:  * ixgbe_setup_low_power_mode - LPLU/WoL preparation
                   3563:  *
                   3564:  *   Prepare the adapter/port for LPLU and/or WoL
                   3565:  ************************************************************************/
1.1       dyoung   3566: static int
1.98      msaitoh  3567: ixgbe_setup_low_power_mode(struct adapter *adapter)
1.1       dyoung   3568: {
1.98      msaitoh  3569:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  3570:        device_t        dev = adapter->dev;
                   3571:        s32             error = 0;
1.98      msaitoh  3572:
                   3573:        KASSERT(mutex_owned(&adapter->core_mtx));
                   3574:
                   3575:        /* Limit power management flow to X550EM baseT */
1.99      msaitoh  3576:        if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T &&
                   3577:            hw->phy.ops.enter_lplu) {
1.98      msaitoh  3578:                /* X550EM baseT adapters need a special LPLU flow */
                   3579:                hw->phy.reset_disable = true;
                   3580:                ixgbe_stop(adapter);
                   3581:                error = hw->phy.ops.enter_lplu(hw);
                   3582:                if (error)
                   3583:                        device_printf(dev,
                   3584:                            "Error entering LPLU: %d\n", error);
                   3585:                hw->phy.reset_disable = false;
                   3586:        } else {
                   3587:                /* Just stop for other adapters */
                   3588:                ixgbe_stop(adapter);
1.33      msaitoh  3589:        }
1.1       dyoung   3590:
1.98      msaitoh  3591:        if (!hw->wol_enabled) {
                   3592:                ixgbe_set_phy_power(hw, FALSE);
                   3593:                IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
                   3594:                IXGBE_WRITE_REG(hw, IXGBE_WUC, 0);
                   3595:        } else {
                   3596:                /* Turn off support for APM wakeup. (Using ACPI instead) */
                   3597:                IXGBE_WRITE_REG(hw, IXGBE_GRC,
                   3598:                    IXGBE_READ_REG(hw, IXGBE_GRC) & ~(u32)2);
1.34      msaitoh  3599:
1.35      msaitoh  3600:                /*
1.98      msaitoh  3601:                 * Clear Wake Up Status register to prevent any previous wakeup
                   3602:                 * events from waking us up immediately after we suspend.
1.33      msaitoh  3603:                 */
1.98      msaitoh  3604:                IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff);
                   3605:
1.1       dyoung   3606:                /*
1.98      msaitoh  3607:                 * Program the Wakeup Filter Control register with user filter
                   3608:                 * settings
1.33      msaitoh  3609:                 */
1.98      msaitoh  3610:                IXGBE_WRITE_REG(hw, IXGBE_WUFC, adapter->wufc);
                   3611:
                   3612:                /* Enable wakeups and power management in Wakeup Control */
                   3613:                IXGBE_WRITE_REG(hw, IXGBE_WUC,
                   3614:                    IXGBE_WUC_WKEN | IXGBE_WUC_PME_EN);
                   3615:
1.1       dyoung   3616:        }
                   3617:
1.98      msaitoh  3618:        return error;
1.99      msaitoh  3619: } /* ixgbe_setup_low_power_mode */
1.98      msaitoh  3620:
1.99      msaitoh  3621: /************************************************************************
                   3622:  * ixgbe_shutdown - Shutdown entry point
                   3623:  ************************************************************************/
1.98      msaitoh  3624: #if 0 /* XXX NetBSD ought to register something like this through pmf(9) */
                   3625: static int
                   3626: ixgbe_shutdown(device_t dev)
                   3627: {
                   3628:        struct adapter *adapter = device_private(dev);
                   3629:        int error = 0;
1.34      msaitoh  3630:
1.98      msaitoh  3631:        INIT_DEBUGOUT("ixgbe_shutdown: begin");
1.34      msaitoh  3632:
1.98      msaitoh  3633:        IXGBE_CORE_LOCK(adapter);
                   3634:        error = ixgbe_setup_low_power_mode(adapter);
                   3635:        IXGBE_CORE_UNLOCK(adapter);
1.1       dyoung   3636:
1.98      msaitoh  3637:        return (error);
1.99      msaitoh  3638: } /* ixgbe_shutdown */
1.98      msaitoh  3639: #endif
1.1       dyoung   3640:
1.99      msaitoh  3641: /************************************************************************
                   3642:  * ixgbe_suspend
                   3643:  *
                   3644:  *   From D0 to D3
                   3645:  ************************************************************************/
1.98      msaitoh  3646: static bool
                   3647: ixgbe_suspend(device_t dev, const pmf_qual_t *qual)
1.1       dyoung   3648: {
1.98      msaitoh  3649:        struct adapter *adapter = device_private(dev);
1.99      msaitoh  3650:        int            error = 0;
1.98      msaitoh  3651:
                   3652:        INIT_DEBUGOUT("ixgbe_suspend: begin");
                   3653:
                   3654:        IXGBE_CORE_LOCK(adapter);
1.1       dyoung   3655:
1.98      msaitoh  3656:        error = ixgbe_setup_low_power_mode(adapter);
1.1       dyoung   3657:
1.98      msaitoh  3658:        IXGBE_CORE_UNLOCK(adapter);
1.34      msaitoh  3659:
1.98      msaitoh  3660:        return (error);
1.99      msaitoh  3661: } /* ixgbe_suspend */
1.1       dyoung   3662:
1.99      msaitoh  3663: /************************************************************************
                   3664:  * ixgbe_resume
                   3665:  *
                   3666:  *   From D3 to D0
                   3667:  ************************************************************************/
1.98      msaitoh  3668: static bool
                   3669: ixgbe_resume(device_t dev, const pmf_qual_t *qual)
                   3670: {
1.99      msaitoh  3671:        struct adapter  *adapter = device_private(dev);
                   3672:        struct ifnet    *ifp = adapter->ifp;
1.98      msaitoh  3673:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  3674:        u32             wus;
1.1       dyoung   3675:
1.98      msaitoh  3676:        INIT_DEBUGOUT("ixgbe_resume: begin");
1.33      msaitoh  3677:
1.98      msaitoh  3678:        IXGBE_CORE_LOCK(adapter);
1.43      msaitoh  3679:
1.98      msaitoh  3680:        /* Read & clear WUS register */
                   3681:        wus = IXGBE_READ_REG(hw, IXGBE_WUS);
                   3682:        if (wus)
                   3683:                device_printf(dev, "Woken up by (WUS): %#010x\n",
                   3684:                    IXGBE_READ_REG(hw, IXGBE_WUS));
                   3685:        IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff);
                   3686:        /* And clear WUFC until next low-power transition */
                   3687:        IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
1.1       dyoung   3688:
                   3689:        /*
1.98      msaitoh  3690:         * Required after D3->D0 transition;
                   3691:         * will re-advertise all previous advertised speeds
                   3692:         */
                   3693:        if (ifp->if_flags & IFF_UP)
                   3694:                ixgbe_init_locked(adapter);
1.34      msaitoh  3695:
1.98      msaitoh  3696:        IXGBE_CORE_UNLOCK(adapter);
1.1       dyoung   3697:
1.98      msaitoh  3698:        return true;
1.99      msaitoh  3699: } /* ixgbe_resume */
1.1       dyoung   3700:
1.98      msaitoh  3701: /*
                   3702:  * Set the various hardware offload abilities.
                   3703:  *
                   3704:  * This takes the ifnet's if_capenable flags (e.g. set by the user using
                   3705:  * ifconfig) and indicates to the OS via the ifnet's if_hwassist field what
                   3706:  * mbuf offload flags the driver will understand.
                   3707:  */
1.1       dyoung   3708: static void
1.98      msaitoh  3709: ixgbe_set_if_hwassist(struct adapter *adapter)
1.1       dyoung   3710: {
1.98      msaitoh  3711:        /* XXX */
1.1       dyoung   3712: }
                   3713:
1.99      msaitoh  3714: /************************************************************************
                   3715:  * ixgbe_init_locked - Init entry point
                   3716:  *
                   3717:  *   Used in two ways: It is used by the stack as an init
                   3718:  *   entry point in network interface structure. It is also
                   3719:  *   used by the driver as a hw/sw initialization routine to
                   3720:  *   get to a consistent state.
1.1       dyoung   3721:  *
1.99      msaitoh  3722:  *   return 0 on success, positive on failure
                   3723:  ************************************************************************/
1.98      msaitoh  3724: static void
                   3725: ixgbe_init_locked(struct adapter *adapter)
1.1       dyoung   3726: {
1.98      msaitoh  3727:        struct ifnet   *ifp = adapter->ifp;
                   3728:        device_t        dev = adapter->dev;
                   3729:        struct ixgbe_hw *hw = &adapter->hw;
                   3730:        struct tx_ring  *txr;
                   3731:        struct rx_ring  *rxr;
                   3732:        u32             txdctl, mhadd;
                   3733:        u32             rxdctl, rxctrl;
1.99      msaitoh  3734:        u32             ctrl_ext;
1.144     msaitoh  3735:        int             i, j, err;
1.1       dyoung   3736:
1.98      msaitoh  3737:        /* XXX check IFF_UP and IFF_RUNNING, power-saving state! */
1.1       dyoung   3738:
1.98      msaitoh  3739:        KASSERT(mutex_owned(&adapter->core_mtx));
                   3740:        INIT_DEBUGOUT("ixgbe_init_locked: begin");
1.1       dyoung   3741:
1.98      msaitoh  3742:        hw->adapter_stopped = FALSE;
                   3743:        ixgbe_stop_adapter(hw);
                   3744:         callout_stop(&adapter->timer);
1.1       dyoung   3745:
1.98      msaitoh  3746:        /* XXX I moved this here from the SIOCSIFMTU case in ixgbe_ioctl(). */
1.1       dyoung   3747:        adapter->max_frame_size =
1.98      msaitoh  3748:                ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
1.1       dyoung   3749:
1.98      msaitoh  3750:        /* Queue indices may change with IOV mode */
1.99      msaitoh  3751:        ixgbe_align_all_queue_indices(adapter);
                   3752:
1.98      msaitoh  3753:        /* reprogram the RAR[0] in case user changed it. */
                   3754:        ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, IXGBE_RAH_AV);
1.1       dyoung   3755:
1.98      msaitoh  3756:        /* Get the latest mac address, User can use a LAA */
                   3757:        memcpy(hw->mac.addr, CLLADDR(ifp->if_sadl),
                   3758:            IXGBE_ETH_LENGTH_OF_ADDRESS);
                   3759:        ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, 1);
                   3760:        hw->addr_ctrl.rar_used_count = 1;
1.1       dyoung   3761:
1.98      msaitoh  3762:        /* Set hardware offload abilities from ifnet flags */
                   3763:        ixgbe_set_if_hwassist(adapter);
1.48      msaitoh  3764:
1.98      msaitoh  3765:        /* Prepare transmit descriptors and buffers */
                   3766:        if (ixgbe_setup_transmit_structures(adapter)) {
                   3767:                device_printf(dev, "Could not setup transmit structures\n");
                   3768:                ixgbe_stop(adapter);
                   3769:                return;
                   3770:        }
1.1       dyoung   3771:
1.98      msaitoh  3772:        ixgbe_init_hw(hw);
1.144     msaitoh  3773:
1.98      msaitoh  3774:        ixgbe_initialize_iov(adapter);
1.144     msaitoh  3775:
1.98      msaitoh  3776:        ixgbe_initialize_transmit_units(adapter);
1.1       dyoung   3777:
1.98      msaitoh  3778:        /* Setup Multicast table */
                   3779:        ixgbe_set_multi(adapter);
1.43      msaitoh  3780:
1.98      msaitoh  3781:        /* Determine the correct mbuf pool, based on frame size */
                   3782:        if (adapter->max_frame_size <= MCLBYTES)
                   3783:                adapter->rx_mbuf_sz = MCLBYTES;
                   3784:        else
                   3785:                adapter->rx_mbuf_sz = MJUMPAGESIZE;
1.43      msaitoh  3786:
1.98      msaitoh  3787:        /* Prepare receive descriptors and buffers */
                   3788:        if (ixgbe_setup_receive_structures(adapter)) {
                   3789:                device_printf(dev, "Could not setup receive structures\n");
                   3790:                ixgbe_stop(adapter);
                   3791:                return;
                   3792:        }
1.43      msaitoh  3793:
1.98      msaitoh  3794:        /* Configure RX settings */
                   3795:        ixgbe_initialize_receive_units(adapter);
1.43      msaitoh  3796:
1.99      msaitoh  3797:        /* Enable SDP & MSI-X interrupts based on adapter */
1.98      msaitoh  3798:        ixgbe_config_gpie(adapter);
1.43      msaitoh  3799:
1.98      msaitoh  3800:        /* Set MTU size */
                   3801:        if (ifp->if_mtu > ETHERMTU) {
                   3802:                /* aka IXGBE_MAXFRS on 82599 and newer */
                   3803:                mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
                   3804:                mhadd &= ~IXGBE_MHADD_MFS_MASK;
                   3805:                mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
                   3806:                IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
1.55      msaitoh  3807:        }
                   3808:
1.98      msaitoh  3809:        /* Now enable all the queues */
1.144     msaitoh  3810:        for (i = 0; i < adapter->num_queues; i++) {
1.98      msaitoh  3811:                txr = &adapter->tx_rings[i];
                   3812:                txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(txr->me));
                   3813:                txdctl |= IXGBE_TXDCTL_ENABLE;
                   3814:                /* Set WTHRESH to 8, burst writeback */
                   3815:                txdctl |= (8 << 16);
                   3816:                /*
                   3817:                 * When the internal queue falls below PTHRESH (32),
                   3818:                 * start prefetching as long as there are at least
                   3819:                 * HTHRESH (1) buffers ready. The values are taken
                   3820:                 * from the Intel linux driver 3.8.21.
                   3821:                 * Prefetching enables tx line rate even with 1 queue.
                   3822:                 */
                   3823:                txdctl |= (32 << 0) | (1 << 8);
                   3824:                IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(txr->me), txdctl);
1.55      msaitoh  3825:        }
1.43      msaitoh  3826:
1.144     msaitoh  3827:        for (i = 0; i < adapter->num_queues; i++) {
1.98      msaitoh  3828:                rxr = &adapter->rx_rings[i];
                   3829:                rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me));
                   3830:                if (hw->mac.type == ixgbe_mac_82598EB) {
                   3831:                        /*
1.99      msaitoh  3832:                         * PTHRESH = 21
                   3833:                         * HTHRESH = 4
                   3834:                         * WTHRESH = 8
                   3835:                         */
1.98      msaitoh  3836:                        rxdctl &= ~0x3FFFFF;
                   3837:                        rxdctl |= 0x080420;
                   3838:                }
                   3839:                rxdctl |= IXGBE_RXDCTL_ENABLE;
                   3840:                IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), rxdctl);
1.144     msaitoh  3841:                for (j = 0; j < 10; j++) {
1.98      msaitoh  3842:                        if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)) &
                   3843:                            IXGBE_RXDCTL_ENABLE)
                   3844:                                break;
                   3845:                        else
                   3846:                                msec_delay(1);
1.55      msaitoh  3847:                }
1.98      msaitoh  3848:                wmb();
1.99      msaitoh  3849:
1.98      msaitoh  3850:                /*
                   3851:                 * In netmap mode, we must preserve the buffers made
                   3852:                 * available to userspace before the if_init()
                   3853:                 * (this is true by default on the TX side, because
                   3854:                 * init makes all buffers available to userspace).
                   3855:                 *
                   3856:                 * netmap_reset() and the device specific routines
                   3857:                 * (e.g. ixgbe_setup_receive_rings()) map these
                   3858:                 * buffers at the end of the NIC ring, so here we
                   3859:                 * must set the RDT (tail) register to make sure
                   3860:                 * they are not overwritten.
                   3861:                 *
                   3862:                 * In this driver the NIC ring starts at RDH = 0,
                   3863:                 * RDT points to the last slot available for reception (?),
                   3864:                 * so RDT = num_rx_desc - 1 means the whole ring is available.
                   3865:                 */
1.99      msaitoh  3866: #ifdef DEV_NETMAP
                   3867:                if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) &&
                   3868:                    (ifp->if_capenable & IFCAP_NETMAP)) {
1.98      msaitoh  3869:                        struct netmap_adapter *na = NA(adapter->ifp);
                   3870:                        struct netmap_kring *kring = &na->rx_rings[i];
                   3871:                        int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
                   3872:
                   3873:                        IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), t);
                   3874:                } else
                   3875: #endif /* DEV_NETMAP */
1.99      msaitoh  3876:                        IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me),
                   3877:                            adapter->num_rx_desc - 1);
1.48      msaitoh  3878:        }
1.98      msaitoh  3879:
                   3880:        /* Enable Receive engine */
                   3881:        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
                   3882:        if (hw->mac.type == ixgbe_mac_82598EB)
                   3883:                rxctrl |= IXGBE_RXCTRL_DMBYPS;
                   3884:        rxctrl |= IXGBE_RXCTRL_RXEN;
                   3885:        ixgbe_enable_rx_dma(hw, rxctrl);
                   3886:
                   3887:        callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
                   3888:
1.144     msaitoh  3889:        /* Set up MSI/MSI-X routing */
1.99      msaitoh  3890:        if (adapter->feat_en & IXGBE_FEATURE_MSIX) {
1.98      msaitoh  3891:                ixgbe_configure_ivars(adapter);
                   3892:                /* Set up auto-mask */
                   3893:                if (hw->mac.type == ixgbe_mac_82598EB)
                   3894:                        IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
                   3895:                else {
                   3896:                        IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF);
                   3897:                        IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF);
1.55      msaitoh  3898:                }
1.98      msaitoh  3899:        } else {  /* Simple settings for Legacy/MSI */
                   3900:                ixgbe_set_ivar(adapter, 0, 0, 0);
                   3901:                ixgbe_set_ivar(adapter, 0, 0, 1);
                   3902:                IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
1.55      msaitoh  3903:        }
1.43      msaitoh  3904:
1.99      msaitoh  3905:        ixgbe_init_fdir(adapter);
1.98      msaitoh  3906:
                   3907:        /*
                   3908:         * Check on any SFP devices that
                   3909:         * need to be kick-started
                   3910:         */
                   3911:        if (hw->phy.type == ixgbe_phy_none) {
                   3912:                err = hw->phy.ops.identify(hw);
                   3913:                if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                   3914:                        device_printf(dev,
                   3915:                            "Unsupported SFP+ module type was detected.\n");
                   3916:                        return;
                   3917:                }
1.43      msaitoh  3918:        }
1.98      msaitoh  3919:
                   3920:        /* Set moderation on the Link interrupt */
1.149   ! msaitoh  3921:        ixgbe_eitr_write(adapter, adapter->vector, IXGBE_LINK_ITR);
1.98      msaitoh  3922:
1.144     msaitoh  3923:        /* Enable power to the phy. */
                   3924:        ixgbe_set_phy_power(hw, TRUE);
                   3925:
1.98      msaitoh  3926:        /* Config/Enable Link */
                   3927:        ixgbe_config_link(adapter);
1.55      msaitoh  3928:
1.98      msaitoh  3929:        /* Hardware Packet Buffer & Flow Control setup */
                   3930:        ixgbe_config_delay_values(adapter);
1.1       dyoung   3931:
1.98      msaitoh  3932:        /* Initialize the FC settings */
                   3933:        ixgbe_start_hw(hw);
1.1       dyoung   3934:
1.98      msaitoh  3935:        /* Set up VLAN support and filter */
                   3936:        ixgbe_setup_vlan_hw_support(adapter);
1.1       dyoung   3937:
1.98      msaitoh  3938:        /* Setup DMA Coalescing */
                   3939:        ixgbe_config_dmac(adapter);
                   3940:
                   3941:        /* And now turn on interrupts */
                   3942:        ixgbe_enable_intr(adapter);
                   3943:
                   3944:        /* Enable the use of the MBX by the VF's */
1.99      msaitoh  3945:        if (adapter->feat_en & IXGBE_FEATURE_SRIOV) {
                   3946:                ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
                   3947:                ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
                   3948:                IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
1.1       dyoung   3949:        }
1.98      msaitoh  3950:
1.123     msaitoh  3951:        /* Update saved flags. See ixgbe_ifflags_cb() */
                   3952:        adapter->if_flags = ifp->if_flags;
                   3953:
1.98      msaitoh  3954:        /* Now inform the stack we're ready */
                   3955:        ifp->if_flags |= IFF_RUNNING;
                   3956:
1.1       dyoung   3957:        return;
1.99      msaitoh  3958: } /* ixgbe_init_locked */
1.1       dyoung   3959:
1.99      msaitoh  3960: /************************************************************************
                   3961:  * ixgbe_init
                   3962:  ************************************************************************/
1.98      msaitoh  3963: static int
                   3964: ixgbe_init(struct ifnet *ifp)
                   3965: {
                   3966:        struct adapter *adapter = ifp->if_softc;
                   3967:
                   3968:        IXGBE_CORE_LOCK(adapter);
                   3969:        ixgbe_init_locked(adapter);
                   3970:        IXGBE_CORE_UNLOCK(adapter);
                   3971:
                   3972:        return 0;       /* XXX ixgbe_init_locked cannot fail?  really? */
1.99      msaitoh  3973: } /* ixgbe_init */
1.43      msaitoh  3974:
1.99      msaitoh  3975: /************************************************************************
                   3976:  * ixgbe_set_ivar
                   3977:  *
                   3978:  *   Setup the correct IVAR register for a particular MSI-X interrupt
                   3979:  *     (yes this is all very magic and confusing :)
                   3980:  *    - entry is the register array entry
                   3981:  *    - vector is the MSI-X vector for this queue
                   3982:  *    - type is RX/TX/MISC
                   3983:  ************************************************************************/
1.42      msaitoh  3984: static void
1.98      msaitoh  3985: ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
1.1       dyoung   3986: {
1.98      msaitoh  3987:        struct ixgbe_hw *hw = &adapter->hw;
                   3988:        u32 ivar, index;
                   3989:
                   3990:        vector |= IXGBE_IVAR_ALLOC_VAL;
                   3991:
                   3992:        switch (hw->mac.type) {
                   3993:        case ixgbe_mac_82598EB:
                   3994:                if (type == -1)
                   3995:                        entry = IXGBE_IVAR_OTHER_CAUSES_INDEX;
                   3996:                else
                   3997:                        entry += (type * 64);
                   3998:                index = (entry >> 2) & 0x1F;
                   3999:                ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
                   4000:                ivar &= ~(0xFF << (8 * (entry & 0x3)));
                   4001:                ivar |= (vector << (8 * (entry & 0x3)));
                   4002:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar);
                   4003:                break;
                   4004:        case ixgbe_mac_82599EB:
                   4005:        case ixgbe_mac_X540:
                   4006:        case ixgbe_mac_X550:
                   4007:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  4008:        case ixgbe_mac_X550EM_a:
1.98      msaitoh  4009:                if (type == -1) { /* MISC IVAR */
                   4010:                        index = (entry & 1) * 8;
                   4011:                        ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC);
                   4012:                        ivar &= ~(0xFF << index);
                   4013:                        ivar |= (vector << index);
                   4014:                        IXGBE_WRITE_REG(hw, IXGBE_IVAR_MISC, ivar);
                   4015:                } else {        /* RX/TX IVARS */
                   4016:                        index = (16 * (entry & 1)) + (8 * type);
                   4017:                        ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(entry >> 1));
                   4018:                        ivar &= ~(0xFF << index);
                   4019:                        ivar |= (vector << index);
                   4020:                        IXGBE_WRITE_REG(hw, IXGBE_IVAR(entry >> 1), ivar);
                   4021:                }
1.135     msaitoh  4022:                break;
1.98      msaitoh  4023:        default:
                   4024:                break;
                   4025:        }
1.99      msaitoh  4026: } /* ixgbe_set_ivar */
1.1       dyoung   4027:
1.99      msaitoh  4028: /************************************************************************
                   4029:  * ixgbe_configure_ivars
                   4030:  ************************************************************************/
1.98      msaitoh  4031: static void
                   4032: ixgbe_configure_ivars(struct adapter *adapter)
                   4033: {
1.99      msaitoh  4034:        struct ix_queue *que = adapter->queues;
                   4035:        u32             newitr;
1.1       dyoung   4036:
1.98      msaitoh  4037:        if (ixgbe_max_interrupt_rate > 0)
                   4038:                newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
                   4039:        else {
1.48      msaitoh  4040:                /*
1.99      msaitoh  4041:                 * Disable DMA coalescing if interrupt moderation is
                   4042:                 * disabled.
                   4043:                 */
1.98      msaitoh  4044:                adapter->dmac = 0;
                   4045:                newitr = 0;
                   4046:        }
                   4047:
                   4048:         for (int i = 0; i < adapter->num_queues; i++, que++) {
                   4049:                struct rx_ring *rxr = &adapter->rx_rings[i];
                   4050:                struct tx_ring *txr = &adapter->tx_rings[i];
                   4051:                /* First the RX queue entry */
                   4052:                 ixgbe_set_ivar(adapter, rxr->me, que->msix, 0);
                   4053:                /* ... and the TX */
                   4054:                ixgbe_set_ivar(adapter, txr->me, que->msix, 1);
                   4055:                /* Set an Initial EITR value */
1.149   ! msaitoh  4056:                ixgbe_eitr_write(adapter, que->msix, newitr);
1.138     knakahar 4057:                /*
                   4058:                 * To eliminate influence of the previous state.
                   4059:                 * At this point, Tx/Rx interrupt handler
                   4060:                 * (ixgbe_msix_que()) cannot be called, so  both
                   4061:                 * IXGBE_TX_LOCK and IXGBE_RX_LOCK are not required.
                   4062:                 */
                   4063:                que->eitr_setting = 0;
1.98      msaitoh  4064:        }
                   4065:
                   4066:        /* For the Link interrupt */
                   4067:         ixgbe_set_ivar(adapter, 1, adapter->vector, -1);
1.99      msaitoh  4068: } /* ixgbe_configure_ivars */
1.98      msaitoh  4069:
1.99      msaitoh  4070: /************************************************************************
                   4071:  * ixgbe_config_gpie
                   4072:  ************************************************************************/
1.98      msaitoh  4073: static void
                   4074: ixgbe_config_gpie(struct adapter *adapter)
                   4075: {
                   4076:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  4077:        u32             gpie;
1.98      msaitoh  4078:
                   4079:        gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
                   4080:
1.99      msaitoh  4081:        if (adapter->feat_en & IXGBE_FEATURE_MSIX) {
                   4082:                /* Enable Enhanced MSI-X mode */
                   4083:                gpie |= IXGBE_GPIE_MSIX_MODE
                   4084:                     |  IXGBE_GPIE_EIAME
                   4085:                     |  IXGBE_GPIE_PBA_SUPPORT
                   4086:                     |  IXGBE_GPIE_OCD;
                   4087:        }
                   4088:
1.98      msaitoh  4089:        /* Fan Failure Interrupt */
1.99      msaitoh  4090:        if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL)
1.98      msaitoh  4091:                gpie |= IXGBE_SDP1_GPIEN;
1.1       dyoung   4092:
1.99      msaitoh  4093:        /* Thermal Sensor Interrupt */
                   4094:        if (adapter->feat_en & IXGBE_FEATURE_TEMP_SENSOR)
                   4095:                gpie |= IXGBE_SDP0_GPIEN_X540;
1.1       dyoung   4096:
1.99      msaitoh  4097:        /* Link detection */
                   4098:        switch (hw->mac.type) {
                   4099:        case ixgbe_mac_82599EB:
                   4100:                gpie |= IXGBE_SDP1_GPIEN | IXGBE_SDP2_GPIEN;
                   4101:                break;
                   4102:        case ixgbe_mac_X550EM_x:
                   4103:        case ixgbe_mac_X550EM_a:
1.98      msaitoh  4104:                gpie |= IXGBE_SDP0_GPIEN_X540;
1.99      msaitoh  4105:                break;
                   4106:        default:
                   4107:                break;
1.1       dyoung   4108:        }
                   4109:
1.98      msaitoh  4110:        IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
                   4111:
1.99      msaitoh  4112: } /* ixgbe_config_gpie */
1.1       dyoung   4113:
1.99      msaitoh  4114: /************************************************************************
                   4115:  * ixgbe_config_delay_values
                   4116:  *
                   4117:  *   Requires adapter->max_frame_size to be set.
                   4118:  ************************************************************************/
1.33      msaitoh  4119: static void
1.98      msaitoh  4120: ixgbe_config_delay_values(struct adapter *adapter)
1.33      msaitoh  4121: {
1.98      msaitoh  4122:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  4123:        u32             rxpb, frame, size, tmp;
1.33      msaitoh  4124:
1.98      msaitoh  4125:        frame = adapter->max_frame_size;
1.33      msaitoh  4126:
1.98      msaitoh  4127:        /* Calculate High Water */
                   4128:        switch (hw->mac.type) {
                   4129:        case ixgbe_mac_X540:
1.44      msaitoh  4130:        case ixgbe_mac_X550:
                   4131:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  4132:        case ixgbe_mac_X550EM_a:
1.98      msaitoh  4133:                tmp = IXGBE_DV_X540(frame, frame);
1.44      msaitoh  4134:                break;
                   4135:        default:
1.98      msaitoh  4136:                tmp = IXGBE_DV(frame, frame);
1.44      msaitoh  4137:                break;
                   4138:        }
1.98      msaitoh  4139:        size = IXGBE_BT2KB(tmp);
                   4140:        rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
                   4141:        hw->fc.high_water[0] = rxpb - size;
1.44      msaitoh  4142:
1.98      msaitoh  4143:        /* Now calculate Low Water */
                   4144:        switch (hw->mac.type) {
                   4145:        case ixgbe_mac_X540:
                   4146:        case ixgbe_mac_X550:
                   4147:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  4148:        case ixgbe_mac_X550EM_a:
1.98      msaitoh  4149:                tmp = IXGBE_LOW_DV_X540(frame);
                   4150:                break;
                   4151:        default:
                   4152:                tmp = IXGBE_LOW_DV(frame);
                   4153:                break;
1.33      msaitoh  4154:        }
1.98      msaitoh  4155:        hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
1.33      msaitoh  4156:
1.98      msaitoh  4157:        hw->fc.pause_time = IXGBE_FC_PAUSE;
                   4158:        hw->fc.send_xon = TRUE;
1.99      msaitoh  4159: } /* ixgbe_config_delay_values */
1.33      msaitoh  4160:
1.99      msaitoh  4161: /************************************************************************
                   4162:  * ixgbe_set_multi - Multicast Update
1.1       dyoung   4163:  *
1.99      msaitoh  4164:  *   Called whenever multicast address list is updated.
                   4165:  ************************************************************************/
1.1       dyoung   4166: static void
1.98      msaitoh  4167: ixgbe_set_multi(struct adapter *adapter)
1.1       dyoung   4168: {
1.99      msaitoh  4169:        struct ixgbe_mc_addr    *mta;
                   4170:        struct ifnet            *ifp = adapter->ifp;
1.98      msaitoh  4171:        u8                      *update_ptr;
                   4172:        int                     mcnt = 0;
1.99      msaitoh  4173:        u32                     fctrl;
1.98      msaitoh  4174:        struct ethercom         *ec = &adapter->osdep.ec;
                   4175:        struct ether_multi      *enm;
                   4176:        struct ether_multistep  step;
                   4177:
1.105     msaitoh  4178:        KASSERT(mutex_owned(&adapter->core_mtx));
1.98      msaitoh  4179:        IOCTL_DEBUGOUT("ixgbe_set_multi: begin");
                   4180:
                   4181:        mta = adapter->mta;
                   4182:        bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES);
1.1       dyoung   4183:
1.98      msaitoh  4184:        ifp->if_flags &= ~IFF_ALLMULTI;
1.105     msaitoh  4185:        ETHER_LOCK(ec);
1.98      msaitoh  4186:        ETHER_FIRST_MULTI(step, ec, enm);
                   4187:        while (enm != NULL) {
                   4188:                if ((mcnt == MAX_NUM_MULTICAST_ADDRESSES) ||
                   4189:                    (memcmp(enm->enm_addrlo, enm->enm_addrhi,
                   4190:                        ETHER_ADDR_LEN) != 0)) {
                   4191:                        ifp->if_flags |= IFF_ALLMULTI;
                   4192:                        break;
                   4193:                }
                   4194:                bcopy(enm->enm_addrlo,
                   4195:                    mta[mcnt].addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
                   4196:                mta[mcnt].vmdq = adapter->pool;
                   4197:                mcnt++;
                   4198:                ETHER_NEXT_MULTI(step, enm);
                   4199:        }
1.105     msaitoh  4200:        ETHER_UNLOCK(ec);
1.1       dyoung   4201:
1.98      msaitoh  4202:        fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
                   4203:        fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
                   4204:        if (ifp->if_flags & IFF_PROMISC)
                   4205:                fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
                   4206:        else if (ifp->if_flags & IFF_ALLMULTI) {
                   4207:                fctrl |= IXGBE_FCTRL_MPE;
1.44      msaitoh  4208:        }
1.1       dyoung   4209:
1.98      msaitoh  4210:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
1.1       dyoung   4211:
1.98      msaitoh  4212:        if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) {
                   4213:                update_ptr = (u8 *)mta;
1.99      msaitoh  4214:                ixgbe_update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
                   4215:                    ixgbe_mc_array_itr, TRUE);
1.98      msaitoh  4216:        }
1.1       dyoung   4217:
1.99      msaitoh  4218: } /* ixgbe_set_multi */
1.1       dyoung   4219:
1.99      msaitoh  4220: /************************************************************************
                   4221:  * ixgbe_mc_array_itr
                   4222:  *
                   4223:  *   An iterator function needed by the multicast shared code.
                   4224:  *   It feeds the shared code routine the addresses in the
                   4225:  *   array of ixgbe_set_multi() one by one.
                   4226:  ************************************************************************/
1.98      msaitoh  4227: static u8 *
                   4228: ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
                   4229: {
                   4230:        struct ixgbe_mc_addr *mta;
1.1       dyoung   4231:
1.98      msaitoh  4232:        mta = (struct ixgbe_mc_addr *)*update_ptr;
                   4233:        *vmdq = mta->vmdq;
1.33      msaitoh  4234:
1.98      msaitoh  4235:        *update_ptr = (u8*)(mta + 1);
1.99      msaitoh  4236:
1.98      msaitoh  4237:        return (mta->addr);
1.99      msaitoh  4238: } /* ixgbe_mc_array_itr */
1.82      msaitoh  4239:
1.99      msaitoh  4240: /************************************************************************
                   4241:  * ixgbe_local_timer - Timer routine
1.98      msaitoh  4242:  *
1.99      msaitoh  4243:  *   Checks for link status, updates statistics,
                   4244:  *   and runs the watchdog check.
                   4245:  ************************************************************************/
1.98      msaitoh  4246: static void
                   4247: ixgbe_local_timer(void *arg)
                   4248: {
                   4249:        struct adapter *adapter = arg;
1.1       dyoung   4250:
1.98      msaitoh  4251:        IXGBE_CORE_LOCK(adapter);
                   4252:        ixgbe_local_timer1(adapter);
                   4253:        IXGBE_CORE_UNLOCK(adapter);
                   4254: }
1.28      msaitoh  4255:
1.98      msaitoh  4256: static void
                   4257: ixgbe_local_timer1(void *arg)
                   4258: {
                   4259:        struct adapter  *adapter = arg;
                   4260:        device_t        dev = adapter->dev;
                   4261:        struct ix_queue *que = adapter->queues;
                   4262:        u64             queues = 0;
1.134     msaitoh  4263:        u64             v0, v1, v2, v3, v4, v5, v6, v7;
1.98      msaitoh  4264:        int             hung = 0;
1.134     msaitoh  4265:        int             i;
1.1       dyoung   4266:
1.98      msaitoh  4267:        KASSERT(mutex_owned(&adapter->core_mtx));
1.1       dyoung   4268:
1.98      msaitoh  4269:        /* Check for pluggable optics */
                   4270:        if (adapter->sfp_probe)
                   4271:                if (!ixgbe_sfp_probe(adapter))
                   4272:                        goto out; /* Nothing to do */
1.1       dyoung   4273:
1.98      msaitoh  4274:        ixgbe_update_link_status(adapter);
                   4275:        ixgbe_update_stats_counters(adapter);
1.33      msaitoh  4276:
1.134     msaitoh  4277:        /* Update some event counters */
                   4278:        v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = 0;
                   4279:        que = adapter->queues;
                   4280:        for (i = 0; i < adapter->num_queues; i++, que++) {
                   4281:                struct tx_ring  *txr = que->txr;
                   4282:
                   4283:                v0 += txr->q_efbig_tx_dma_setup;
                   4284:                v1 += txr->q_mbuf_defrag_failed;
                   4285:                v2 += txr->q_efbig2_tx_dma_setup;
                   4286:                v3 += txr->q_einval_tx_dma_setup;
                   4287:                v4 += txr->q_other_tx_dma_setup;
                   4288:                v5 += txr->q_eagain_tx_dma_setup;
                   4289:                v6 += txr->q_enomem_tx_dma_setup;
                   4290:                v7 += txr->q_tso_err;
                   4291:        }
                   4292:        adapter->efbig_tx_dma_setup.ev_count = v0;
                   4293:        adapter->mbuf_defrag_failed.ev_count = v1;
                   4294:        adapter->efbig2_tx_dma_setup.ev_count = v2;
                   4295:        adapter->einval_tx_dma_setup.ev_count = v3;
                   4296:        adapter->other_tx_dma_setup.ev_count = v4;
                   4297:        adapter->eagain_tx_dma_setup.ev_count = v5;
                   4298:        adapter->enomem_tx_dma_setup.ev_count = v6;
                   4299:        adapter->tso_err.ev_count = v7;
                   4300:
1.98      msaitoh  4301:        /*
1.99      msaitoh  4302:         * Check the TX queues status
                   4303:         *      - mark hung queues so we don't schedule on them
                   4304:         *      - watchdog only if all queues show hung
                   4305:         */
1.134     msaitoh  4306:        que = adapter->queues;
                   4307:        for (i = 0; i < adapter->num_queues; i++, que++) {
1.98      msaitoh  4308:                /* Keep track of queues with work for soft irq */
                   4309:                if (que->txr->busy)
                   4310:                        queues |= ((u64)1 << que->me);
                   4311:                /*
1.99      msaitoh  4312:                 * Each time txeof runs without cleaning, but there
                   4313:                 * are uncleaned descriptors it increments busy. If
                   4314:                 * we get to the MAX we declare it hung.
                   4315:                 */
1.98      msaitoh  4316:                if (que->busy == IXGBE_QUEUE_HUNG) {
                   4317:                        ++hung;
                   4318:                        /* Mark the queue as inactive */
                   4319:                        adapter->active_queues &= ~((u64)1 << que->me);
                   4320:                        continue;
                   4321:                } else {
                   4322:                        /* Check if we've come back from hung */
                   4323:                        if ((adapter->active_queues & ((u64)1 << que->me)) == 0)
                   4324:                                adapter->active_queues |= ((u64)1 << que->me);
                   4325:                }
                   4326:                if (que->busy >= IXGBE_MAX_TX_BUSY) {
1.99      msaitoh  4327:                        device_printf(dev,
                   4328:                            "Warning queue %d appears to be hung!\n", i);
1.98      msaitoh  4329:                        que->txr->busy = IXGBE_QUEUE_HUNG;
                   4330:                        ++hung;
                   4331:                }
1.1       dyoung   4332:        }
                   4333:
1.98      msaitoh  4334:        /* Only truely watchdog if all queues show hung */
                   4335:        if (hung == adapter->num_queues)
                   4336:                goto watchdog;
                   4337:        else if (queues != 0) { /* Force an IRQ on queues with work */
1.131     knakahar 4338:                que = adapter->queues;
1.134     msaitoh  4339:                for (i = 0; i < adapter->num_queues; i++, que++) {
1.139     knakahar 4340:                        mutex_enter(&que->dc_mtx);
                   4341:                        if (que->disabled_count == 0)
1.131     knakahar 4342:                                ixgbe_rearm_queues(adapter,
                   4343:                                    queues & ((u64)1 << i));
1.139     knakahar 4344:                        mutex_exit(&que->dc_mtx);
1.131     knakahar 4345:                }
1.98      msaitoh  4346:        }
1.1       dyoung   4347:
1.98      msaitoh  4348: out:
                   4349:        callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
                   4350:        return;
1.1       dyoung   4351:
1.98      msaitoh  4352: watchdog:
                   4353:        device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
                   4354:        adapter->ifp->if_flags &= ~IFF_RUNNING;
                   4355:        adapter->watchdog_events.ev_count++;
                   4356:        ixgbe_init_locked(adapter);
1.99      msaitoh  4357: } /* ixgbe_local_timer */
1.43      msaitoh  4358:
1.99      msaitoh  4359: /************************************************************************
                   4360:  * ixgbe_sfp_probe
1.98      msaitoh  4361:  *
1.99      msaitoh  4362:  *   Determine if a port had optics inserted.
                   4363:  ************************************************************************/
1.98      msaitoh  4364: static bool
                   4365: ixgbe_sfp_probe(struct adapter *adapter)
                   4366: {
                   4367:        struct ixgbe_hw *hw = &adapter->hw;
                   4368:        device_t        dev = adapter->dev;
                   4369:        bool            result = FALSE;
1.1       dyoung   4370:
1.98      msaitoh  4371:        if ((hw->phy.type == ixgbe_phy_nl) &&
                   4372:            (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
                   4373:                s32 ret = hw->phy.ops.identify_sfp(hw);
                   4374:                if (ret)
                   4375:                        goto out;
                   4376:                ret = hw->phy.ops.reset(hw);
1.99      msaitoh  4377:                adapter->sfp_probe = FALSE;
1.98      msaitoh  4378:                if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                   4379:                        device_printf(dev,"Unsupported SFP+ module detected!");
1.99      msaitoh  4380:                        device_printf(dev,
                   4381:                            "Reload driver with supported module.\n");
1.98      msaitoh  4382:                         goto out;
                   4383:                } else
                   4384:                        device_printf(dev, "SFP+ module detected!\n");
                   4385:                /* We now have supported optics */
                   4386:                result = TRUE;
                   4387:        }
                   4388: out:
1.99      msaitoh  4389:
1.98      msaitoh  4390:        return (result);
1.99      msaitoh  4391: } /* ixgbe_sfp_probe */
1.1       dyoung   4392:
1.99      msaitoh  4393: /************************************************************************
                   4394:  * ixgbe_handle_mod - Tasklet for SFP module interrupts
                   4395:  ************************************************************************/
1.1       dyoung   4396: static void
1.98      msaitoh  4397: ixgbe_handle_mod(void *context)
1.1       dyoung   4398: {
1.98      msaitoh  4399:        struct adapter  *adapter = context;
1.1       dyoung   4400:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  4401:        device_t        dev = adapter->dev;
1.99      msaitoh  4402:        u32             err, cage_full = 0;
1.98      msaitoh  4403:
1.137     msaitoh  4404:        ++adapter->mod_sicount.ev_count;
1.99      msaitoh  4405:        if (adapter->hw.need_crosstalk_fix) {
                   4406:                switch (hw->mac.type) {
                   4407:                case ixgbe_mac_82599EB:
                   4408:                        cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
                   4409:                            IXGBE_ESDP_SDP2;
                   4410:                        break;
                   4411:                case ixgbe_mac_X550EM_x:
                   4412:                case ixgbe_mac_X550EM_a:
                   4413:                        cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
                   4414:                            IXGBE_ESDP_SDP0;
                   4415:                        break;
                   4416:                default:
                   4417:                        break;
1.33      msaitoh  4418:                }
1.98      msaitoh  4419:
1.99      msaitoh  4420:                if (!cage_full)
                   4421:                        return;
1.98      msaitoh  4422:        }
                   4423:
                   4424:        err = hw->phy.ops.identify_sfp(hw);
                   4425:        if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                   4426:                device_printf(dev,
                   4427:                    "Unsupported SFP+ module type was detected.\n");
1.99      msaitoh  4428:                return;
1.33      msaitoh  4429:        }
                   4430:
1.142     msaitoh  4431:        if (hw->mac.type == ixgbe_mac_82598EB)
                   4432:                err = hw->phy.ops.reset(hw);
                   4433:        else
                   4434:                err = hw->mac.ops.setup_sfp(hw);
                   4435:
1.98      msaitoh  4436:        if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                   4437:                device_printf(dev,
                   4438:                    "Setup failure - unsupported SFP+ module type.\n");
1.99      msaitoh  4439:                return;
1.1       dyoung   4440:        }
1.98      msaitoh  4441:        softint_schedule(adapter->msf_si);
1.99      msaitoh  4442: } /* ixgbe_handle_mod */
1.1       dyoung   4443:
                   4444:
1.99      msaitoh  4445: /************************************************************************
                   4446:  * ixgbe_handle_msf - Tasklet for MSF (multispeed fiber) interrupts
                   4447:  ************************************************************************/
1.33      msaitoh  4448: static void
1.98      msaitoh  4449: ixgbe_handle_msf(void *context)
1.33      msaitoh  4450: {
1.98      msaitoh  4451:        struct adapter  *adapter = context;
                   4452:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  4453:        u32             autoneg;
                   4454:        bool            negotiate;
1.33      msaitoh  4455:
1.137     msaitoh  4456:        ++adapter->msf_sicount.ev_count;
1.99      msaitoh  4457:        /* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */
                   4458:        adapter->phy_layer = ixgbe_get_supported_physical_layer(hw);
1.33      msaitoh  4459:
1.98      msaitoh  4460:        autoneg = hw->phy.autoneg_advertised;
                   4461:        if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
                   4462:                hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate);
                   4463:        else
                   4464:                negotiate = 0;
                   4465:        if (hw->mac.ops.setup_link)
                   4466:                hw->mac.ops.setup_link(hw, autoneg, TRUE);
1.33      msaitoh  4467:
1.99      msaitoh  4468:        /* Adjust media types shown in ifconfig */
                   4469:        ifmedia_removeall(&adapter->media);
                   4470:        ixgbe_add_media_types(adapter);
                   4471:        ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
                   4472: } /* ixgbe_handle_msf */
1.33      msaitoh  4473:
1.99      msaitoh  4474: /************************************************************************
                   4475:  * ixgbe_handle_phy - Tasklet for external PHY interrupts
                   4476:  ************************************************************************/
1.1       dyoung   4477: static void
1.98      msaitoh  4478: ixgbe_handle_phy(void *context)
1.1       dyoung   4479: {
1.98      msaitoh  4480:        struct adapter  *adapter = context;
1.1       dyoung   4481:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  4482:        int error;
1.1       dyoung   4483:
1.137     msaitoh  4484:        ++adapter->phy_sicount.ev_count;
1.98      msaitoh  4485:        error = hw->phy.ops.handle_lasi(hw);
                   4486:        if (error == IXGBE_ERR_OVERTEMP)
                   4487:                device_printf(adapter->dev,
                   4488:                    "CRITICAL: EXTERNAL PHY OVER TEMP!! "
                   4489:                    " PHY will downshift to lower power state!\n");
                   4490:        else if (error)
                   4491:                device_printf(adapter->dev,
1.99      msaitoh  4492:                    "Error handling LASI interrupt: %d\n", error);
                   4493: } /* ixgbe_handle_phy */
1.1       dyoung   4494:
1.98      msaitoh  4495: static void
                   4496: ixgbe_ifstop(struct ifnet *ifp, int disable)
                   4497: {
                   4498:        struct adapter *adapter = ifp->if_softc;
1.1       dyoung   4499:
1.98      msaitoh  4500:        IXGBE_CORE_LOCK(adapter);
                   4501:        ixgbe_stop(adapter);
                   4502:        IXGBE_CORE_UNLOCK(adapter);
                   4503: }
1.1       dyoung   4504:
1.99      msaitoh  4505: /************************************************************************
                   4506:  * ixgbe_stop - Stop the hardware
1.98      msaitoh  4507:  *
1.99      msaitoh  4508:  *   Disables all traffic on the adapter by issuing a
                   4509:  *   global reset on the MAC and deallocates TX/RX buffers.
                   4510:  ************************************************************************/
1.1       dyoung   4511: static void
1.98      msaitoh  4512: ixgbe_stop(void *arg)
1.1       dyoung   4513: {
1.99      msaitoh  4514:        struct ifnet    *ifp;
                   4515:        struct adapter  *adapter = arg;
1.98      msaitoh  4516:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  4517:
1.98      msaitoh  4518:        ifp = adapter->ifp;
                   4519:
                   4520:        KASSERT(mutex_owned(&adapter->core_mtx));
                   4521:
                   4522:        INIT_DEBUGOUT("ixgbe_stop: begin\n");
                   4523:        ixgbe_disable_intr(adapter);
                   4524:        callout_stop(&adapter->timer);
                   4525:
                   4526:        /* Let the stack know...*/
                   4527:        ifp->if_flags &= ~IFF_RUNNING;
                   4528:
                   4529:        ixgbe_reset_hw(hw);
                   4530:        hw->adapter_stopped = FALSE;
                   4531:        ixgbe_stop_adapter(hw);
                   4532:        if (hw->mac.type == ixgbe_mac_82599EB)
                   4533:                ixgbe_stop_mac_link_on_d3_82599(hw);
                   4534:        /* Turn off the laser - noop with no optics */
                   4535:        ixgbe_disable_tx_laser(hw);
1.1       dyoung   4536:
1.98      msaitoh  4537:        /* Update the stack */
                   4538:        adapter->link_up = FALSE;
                   4539:        ixgbe_update_link_status(adapter);
1.1       dyoung   4540:
1.98      msaitoh  4541:        /* reprogram the RAR[0] in case user changed it. */
                   4542:        ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
1.1       dyoung   4543:
1.98      msaitoh  4544:        return;
1.99      msaitoh  4545: } /* ixgbe_stop */
1.1       dyoung   4546:
1.99      msaitoh  4547: /************************************************************************
                   4548:  * ixgbe_update_link_status - Update OS on link state
                   4549:  *
                   4550:  * Note: Only updates the OS on the cached link state.
                   4551:  *       The real check of the hardware only happens with
                   4552:  *       a link interrupt.
                   4553:  ************************************************************************/
1.98      msaitoh  4554: static void
                   4555: ixgbe_update_link_status(struct adapter *adapter)
1.1       dyoung   4556: {
1.98      msaitoh  4557:        struct ifnet    *ifp = adapter->ifp;
1.99      msaitoh  4558:        device_t        dev = adapter->dev;
1.98      msaitoh  4559:        struct ixgbe_hw *hw = &adapter->hw;
                   4560:
1.136     knakahar 4561:        KASSERT(mutex_owned(&adapter->core_mtx));
                   4562:
1.98      msaitoh  4563:        if (adapter->link_up) {
                   4564:                if (adapter->link_active == FALSE) {
1.138     knakahar 4565:                        /*
                   4566:                         * To eliminate influence of the previous state
                   4567:                         * in the same way as ixgbe_init_locked().
                   4568:                         */
                   4569:                        struct ix_queue *que = adapter->queues;
                   4570:                        for (int i = 0; i < adapter->num_queues; i++, que++)
                   4571:                                que->eitr_setting = 0;
                   4572:
1.98      msaitoh  4573:                        if (adapter->link_speed == IXGBE_LINK_SPEED_10GB_FULL){
                   4574:                                /*
                   4575:                                 *  Discard count for both MAC Local Fault and
                   4576:                                 * Remote Fault because those registers are
                   4577:                                 * valid only when the link speed is up and
                   4578:                                 * 10Gbps.
                   4579:                                 */
                   4580:                                IXGBE_READ_REG(hw, IXGBE_MLFC);
                   4581:                                IXGBE_READ_REG(hw, IXGBE_MRFC);
                   4582:                        }
                   4583:
                   4584:                        if (bootverbose) {
                   4585:                                const char *bpsmsg;
1.1       dyoung   4586:
1.98      msaitoh  4587:                                switch (adapter->link_speed) {
                   4588:                                case IXGBE_LINK_SPEED_10GB_FULL:
                   4589:                                        bpsmsg = "10 Gbps";
                   4590:                                        break;
                   4591:                                case IXGBE_LINK_SPEED_5GB_FULL:
                   4592:                                        bpsmsg = "5 Gbps";
                   4593:                                        break;
                   4594:                                case IXGBE_LINK_SPEED_2_5GB_FULL:
                   4595:                                        bpsmsg = "2.5 Gbps";
                   4596:                                        break;
                   4597:                                case IXGBE_LINK_SPEED_1GB_FULL:
                   4598:                                        bpsmsg = "1 Gbps";
                   4599:                                        break;
                   4600:                                case IXGBE_LINK_SPEED_100_FULL:
                   4601:                                        bpsmsg = "100 Mbps";
                   4602:                                        break;
1.99      msaitoh  4603:                                case IXGBE_LINK_SPEED_10_FULL:
                   4604:                                        bpsmsg = "10 Mbps";
                   4605:                                        break;
1.98      msaitoh  4606:                                default:
                   4607:                                        bpsmsg = "unknown speed";
                   4608:                                        break;
                   4609:                                }
                   4610:                                device_printf(dev, "Link is up %s %s \n",
                   4611:                                    bpsmsg, "Full Duplex");
                   4612:                        }
                   4613:                        adapter->link_active = TRUE;
                   4614:                        /* Update any Flow Control changes */
                   4615:                        ixgbe_fc_enable(&adapter->hw);
                   4616:                        /* Update DMA coalescing config */
                   4617:                        ixgbe_config_dmac(adapter);
                   4618:                        if_link_state_change(ifp, LINK_STATE_UP);
1.144     msaitoh  4619:
1.99      msaitoh  4620:                        if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
                   4621:                                ixgbe_ping_all_vfs(adapter);
1.98      msaitoh  4622:                }
                   4623:        } else { /* Link down */
                   4624:                if (adapter->link_active == TRUE) {
                   4625:                        if (bootverbose)
                   4626:                                device_printf(dev, "Link is Down\n");
                   4627:                        if_link_state_change(ifp, LINK_STATE_DOWN);
                   4628:                        adapter->link_active = FALSE;
1.99      msaitoh  4629:                        if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
                   4630:                                ixgbe_ping_all_vfs(adapter);
1.141     knakahar 4631:                        ixgbe_drain_all(adapter);
1.98      msaitoh  4632:                }
1.1       dyoung   4633:        }
1.99      msaitoh  4634: } /* ixgbe_update_link_status */
1.1       dyoung   4635:
1.99      msaitoh  4636: /************************************************************************
                   4637:  * ixgbe_config_dmac - Configure DMA Coalescing
                   4638:  ************************************************************************/
1.1       dyoung   4639: static void
1.98      msaitoh  4640: ixgbe_config_dmac(struct adapter *adapter)
1.1       dyoung   4641: {
                   4642:        struct ixgbe_hw *hw = &adapter->hw;
1.98      msaitoh  4643:        struct ixgbe_dmac_config *dcfg = &hw->mac.dmac_config;
1.1       dyoung   4644:
1.99      msaitoh  4645:        if (hw->mac.type < ixgbe_mac_X550 || !hw->mac.ops.dmac_config)
1.98      msaitoh  4646:                return;
1.65      msaitoh  4647:
1.98      msaitoh  4648:        if (dcfg->watchdog_timer ^ adapter->dmac ||
                   4649:            dcfg->link_speed ^ adapter->link_speed) {
                   4650:                dcfg->watchdog_timer = adapter->dmac;
                   4651:                dcfg->fcoe_en = false;
                   4652:                dcfg->link_speed = adapter->link_speed;
                   4653:                dcfg->num_tcs = 1;
1.51      msaitoh  4654:
1.98      msaitoh  4655:                INIT_DEBUGOUT2("dmac settings: watchdog %d, link speed %d\n",
                   4656:                    dcfg->watchdog_timer, dcfg->link_speed);
1.51      msaitoh  4657:
1.98      msaitoh  4658:                hw->mac.ops.dmac_config(hw);
                   4659:        }
1.99      msaitoh  4660: } /* ixgbe_config_dmac */
1.51      msaitoh  4661:
1.99      msaitoh  4662: /************************************************************************
                   4663:  * ixgbe_enable_intr
                   4664:  ************************************************************************/
1.98      msaitoh  4665: static void
                   4666: ixgbe_enable_intr(struct adapter *adapter)
                   4667: {
                   4668:        struct ixgbe_hw *hw = &adapter->hw;
                   4669:        struct ix_queue *que = adapter->queues;
                   4670:        u32             mask, fwsm;
1.51      msaitoh  4671:
1.98      msaitoh  4672:        mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
1.45      msaitoh  4673:
1.98      msaitoh  4674:        switch (adapter->hw.mac.type) {
1.99      msaitoh  4675:        case ixgbe_mac_82599EB:
                   4676:                mask |= IXGBE_EIMS_ECC;
                   4677:                /* Temperature sensor on some adapters */
                   4678:                mask |= IXGBE_EIMS_GPI_SDP0;
                   4679:                /* SFP+ (RX_LOS_N & MOD_ABS_N) */
                   4680:                mask |= IXGBE_EIMS_GPI_SDP1;
                   4681:                mask |= IXGBE_EIMS_GPI_SDP2;
                   4682:                break;
                   4683:        case ixgbe_mac_X540:
                   4684:                /* Detect if Thermal Sensor is enabled */
                   4685:                fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
                   4686:                if (fwsm & IXGBE_FWSM_TS_ENABLED)
1.98      msaitoh  4687:                        mask |= IXGBE_EIMS_TS;
1.99      msaitoh  4688:                mask |= IXGBE_EIMS_ECC;
                   4689:                break;
                   4690:        case ixgbe_mac_X550:
                   4691:                /* MAC thermal sensor is automatically enabled */
                   4692:                mask |= IXGBE_EIMS_TS;
                   4693:                mask |= IXGBE_EIMS_ECC;
                   4694:                break;
                   4695:        case ixgbe_mac_X550EM_x:
                   4696:        case ixgbe_mac_X550EM_a:
                   4697:                /* Some devices use SDP0 for important information */
                   4698:                if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
                   4699:                    hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP ||
                   4700:                    hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N ||
                   4701:                    hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T)
                   4702:                        mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(hw);
                   4703:                if (hw->phy.type == ixgbe_phy_x550em_ext_t)
                   4704:                        mask |= IXGBE_EICR_GPI_SDP0_X540;
                   4705:                mask |= IXGBE_EIMS_ECC;
                   4706:                break;
                   4707:        default:
                   4708:                break;
1.1       dyoung   4709:        }
1.51      msaitoh  4710:
1.99      msaitoh  4711:        /* Enable Fan Failure detection */
                   4712:        if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL)
                   4713:                mask |= IXGBE_EIMS_GPI_SDP1;
                   4714:        /* Enable SR-IOV */
                   4715:        if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
                   4716:                mask |= IXGBE_EIMS_MAILBOX;
                   4717:        /* Enable Flow Director */
                   4718:        if (adapter->feat_en & IXGBE_FEATURE_FDIR)
                   4719:                mask |= IXGBE_EIMS_FLOW_DIR;
                   4720:
1.98      msaitoh  4721:        IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
1.64      msaitoh  4722:
1.98      msaitoh  4723:        /* With MSI-X we use auto clear */
                   4724:        if (adapter->msix_mem) {
                   4725:                mask = IXGBE_EIMS_ENABLE_MASK;
                   4726:                /* Don't autoclear Link */
                   4727:                mask &= ~IXGBE_EIMS_OTHER;
                   4728:                mask &= ~IXGBE_EIMS_LSC;
1.99      msaitoh  4729:                if (adapter->feat_cap & IXGBE_FEATURE_SRIOV)
                   4730:                        mask &= ~IXGBE_EIMS_MAILBOX;
1.98      msaitoh  4731:                IXGBE_WRITE_REG(hw, IXGBE_EIAC, mask);
                   4732:        }
1.1       dyoung   4733:
1.98      msaitoh  4734:        /*
1.99      msaitoh  4735:         * Now enable all queues, this is done separately to
                   4736:         * allow for handling the extended (beyond 32) MSI-X
                   4737:         * vectors that can be used by 82599
                   4738:         */
1.98      msaitoh  4739:         for (int i = 0; i < adapter->num_queues; i++, que++)
                   4740:                 ixgbe_enable_queue(adapter, que->msix);
1.1       dyoung   4741:
1.98      msaitoh  4742:        IXGBE_WRITE_FLUSH(hw);
1.43      msaitoh  4743:
1.99      msaitoh  4744: } /* ixgbe_enable_intr */
1.1       dyoung   4745:
1.99      msaitoh  4746: /************************************************************************
1.139     knakahar 4747:  * ixgbe_disable_intr_internal
1.99      msaitoh  4748:  ************************************************************************/
1.44      msaitoh  4749: static void
1.139     knakahar 4750: ixgbe_disable_intr_internal(struct adapter *adapter, bool nestok)
1.44      msaitoh  4751: {
1.127     knakahar 4752:        struct ix_queue *que = adapter->queues;
                   4753:
                   4754:        /* disable interrupts other than queues */
                   4755:        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~IXGBE_EIMC_RTX_QUEUE);
                   4756:
1.98      msaitoh  4757:        if (adapter->msix_mem)
                   4758:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, 0);
1.127     knakahar 4759:
                   4760:        for (int i = 0; i < adapter->num_queues; i++, que++)
1.139     knakahar 4761:                ixgbe_disable_queue_internal(adapter, que->msix, nestok);
1.127     knakahar 4762:
1.98      msaitoh  4763:        IXGBE_WRITE_FLUSH(&adapter->hw);
1.99      msaitoh  4764:
1.139     knakahar 4765: } /* ixgbe_do_disable_intr_internal */
                   4766:
                   4767: /************************************************************************
                   4768:  * ixgbe_disable_intr
                   4769:  ************************************************************************/
                   4770: static void
                   4771: ixgbe_disable_intr(struct adapter *adapter)
                   4772: {
                   4773:
                   4774:        ixgbe_disable_intr_internal(adapter, true);
1.99      msaitoh  4775: } /* ixgbe_disable_intr */
1.98      msaitoh  4776:
1.99      msaitoh  4777: /************************************************************************
1.139     knakahar 4778:  * ixgbe_ensure_disabled_intr
                   4779:  ************************************************************************/
                   4780: void
                   4781: ixgbe_ensure_disabled_intr(struct adapter *adapter)
                   4782: {
                   4783:
                   4784:        ixgbe_disable_intr_internal(adapter, false);
                   4785: } /* ixgbe_ensure_disabled_intr */
                   4786:
                   4787: /************************************************************************
1.99      msaitoh  4788:  * ixgbe_legacy_irq - Legacy Interrupt Service routine
                   4789:  ************************************************************************/
1.98      msaitoh  4790: static int
                   4791: ixgbe_legacy_irq(void *arg)
1.1       dyoung   4792: {
1.98      msaitoh  4793:        struct ix_queue *que = arg;
                   4794:        struct adapter  *adapter = que->adapter;
                   4795:        struct ixgbe_hw *hw = &adapter->hw;
                   4796:        struct ifnet    *ifp = adapter->ifp;
                   4797:        struct          tx_ring *txr = adapter->tx_rings;
                   4798:        bool            more = false;
1.99      msaitoh  4799:        u32             eicr, eicr_mask;
1.98      msaitoh  4800:
1.99      msaitoh  4801:        /* Silicon errata #26 on 82598 */
                   4802:        IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
1.98      msaitoh  4803:
1.99      msaitoh  4804:        eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
1.44      msaitoh  4805:
1.98      msaitoh  4806:        adapter->stats.pf.legint.ev_count++;
                   4807:        ++que->irqs.ev_count;
1.99      msaitoh  4808:        if (eicr == 0) {
1.98      msaitoh  4809:                adapter->stats.pf.intzero.ev_count++;
                   4810:                if ((ifp->if_flags & IFF_UP) != 0)
                   4811:                        ixgbe_enable_intr(adapter);
                   4812:                return 0;
                   4813:        }
1.44      msaitoh  4814:
1.98      msaitoh  4815:        if ((ifp->if_flags & IFF_RUNNING) != 0) {
1.147     knakahar 4816:                /*
                   4817:                 * The same as ixgbe_msix_que() about "que->txrx_use_workqueue".
                   4818:                 */
                   4819:                que->txrx_use_workqueue = adapter->txrx_use_workqueue;
                   4820:
1.98      msaitoh  4821: #ifdef __NetBSD__
                   4822:                /* Don't run ixgbe_rxeof in interrupt context */
                   4823:                more = true;
                   4824: #else
                   4825:                more = ixgbe_rxeof(que);
                   4826: #endif
1.44      msaitoh  4827:
1.98      msaitoh  4828:                IXGBE_TX_LOCK(txr);
                   4829:                ixgbe_txeof(txr);
1.99      msaitoh  4830: #ifdef notyet
                   4831:                if (!ixgbe_ring_empty(ifp, txr->br))
                   4832:                        ixgbe_start_locked(ifp, txr);
                   4833: #endif
1.98      msaitoh  4834:                IXGBE_TX_UNLOCK(txr);
1.44      msaitoh  4835:        }
                   4836:
1.98      msaitoh  4837:        /* Check for fan failure */
1.99      msaitoh  4838:        if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) {
                   4839:                ixgbe_check_fan_failure(adapter, eicr, true);
1.98      msaitoh  4840:                IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
                   4841:        }
1.44      msaitoh  4842:
1.98      msaitoh  4843:        /* Link status change */
1.99      msaitoh  4844:        if (eicr & IXGBE_EICR_LSC)
1.98      msaitoh  4845:                softint_schedule(adapter->link_si);
1.44      msaitoh  4846:
1.99      msaitoh  4847:        if (ixgbe_is_sfp(hw)) {
                   4848:                /* Pluggable optics-related interrupt */
                   4849:                if (hw->mac.type >= ixgbe_mac_X540)
                   4850:                        eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
                   4851:                else
                   4852:                        eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
                   4853:
                   4854:                if (eicr & eicr_mask) {
                   4855:                        IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
                   4856:                        softint_schedule(adapter->mod_si);
                   4857:                }
                   4858:
                   4859:                if ((hw->mac.type == ixgbe_mac_82599EB) &&
                   4860:                    (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
                   4861:                        IXGBE_WRITE_REG(hw, IXGBE_EICR,
                   4862:                            IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
                   4863:                        softint_schedule(adapter->msf_si);
                   4864:                }
                   4865:        }
                   4866:
1.98      msaitoh  4867:        /* External PHY interrupt */
1.99      msaitoh  4868:        if ((hw->phy.type == ixgbe_phy_x550em_ext_t) &&
                   4869:            (eicr & IXGBE_EICR_GPI_SDP0_X540))
1.98      msaitoh  4870:                softint_schedule(adapter->phy_si);
1.44      msaitoh  4871:
1.129     msaitoh  4872:        if (more) {
                   4873:                que->req.ev_count++;
1.133     knakahar 4874:                ixgbe_sched_handle_que(adapter, que);
1.129     msaitoh  4875:        } else
1.98      msaitoh  4876:                ixgbe_enable_intr(adapter);
1.99      msaitoh  4877:
1.98      msaitoh  4878:        return 1;
1.99      msaitoh  4879: } /* ixgbe_legacy_irq */
1.98      msaitoh  4880:
1.99      msaitoh  4881: /************************************************************************
1.119     msaitoh  4882:  * ixgbe_free_pciintr_resources
1.99      msaitoh  4883:  ************************************************************************/
1.98      msaitoh  4884: static void
1.119     msaitoh  4885: ixgbe_free_pciintr_resources(struct adapter *adapter)
1.44      msaitoh  4886: {
1.99      msaitoh  4887:        struct ix_queue *que = adapter->queues;
1.98      msaitoh  4888:        int             rid;
1.44      msaitoh  4889:
1.98      msaitoh  4890:        /*
1.99      msaitoh  4891:         * Release all msix queue resources:
                   4892:         */
1.98      msaitoh  4893:        for (int i = 0; i < adapter->num_queues; i++, que++) {
1.119     msaitoh  4894:                if (que->res != NULL) {
1.98      msaitoh  4895:                        pci_intr_disestablish(adapter->osdep.pc,
                   4896:                            adapter->osdep.ihs[i]);
1.119     msaitoh  4897:                        adapter->osdep.ihs[i] = NULL;
                   4898:                }
1.58      msaitoh  4899:        }
                   4900:
1.98      msaitoh  4901:        /* Clean the Legacy or Link interrupt last */
                   4902:        if (adapter->vector) /* we are doing MSIX */
                   4903:                rid = adapter->vector;
                   4904:        else
                   4905:                rid = 0;
1.44      msaitoh  4906:
1.98      msaitoh  4907:        if (adapter->osdep.ihs[rid] != NULL) {
                   4908:                pci_intr_disestablish(adapter->osdep.pc,
                   4909:                    adapter->osdep.ihs[rid]);
                   4910:                adapter->osdep.ihs[rid] = NULL;
                   4911:        }
1.44      msaitoh  4912:
1.119     msaitoh  4913:        if (adapter->osdep.intrs != NULL) {
                   4914:                pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs,
                   4915:                    adapter->osdep.nintrs);
                   4916:                adapter->osdep.intrs = NULL;
                   4917:        }
                   4918: } /* ixgbe_free_pciintr_resources */
                   4919:
                   4920: /************************************************************************
                   4921:  * ixgbe_free_pci_resources
                   4922:  ************************************************************************/
                   4923: static void
                   4924: ixgbe_free_pci_resources(struct adapter *adapter)
                   4925: {
                   4926:
                   4927:        ixgbe_free_pciintr_resources(adapter);
1.44      msaitoh  4928:
1.98      msaitoh  4929:        if (adapter->osdep.mem_size != 0) {
                   4930:                bus_space_unmap(adapter->osdep.mem_bus_space_tag,
                   4931:                    adapter->osdep.mem_bus_space_handle,
                   4932:                    adapter->osdep.mem_size);
1.44      msaitoh  4933:        }
                   4934:
1.99      msaitoh  4935: } /* ixgbe_free_pci_resources */
1.44      msaitoh  4936:
1.99      msaitoh  4937: /************************************************************************
                   4938:  * ixgbe_set_sysctl_value
                   4939:  ************************************************************************/
1.44      msaitoh  4940: static void
1.98      msaitoh  4941: ixgbe_set_sysctl_value(struct adapter *adapter, const char *name,
                   4942:     const char *description, int *limit, int value)
1.44      msaitoh  4943: {
1.98      msaitoh  4944:        device_t dev =  adapter->dev;
                   4945:        struct sysctllog **log;
                   4946:        const struct sysctlnode *rnode, *cnode;
1.1       dyoung   4947:
1.98      msaitoh  4948:        log = &adapter->sysctllog;
                   4949:        if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL) {
                   4950:                aprint_error_dev(dev, "could not create sysctl root\n");
                   4951:                return;
                   4952:        }
                   4953:        if (sysctl_createv(log, 0, &rnode, &cnode,
                   4954:            CTLFLAG_READWRITE, CTLTYPE_INT,
                   4955:            name, SYSCTL_DESCR(description),
                   4956:                NULL, 0, limit, 0, CTL_CREATE, CTL_EOL) != 0)
                   4957:                aprint_error_dev(dev, "could not create sysctl\n");
                   4958:        *limit = value;
1.99      msaitoh  4959: } /* ixgbe_set_sysctl_value */
1.1       dyoung   4960:
1.99      msaitoh  4961: /************************************************************************
                   4962:  * ixgbe_sysctl_flowcntl
                   4963:  *
                   4964:  *   SYSCTL wrapper around setting Flow Control
                   4965:  ************************************************************************/
1.98      msaitoh  4966: static int
                   4967: ixgbe_sysctl_flowcntl(SYSCTLFN_ARGS)
                   4968: {
                   4969:        struct sysctlnode node = *rnode;
                   4970:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
1.99      msaitoh  4971:        int error, fc;
1.82      msaitoh  4972:
1.99      msaitoh  4973:        fc = adapter->hw.fc.current_mode;
1.98      msaitoh  4974:        node.sysctl_data = &fc;
                   4975:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   4976:        if (error != 0 || newp == NULL)
                   4977:                return error;
1.82      msaitoh  4978:
1.98      msaitoh  4979:        /* Don't bother if it's not changed */
1.99      msaitoh  4980:        if (fc == adapter->hw.fc.current_mode)
1.98      msaitoh  4981:                return (0);
1.83      msaitoh  4982:
1.98      msaitoh  4983:        return ixgbe_set_flowcntl(adapter, fc);
1.99      msaitoh  4984: } /* ixgbe_sysctl_flowcntl */
1.1       dyoung   4985:
1.99      msaitoh  4986: /************************************************************************
                   4987:  * ixgbe_set_flowcntl - Set flow control
                   4988:  *
                   4989:  *   Flow control values:
                   4990:  *     0 - off
                   4991:  *     1 - rx pause
                   4992:  *     2 - tx pause
                   4993:  *     3 - full
                   4994:  ************************************************************************/
1.98      msaitoh  4995: static int
                   4996: ixgbe_set_flowcntl(struct adapter *adapter, int fc)
                   4997: {
                   4998:        switch (fc) {
                   4999:                case ixgbe_fc_rx_pause:
                   5000:                case ixgbe_fc_tx_pause:
                   5001:                case ixgbe_fc_full:
1.99      msaitoh  5002:                        adapter->hw.fc.requested_mode = fc;
1.98      msaitoh  5003:                        if (adapter->num_queues > 1)
                   5004:                                ixgbe_disable_rx_drop(adapter);
                   5005:                        break;
                   5006:                case ixgbe_fc_none:
                   5007:                        adapter->hw.fc.requested_mode = ixgbe_fc_none;
                   5008:                        if (adapter->num_queues > 1)
                   5009:                                ixgbe_enable_rx_drop(adapter);
                   5010:                        break;
                   5011:                default:
                   5012:                        return (EINVAL);
1.1       dyoung   5013:        }
1.99      msaitoh  5014:
1.98      msaitoh  5015: #if 0 /* XXX NetBSD */
                   5016:        /* Don't autoneg if forcing a value */
                   5017:        adapter->hw.fc.disable_fc_autoneg = TRUE;
                   5018: #endif
                   5019:        ixgbe_fc_enable(&adapter->hw);
1.99      msaitoh  5020:
1.98      msaitoh  5021:        return (0);
1.99      msaitoh  5022: } /* ixgbe_set_flowcntl */
1.1       dyoung   5023:
1.99      msaitoh  5024: /************************************************************************
                   5025:  * ixgbe_enable_rx_drop
                   5026:  *
                   5027:  *   Enable the hardware to drop packets when the buffer is
                   5028:  *   full. This is useful with multiqueue, so that no single
                   5029:  *   queue being full stalls the entire RX engine. We only
                   5030:  *   enable this when Multiqueue is enabled AND Flow Control
                   5031:  *   is disabled.
                   5032:  ************************************************************************/
1.98      msaitoh  5033: static void
                   5034: ixgbe_enable_rx_drop(struct adapter *adapter)
                   5035: {
1.99      msaitoh  5036:        struct ixgbe_hw *hw = &adapter->hw;
                   5037:        struct rx_ring  *rxr;
                   5038:        u32             srrctl;
1.1       dyoung   5039:
1.98      msaitoh  5040:        for (int i = 0; i < adapter->num_queues; i++) {
1.99      msaitoh  5041:                rxr = &adapter->rx_rings[i];
                   5042:                srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me));
                   5043:                srrctl |= IXGBE_SRRCTL_DROP_EN;
                   5044:                IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
1.98      msaitoh  5045:        }
1.99      msaitoh  5046:
1.98      msaitoh  5047:        /* enable drop for each vf */
                   5048:        for (int i = 0; i < adapter->num_vfs; i++) {
                   5049:                IXGBE_WRITE_REG(hw, IXGBE_QDE,
                   5050:                    (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT) |
                   5051:                    IXGBE_QDE_ENABLE));
                   5052:        }
1.99      msaitoh  5053: } /* ixgbe_enable_rx_drop */
1.43      msaitoh  5054:
1.99      msaitoh  5055: /************************************************************************
                   5056:  * ixgbe_disable_rx_drop
                   5057:  ************************************************************************/
1.98      msaitoh  5058: static void
                   5059: ixgbe_disable_rx_drop(struct adapter *adapter)
                   5060: {
                   5061:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  5062:        struct rx_ring  *rxr;
                   5063:        u32             srrctl;
1.43      msaitoh  5064:
1.98      msaitoh  5065:        for (int i = 0; i < adapter->num_queues; i++) {
1.99      msaitoh  5066:                rxr = &adapter->rx_rings[i];
                   5067:                srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me));
1.98      msaitoh  5068:                srrctl &= ~IXGBE_SRRCTL_DROP_EN;
                   5069:                IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
                   5070:        }
1.99      msaitoh  5071:
1.98      msaitoh  5072:        /* disable drop for each vf */
                   5073:        for (int i = 0; i < adapter->num_vfs; i++) {
                   5074:                IXGBE_WRITE_REG(hw, IXGBE_QDE,
                   5075:                    (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT)));
1.1       dyoung   5076:        }
1.99      msaitoh  5077: } /* ixgbe_disable_rx_drop */
1.98      msaitoh  5078:
1.99      msaitoh  5079: /************************************************************************
                   5080:  * ixgbe_sysctl_advertise
                   5081:  *
                   5082:  *   SYSCTL wrapper around setting advertised speed
                   5083:  ************************************************************************/
1.98      msaitoh  5084: static int
                   5085: ixgbe_sysctl_advertise(SYSCTLFN_ARGS)
                   5086: {
1.99      msaitoh  5087:        struct sysctlnode node = *rnode;
                   5088:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
                   5089:        int            error = 0, advertise;
1.1       dyoung   5090:
1.98      msaitoh  5091:        advertise = adapter->advertise;
                   5092:        node.sysctl_data = &advertise;
                   5093:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5094:        if (error != 0 || newp == NULL)
                   5095:                return error;
1.28      msaitoh  5096:
1.98      msaitoh  5097:        return ixgbe_set_advertise(adapter, advertise);
1.99      msaitoh  5098: } /* ixgbe_sysctl_advertise */
1.1       dyoung   5099:
1.99      msaitoh  5100: /************************************************************************
                   5101:  * ixgbe_set_advertise - Control advertised link speed
                   5102:  *
                   5103:  *   Flags:
1.103     msaitoh  5104:  *     0x00 - Default (all capable link speed)
                   5105:  *     0x01 - advertise 100 Mb
                   5106:  *     0x02 - advertise 1G
                   5107:  *     0x04 - advertise 10G
                   5108:  *     0x08 - advertise 10 Mb
                   5109:  *     0x10 - advertise 2.5G
                   5110:  *     0x20 - advertise 5G
1.99      msaitoh  5111:  ************************************************************************/
1.98      msaitoh  5112: static int
                   5113: ixgbe_set_advertise(struct adapter *adapter, int advertise)
1.1       dyoung   5114: {
1.99      msaitoh  5115:        device_t         dev;
                   5116:        struct ixgbe_hw  *hw;
                   5117:        ixgbe_link_speed speed = 0;
                   5118:        ixgbe_link_speed link_caps = 0;
                   5119:        s32              err = IXGBE_NOT_IMPLEMENTED;
                   5120:        bool             negotiate = FALSE;
1.98      msaitoh  5121:
                   5122:        /* Checks to validate new value */
                   5123:        if (adapter->advertise == advertise) /* no change */
                   5124:                return (0);
                   5125:
1.99      msaitoh  5126:        dev = adapter->dev;
1.98      msaitoh  5127:        hw = &adapter->hw;
                   5128:
                   5129:        /* No speed changes for backplane media */
                   5130:        if (hw->phy.media_type == ixgbe_media_type_backplane)
                   5131:                return (ENODEV);
                   5132:
                   5133:        if (!((hw->phy.media_type == ixgbe_media_type_copper) ||
                   5134:            (hw->phy.multispeed_fiber))) {
                   5135:                device_printf(dev,
                   5136:                    "Advertised speed can only be set on copper or "
                   5137:                    "multispeed fiber media types.\n");
                   5138:                return (EINVAL);
                   5139:        }
                   5140:
1.109     msaitoh  5141:        if (advertise < 0x0 || advertise > 0x2f) {
1.98      msaitoh  5142:                device_printf(dev,
                   5143:                    "Invalid advertised speed; valid modes are 0x0 through 0x7\n");
                   5144:                return (EINVAL);
                   5145:        }
1.1       dyoung   5146:
1.99      msaitoh  5147:        if (hw->mac.ops.get_link_capabilities) {
                   5148:                err = hw->mac.ops.get_link_capabilities(hw, &link_caps,
                   5149:                    &negotiate);
                   5150:                if (err != IXGBE_SUCCESS) {
                   5151:                        device_printf(dev, "Unable to determine supported advertise speeds\n");
                   5152:                        return (ENODEV);
                   5153:                }
                   5154:        }
                   5155:
1.98      msaitoh  5156:        /* Set new value and report new advertised mode */
1.99      msaitoh  5157:        if (advertise & 0x1) {
                   5158:                if (!(link_caps & IXGBE_LINK_SPEED_100_FULL)) {
                   5159:                        device_printf(dev, "Interface does not support 100Mb advertised speed\n");
1.98      msaitoh  5160:                        return (EINVAL);
                   5161:                }
                   5162:                speed |= IXGBE_LINK_SPEED_100_FULL;
1.99      msaitoh  5163:        }
                   5164:        if (advertise & 0x2) {
                   5165:                if (!(link_caps & IXGBE_LINK_SPEED_1GB_FULL)) {
                   5166:                        device_printf(dev, "Interface does not support 1Gb advertised speed\n");
                   5167:                        return (EINVAL);
                   5168:                }
1.98      msaitoh  5169:                speed |= IXGBE_LINK_SPEED_1GB_FULL;
1.99      msaitoh  5170:        }
                   5171:        if (advertise & 0x4) {
                   5172:                if (!(link_caps & IXGBE_LINK_SPEED_10GB_FULL)) {
                   5173:                        device_printf(dev, "Interface does not support 10Gb advertised speed\n");
                   5174:                        return (EINVAL);
                   5175:                }
1.98      msaitoh  5176:                speed |= IXGBE_LINK_SPEED_10GB_FULL;
1.99      msaitoh  5177:        }
                   5178:        if (advertise & 0x8) {
                   5179:                if (!(link_caps & IXGBE_LINK_SPEED_10_FULL)) {
                   5180:                        device_printf(dev, "Interface does not support 10Mb advertised speed\n");
                   5181:                        return (EINVAL);
                   5182:                }
                   5183:                speed |= IXGBE_LINK_SPEED_10_FULL;
                   5184:        }
1.103     msaitoh  5185:        if (advertise & 0x10) {
                   5186:                if (!(link_caps & IXGBE_LINK_SPEED_2_5GB_FULL)) {
                   5187:                        device_printf(dev, "Interface does not support 2.5Gb advertised speed\n");
                   5188:                        return (EINVAL);
                   5189:                }
                   5190:                speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
                   5191:        }
                   5192:        if (advertise & 0x20) {
                   5193:                if (!(link_caps & IXGBE_LINK_SPEED_5GB_FULL)) {
                   5194:                        device_printf(dev, "Interface does not support 5Gb advertised speed\n");
                   5195:                        return (EINVAL);
                   5196:                }
                   5197:                speed |= IXGBE_LINK_SPEED_5GB_FULL;
                   5198:        }
1.99      msaitoh  5199:        if (advertise == 0)
                   5200:                speed = link_caps; /* All capable link speed */
1.1       dyoung   5201:
1.98      msaitoh  5202:        hw->mac.autotry_restart = TRUE;
                   5203:        hw->mac.ops.setup_link(hw, speed, TRUE);
1.99      msaitoh  5204:        adapter->advertise = advertise;
1.1       dyoung   5205:
1.99      msaitoh  5206:        return (0);
                   5207: } /* ixgbe_set_advertise */
1.1       dyoung   5208:
1.99      msaitoh  5209: /************************************************************************
                   5210:  * ixgbe_get_advertise - Get current advertised speed settings
                   5211:  *
                   5212:  *   Formatted for sysctl usage.
                   5213:  *   Flags:
1.103     msaitoh  5214:  *     0x01 - advertise 100 Mb
                   5215:  *     0x02 - advertise 1G
                   5216:  *     0x04 - advertise 10G
                   5217:  *     0x08 - advertise 10 Mb (yes, Mb)
                   5218:  *     0x10 - advertise 2.5G
                   5219:  *     0x20 - advertise 5G
1.99      msaitoh  5220:  ************************************************************************/
1.98      msaitoh  5221: static int
1.99      msaitoh  5222: ixgbe_get_advertise(struct adapter *adapter)
1.1       dyoung   5223: {
1.99      msaitoh  5224:        struct ixgbe_hw  *hw = &adapter->hw;
                   5225:        int              speed;
                   5226:        ixgbe_link_speed link_caps = 0;
                   5227:        s32              err;
                   5228:        bool             negotiate = FALSE;
1.98      msaitoh  5229:
1.99      msaitoh  5230:        /*
                   5231:         * Advertised speed means nothing unless it's copper or
                   5232:         * multi-speed fiber
                   5233:         */
                   5234:        if (!(hw->phy.media_type == ixgbe_media_type_copper) &&
                   5235:            !(hw->phy.multispeed_fiber))
                   5236:                return (0);
1.1       dyoung   5237:
1.99      msaitoh  5238:        err = hw->mac.ops.get_link_capabilities(hw, &link_caps, &negotiate);
                   5239:        if (err != IXGBE_SUCCESS)
                   5240:                return (0);
1.1       dyoung   5241:
1.99      msaitoh  5242:        speed =
1.103     msaitoh  5243:            ((link_caps & IXGBE_LINK_SPEED_10GB_FULL)  ? 0x04 : 0) |
                   5244:            ((link_caps & IXGBE_LINK_SPEED_1GB_FULL)   ? 0x02 : 0) |
                   5245:            ((link_caps & IXGBE_LINK_SPEED_100_FULL)   ? 0x01 : 0) |
                   5246:            ((link_caps & IXGBE_LINK_SPEED_10_FULL)    ? 0x08 : 0) |
                   5247:            ((link_caps & IXGBE_LINK_SPEED_2_5GB_FULL) ? 0x10 : 0) |
                   5248:            ((link_caps & IXGBE_LINK_SPEED_5GB_FULL)   ? 0x20 : 0);
1.99      msaitoh  5249:
                   5250:        return speed;
                   5251: } /* ixgbe_get_advertise */
                   5252:
                   5253: /************************************************************************
                   5254:  * ixgbe_sysctl_dmac - Manage DMA Coalescing
                   5255:  *
                   5256:  *   Control values:
                   5257:  *     0/1 - off / on (use default value of 1000)
                   5258:  *
                   5259:  *     Legal timer values are:
                   5260:  *     50,100,250,500,1000,2000,5000,10000
                   5261:  *
                   5262:  *     Turning off interrupt moderation will also turn this off.
                   5263:  ************************************************************************/
1.1       dyoung   5264: static int
1.98      msaitoh  5265: ixgbe_sysctl_dmac(SYSCTLFN_ARGS)
1.1       dyoung   5266: {
1.44      msaitoh  5267:        struct sysctlnode node = *rnode;
1.98      msaitoh  5268:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
1.99      msaitoh  5269:        struct ifnet   *ifp = adapter->ifp;
                   5270:        int            error;
                   5271:        int            newval;
1.1       dyoung   5272:
1.99      msaitoh  5273:        newval = adapter->dmac;
1.98      msaitoh  5274:        node.sysctl_data = &newval;
1.22      msaitoh  5275:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
1.98      msaitoh  5276:        if ((error) || (newp == NULL))
                   5277:                return (error);
                   5278:
                   5279:        switch (newval) {
                   5280:        case 0:
                   5281:                /* Disabled */
                   5282:                adapter->dmac = 0;
                   5283:                break;
                   5284:        case 1:
                   5285:                /* Enable and use default */
                   5286:                adapter->dmac = 1000;
                   5287:                break;
                   5288:        case 50:
                   5289:        case 100:
                   5290:        case 250:
                   5291:        case 500:
                   5292:        case 1000:
                   5293:        case 2000:
                   5294:        case 5000:
                   5295:        case 10000:
                   5296:                /* Legal values - allow */
                   5297:                adapter->dmac = newval;
                   5298:                break;
                   5299:        default:
                   5300:                /* Do nothing, illegal value */
                   5301:                return (EINVAL);
1.22      msaitoh  5302:        }
1.1       dyoung   5303:
1.98      msaitoh  5304:        /* Re-initialize hardware if it's already running */
                   5305:        if (ifp->if_flags & IFF_RUNNING)
1.135     msaitoh  5306:                ifp->if_init(ifp);
1.1       dyoung   5307:
1.98      msaitoh  5308:        return (0);
1.1       dyoung   5309: }
                   5310:
1.98      msaitoh  5311: #ifdef IXGBE_DEBUG
1.99      msaitoh  5312: /************************************************************************
                   5313:  * ixgbe_sysctl_power_state
                   5314:  *
                   5315:  *   Sysctl to test power states
                   5316:  *   Values:
                   5317:  *     0      - set device to D0
                   5318:  *     3      - set device to D3
                   5319:  *     (none) - get current device power state
                   5320:  ************************************************************************/
1.98      msaitoh  5321: static int
                   5322: ixgbe_sysctl_power_state(SYSCTLFN_ARGS)
1.44      msaitoh  5323: {
1.99      msaitoh  5324: #ifdef notyet
1.98      msaitoh  5325:        struct sysctlnode node = *rnode;
                   5326:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
1.99      msaitoh  5327:        device_t       dev =  adapter->dev;
                   5328:        int            curr_ps, new_ps, error = 0;
1.44      msaitoh  5329:
1.98      msaitoh  5330:        curr_ps = new_ps = pci_get_powerstate(dev);
1.44      msaitoh  5331:
1.98      msaitoh  5332:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5333:        if ((error) || (req->newp == NULL))
                   5334:                return (error);
1.44      msaitoh  5335:
1.98      msaitoh  5336:        if (new_ps == curr_ps)
                   5337:                return (0);
1.44      msaitoh  5338:
1.98      msaitoh  5339:        if (new_ps == 3 && curr_ps == 0)
                   5340:                error = DEVICE_SUSPEND(dev);
                   5341:        else if (new_ps == 0 && curr_ps == 3)
                   5342:                error = DEVICE_RESUME(dev);
                   5343:        else
                   5344:                return (EINVAL);
1.44      msaitoh  5345:
1.98      msaitoh  5346:        device_printf(dev, "New state: %d\n", pci_get_powerstate(dev));
1.44      msaitoh  5347:
1.98      msaitoh  5348:        return (error);
                   5349: #else
                   5350:        return 0;
                   5351: #endif
1.99      msaitoh  5352: } /* ixgbe_sysctl_power_state */
1.98      msaitoh  5353: #endif
1.99      msaitoh  5354:
                   5355: /************************************************************************
                   5356:  * ixgbe_sysctl_wol_enable
                   5357:  *
                   5358:  *   Sysctl to enable/disable the WoL capability,
                   5359:  *   if supported by the adapter.
                   5360:  *
                   5361:  *   Values:
                   5362:  *     0 - disabled
                   5363:  *     1 - enabled
                   5364:  ************************************************************************/
1.98      msaitoh  5365: static int
                   5366: ixgbe_sysctl_wol_enable(SYSCTLFN_ARGS)
                   5367: {
                   5368:        struct sysctlnode node = *rnode;
1.99      msaitoh  5369:        struct adapter  *adapter = (struct adapter *)node.sysctl_data;
1.98      msaitoh  5370:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  5371:        bool            new_wol_enabled;
                   5372:        int             error = 0;
1.44      msaitoh  5373:
1.98      msaitoh  5374:        new_wol_enabled = hw->wol_enabled;
                   5375:        node.sysctl_data = &new_wol_enabled;
                   5376:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5377:        if ((error) || (newp == NULL))
                   5378:                return (error);
                   5379:        if (new_wol_enabled == hw->wol_enabled)
                   5380:                return (0);
1.44      msaitoh  5381:
1.98      msaitoh  5382:        if (new_wol_enabled && !adapter->wol_support)
                   5383:                return (ENODEV);
                   5384:        else
                   5385:                hw->wol_enabled = new_wol_enabled;
1.44      msaitoh  5386:
1.98      msaitoh  5387:        return (0);
1.99      msaitoh  5388: } /* ixgbe_sysctl_wol_enable */
1.48      msaitoh  5389:
1.99      msaitoh  5390: /************************************************************************
                   5391:  * ixgbe_sysctl_wufc - Wake Up Filter Control
                   5392:  *
                   5393:  *   Sysctl to enable/disable the types of packets that the
                   5394:  *   adapter will wake up on upon receipt.
                   5395:  *   Flags:
                   5396:  *     0x1  - Link Status Change
                   5397:  *     0x2  - Magic Packet
                   5398:  *     0x4  - Direct Exact
                   5399:  *     0x8  - Directed Multicast
                   5400:  *     0x10 - Broadcast
                   5401:  *     0x20 - ARP/IPv4 Request Packet
                   5402:  *     0x40 - Direct IPv4 Packet
                   5403:  *     0x80 - Direct IPv6 Packet
1.98      msaitoh  5404:  *
1.99      msaitoh  5405:  *   Settings not listed above will cause the sysctl to return an error.
                   5406:  ************************************************************************/
1.1       dyoung   5407: static int
1.98      msaitoh  5408: ixgbe_sysctl_wufc(SYSCTLFN_ARGS)
1.1       dyoung   5409: {
1.98      msaitoh  5410:        struct sysctlnode node = *rnode;
                   5411:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
                   5412:        int error = 0;
                   5413:        u32 new_wufc;
1.52      msaitoh  5414:
1.98      msaitoh  5415:        new_wufc = adapter->wufc;
                   5416:        node.sysctl_data = &new_wufc;
1.52      msaitoh  5417:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
1.98      msaitoh  5418:        if ((error) || (newp == NULL))
                   5419:                return (error);
                   5420:        if (new_wufc == adapter->wufc)
                   5421:                return (0);
                   5422:
                   5423:        if (new_wufc & 0xffffff00)
                   5424:                return (EINVAL);
1.99      msaitoh  5425:
                   5426:        new_wufc &= 0xff;
                   5427:        new_wufc |= (0xffffff & adapter->wufc);
                   5428:        adapter->wufc = new_wufc;
1.52      msaitoh  5429:
1.98      msaitoh  5430:        return (0);
1.99      msaitoh  5431: } /* ixgbe_sysctl_wufc */
1.52      msaitoh  5432:
1.98      msaitoh  5433: #ifdef IXGBE_DEBUG
1.99      msaitoh  5434: /************************************************************************
                   5435:  * ixgbe_sysctl_print_rss_config
                   5436:  ************************************************************************/
1.52      msaitoh  5437: static int
1.98      msaitoh  5438: ixgbe_sysctl_print_rss_config(SYSCTLFN_ARGS)
1.52      msaitoh  5439: {
1.99      msaitoh  5440: #ifdef notyet
                   5441:        struct sysctlnode node = *rnode;
                   5442:        struct adapter  *adapter = (struct adapter *)node.sysctl_data;
1.98      msaitoh  5443:        struct ixgbe_hw *hw = &adapter->hw;
1.99      msaitoh  5444:        device_t        dev = adapter->dev;
                   5445:        struct sbuf     *buf;
                   5446:        int             error = 0, reta_size;
                   5447:        u32             reg;
1.1       dyoung   5448:
1.98      msaitoh  5449:        buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
                   5450:        if (!buf) {
                   5451:                device_printf(dev, "Could not allocate sbuf for output.\n");
                   5452:                return (ENOMEM);
                   5453:        }
1.52      msaitoh  5454:
1.98      msaitoh  5455:        // TODO: use sbufs to make a string to print out
                   5456:        /* Set multiplier for RETA setup and table size based on MAC */
                   5457:        switch (adapter->hw.mac.type) {
                   5458:        case ixgbe_mac_X550:
                   5459:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  5460:        case ixgbe_mac_X550EM_a:
1.98      msaitoh  5461:                reta_size = 128;
                   5462:                break;
                   5463:        default:
                   5464:                reta_size = 32;
                   5465:                break;
1.43      msaitoh  5466:        }
1.1       dyoung   5467:
1.98      msaitoh  5468:        /* Print out the redirection table */
                   5469:        sbuf_cat(buf, "\n");
                   5470:        for (int i = 0; i < reta_size; i++) {
                   5471:                if (i < 32) {
                   5472:                        reg = IXGBE_READ_REG(hw, IXGBE_RETA(i));
                   5473:                        sbuf_printf(buf, "RETA(%2d): 0x%08x\n", i, reg);
                   5474:                } else {
                   5475:                        reg = IXGBE_READ_REG(hw, IXGBE_ERETA(i - 32));
                   5476:                        sbuf_printf(buf, "ERETA(%2d): 0x%08x\n", i - 32, reg);
                   5477:                }
1.28      msaitoh  5478:        }
1.1       dyoung   5479:
1.98      msaitoh  5480:        // TODO: print more config
1.43      msaitoh  5481:
1.98      msaitoh  5482:        error = sbuf_finish(buf);
                   5483:        if (error)
                   5484:                device_printf(dev, "Error finishing sbuf: %d\n", error);
1.1       dyoung   5485:
1.98      msaitoh  5486:        sbuf_delete(buf);
1.99      msaitoh  5487: #endif
1.98      msaitoh  5488:        return (0);
1.99      msaitoh  5489: } /* ixgbe_sysctl_print_rss_config */
1.98      msaitoh  5490: #endif /* IXGBE_DEBUG */
1.24      msaitoh  5491:
1.99      msaitoh  5492: /************************************************************************
                   5493:  * ixgbe_sysctl_phy_temp - Retrieve temperature of PHY
                   5494:  *
                   5495:  *   For X552/X557-AT devices using an external PHY
                   5496:  ************************************************************************/
1.44      msaitoh  5497: static int
                   5498: ixgbe_sysctl_phy_temp(SYSCTLFN_ARGS)
                   5499: {
                   5500:        struct sysctlnode node = *rnode;
                   5501:        struct adapter  *adapter = (struct adapter *)node.sysctl_data;
                   5502:        struct ixgbe_hw *hw = &adapter->hw;
                   5503:        int val;
                   5504:        u16 reg;
                   5505:        int             error;
                   5506:
                   5507:        if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) {
                   5508:                device_printf(adapter->dev,
                   5509:                    "Device has no supported external thermal sensor.\n");
                   5510:                return (ENODEV);
                   5511:        }
                   5512:
                   5513:        if (hw->phy.ops.read_reg(hw, IXGBE_PHY_CURRENT_TEMP,
1.99      msaitoh  5514:                IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &reg)) {
1.44      msaitoh  5515:                device_printf(adapter->dev,
                   5516:                    "Error reading from PHY's current temperature register\n");
                   5517:                return (EAGAIN);
                   5518:        }
                   5519:
                   5520:        node.sysctl_data = &val;
                   5521:
                   5522:        /* Shift temp for output */
                   5523:        val = reg >> 8;
                   5524:
                   5525:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5526:        if ((error) || (newp == NULL))
                   5527:                return (error);
                   5528:
                   5529:        return (0);
1.99      msaitoh  5530: } /* ixgbe_sysctl_phy_temp */
1.44      msaitoh  5531:
1.99      msaitoh  5532: /************************************************************************
                   5533:  * ixgbe_sysctl_phy_overtemp_occurred
                   5534:  *
                   5535:  *   Reports (directly from the PHY) whether the current PHY
                   5536:  *   temperature is over the overtemp threshold.
                   5537:  ************************************************************************/
1.44      msaitoh  5538: static int
                   5539: ixgbe_sysctl_phy_overtemp_occurred(SYSCTLFN_ARGS)
                   5540: {
                   5541:        struct sysctlnode node = *rnode;
                   5542:        struct adapter  *adapter = (struct adapter *)node.sysctl_data;
                   5543:        struct ixgbe_hw *hw = &adapter->hw;
                   5544:        int val, error;
                   5545:        u16 reg;
                   5546:
                   5547:        if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) {
                   5548:                device_printf(adapter->dev,
                   5549:                    "Device has no supported external thermal sensor.\n");
                   5550:                return (ENODEV);
                   5551:        }
                   5552:
                   5553:        if (hw->phy.ops.read_reg(hw, IXGBE_PHY_OVERTEMP_STATUS,
1.99      msaitoh  5554:                IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &reg)) {
1.44      msaitoh  5555:                device_printf(adapter->dev,
                   5556:                    "Error reading from PHY's temperature status register\n");
                   5557:                return (EAGAIN);
                   5558:        }
                   5559:
                   5560:        node.sysctl_data = &val;
                   5561:
                   5562:        /* Get occurrence bit */
                   5563:        val = !!(reg & 0x4000);
                   5564:
                   5565:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5566:        if ((error) || (newp == NULL))
                   5567:                return (error);
                   5568:
                   5569:        return (0);
1.99      msaitoh  5570: } /* ixgbe_sysctl_phy_overtemp_occurred */
                   5571:
                   5572: /************************************************************************
                   5573:  * ixgbe_sysctl_eee_state
                   5574:  *
                   5575:  *   Sysctl to set EEE power saving feature
                   5576:  *   Values:
                   5577:  *     0      - disable EEE
                   5578:  *     1      - enable EEE
                   5579:  *     (none) - get current device EEE state
                   5580:  ************************************************************************/
                   5581: static int
                   5582: ixgbe_sysctl_eee_state(SYSCTLFN_ARGS)
                   5583: {
                   5584:        struct sysctlnode node = *rnode;
                   5585:        struct adapter *adapter = (struct adapter *)node.sysctl_data;
                   5586:        struct ifnet   *ifp = adapter->ifp;
                   5587:        device_t       dev = adapter->dev;
                   5588:        int            curr_eee, new_eee, error = 0;
                   5589:        s32            retval;
                   5590:
                   5591:        curr_eee = new_eee = !!(adapter->feat_en & IXGBE_FEATURE_EEE);
                   5592:        node.sysctl_data = &new_eee;
                   5593:        error = sysctl_lookup(SYSCTLFN_CALL(&node));
                   5594:        if ((error) || (newp == NULL))
                   5595:                return (error);
                   5596:
                   5597:        /* Nothing to do */
                   5598:        if (new_eee == curr_eee)
                   5599:                return (0);
                   5600:
                   5601:        /* Not supported */
                   5602:        if (!(adapter->feat_cap & IXGBE_FEATURE_EEE))
                   5603:                return (EINVAL);
                   5604:
                   5605:        /* Bounds checking */
                   5606:        if ((new_eee < 0) || (new_eee > 1))
                   5607:                return (EINVAL);
                   5608:
                   5609:        retval = adapter->hw.mac.ops.setup_eee(&adapter->hw, new_eee);
                   5610:        if (retval) {
                   5611:                device_printf(dev, "Error in EEE setup: 0x%08X\n", retval);
                   5612:                return (EINVAL);
                   5613:        }
                   5614:
                   5615:        /* Restart auto-neg */
1.135     msaitoh  5616:        ifp->if_init(ifp);
1.99      msaitoh  5617:
                   5618:        device_printf(dev, "New EEE state: %d\n", new_eee);
                   5619:
                   5620:        /* Cache new value */
                   5621:        if (new_eee)
                   5622:                adapter->feat_en |= IXGBE_FEATURE_EEE;
                   5623:        else
                   5624:                adapter->feat_en &= ~IXGBE_FEATURE_EEE;
                   5625:
                   5626:        return (error);
                   5627: } /* ixgbe_sysctl_eee_state */
                   5628:
                   5629: /************************************************************************
                   5630:  * ixgbe_init_device_features
                   5631:  ************************************************************************/
                   5632: static void
                   5633: ixgbe_init_device_features(struct adapter *adapter)
                   5634: {
                   5635:        adapter->feat_cap = IXGBE_FEATURE_NETMAP
                   5636:                          | IXGBE_FEATURE_RSS
                   5637:                          | IXGBE_FEATURE_MSI
                   5638:                          | IXGBE_FEATURE_MSIX
                   5639:                          | IXGBE_FEATURE_LEGACY_IRQ
                   5640:                          | IXGBE_FEATURE_LEGACY_TX;
                   5641:
                   5642:        /* Set capabilities first... */
                   5643:        switch (adapter->hw.mac.type) {
                   5644:        case ixgbe_mac_82598EB:
                   5645:                if (adapter->hw.device_id == IXGBE_DEV_ID_82598AT)
                   5646:                        adapter->feat_cap |= IXGBE_FEATURE_FAN_FAIL;
                   5647:                break;
                   5648:        case ixgbe_mac_X540:
                   5649:                adapter->feat_cap |= IXGBE_FEATURE_SRIOV;
                   5650:                adapter->feat_cap |= IXGBE_FEATURE_FDIR;
                   5651:                if ((adapter->hw.device_id == IXGBE_DEV_ID_X540_BYPASS) &&
                   5652:                    (adapter->hw.bus.func == 0))
                   5653:                        adapter->feat_cap |= IXGBE_FEATURE_BYPASS;
                   5654:                break;
                   5655:        case ixgbe_mac_X550:
                   5656:                adapter->feat_cap |= IXGBE_FEATURE_TEMP_SENSOR;
                   5657:                adapter->feat_cap |= IXGBE_FEATURE_SRIOV;
                   5658:                adapter->feat_cap |= IXGBE_FEATURE_FDIR;
                   5659:                break;
                   5660:        case ixgbe_mac_X550EM_x:
                   5661:                adapter->feat_cap |= IXGBE_FEATURE_SRIOV;
                   5662:                adapter->feat_cap |= IXGBE_FEATURE_FDIR;
                   5663:                if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_KR)
                   5664:                        adapter->feat_cap |= IXGBE_FEATURE_EEE;
                   5665:                break;
                   5666:        case ixgbe_mac_X550EM_a:
                   5667:                adapter->feat_cap |= IXGBE_FEATURE_SRIOV;
                   5668:                adapter->feat_cap |= IXGBE_FEATURE_FDIR;
                   5669:                adapter->feat_cap &= ~IXGBE_FEATURE_LEGACY_IRQ;
                   5670:                if ((adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_1G_T) ||
                   5671:                    (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L)) {
                   5672:                        adapter->feat_cap |= IXGBE_FEATURE_TEMP_SENSOR;
                   5673:                        adapter->feat_cap |= IXGBE_FEATURE_EEE;
                   5674:                }
                   5675:                break;
                   5676:        case ixgbe_mac_82599EB:
                   5677:                adapter->feat_cap |= IXGBE_FEATURE_SRIOV;
                   5678:                adapter->feat_cap |= IXGBE_FEATURE_FDIR;
                   5679:                if ((adapter->hw.device_id == IXGBE_DEV_ID_82599_BYPASS) &&
                   5680:                    (adapter->hw.bus.func == 0))
                   5681:                        adapter->feat_cap |= IXGBE_FEATURE_BYPASS;
                   5682:                if (adapter->hw.device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP)
                   5683:                        adapter->feat_cap &= ~IXGBE_FEATURE_LEGACY_IRQ;
                   5684:                break;
                   5685:        default:
                   5686:                break;
                   5687:        }
                   5688:
                   5689:        /* Enabled by default... */
                   5690:        /* Fan failure detection */
                   5691:        if (adapter->feat_cap & IXGBE_FEATURE_FAN_FAIL)
                   5692:                adapter->feat_en |= IXGBE_FEATURE_FAN_FAIL;
                   5693:        /* Netmap */
                   5694:        if (adapter->feat_cap & IXGBE_FEATURE_NETMAP)
                   5695:                adapter->feat_en |= IXGBE_FEATURE_NETMAP;
                   5696:        /* EEE */
                   5697:        if (adapter->feat_cap & IXGBE_FEATURE_EEE)
                   5698:                adapter->feat_en |= IXGBE_FEATURE_EEE;
                   5699:        /* Thermal Sensor */
                   5700:        if (adapter->feat_cap & IXGBE_FEATURE_TEMP_SENSOR)
                   5701:                adapter->feat_en |= IXGBE_FEATURE_TEMP_SENSOR;
                   5702:
                   5703:        /* Enabled via global sysctl... */
                   5704:        /* Flow Director */
                   5705:        if (ixgbe_enable_fdir) {
                   5706:                if (adapter->feat_cap & IXGBE_FEATURE_FDIR)
                   5707:                        adapter->feat_en |= IXGBE_FEATURE_FDIR;
                   5708:                else
                   5709:                        device_printf(adapter->dev, "Device does not support Flow Director. Leaving disabled.");
                   5710:        }
                   5711:        /* Legacy (single queue) transmit */
                   5712:        if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) &&
                   5713:            ixgbe_enable_legacy_tx)
                   5714:                adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX;
                   5715:        /*
                   5716:         * Message Signal Interrupts - Extended (MSI-X)
                   5717:         * Normal MSI is only enabled if MSI-X calls fail.
                   5718:         */
                   5719:        if (!ixgbe_enable_msix)
                   5720:                adapter->feat_cap &= ~IXGBE_FEATURE_MSIX;
                   5721:        /* Receive-Side Scaling (RSS) */
                   5722:        if ((adapter->feat_cap & IXGBE_FEATURE_RSS) && ixgbe_enable_rss)
                   5723:                adapter->feat_en |= IXGBE_FEATURE_RSS;
                   5724:
                   5725:        /* Disable features with unmet dependencies... */
                   5726:        /* No MSI-X */
                   5727:        if (!(adapter->feat_cap & IXGBE_FEATURE_MSIX)) {
                   5728:                adapter->feat_cap &= ~IXGBE_FEATURE_RSS;
                   5729:                adapter->feat_cap &= ~IXGBE_FEATURE_SRIOV;
                   5730:                adapter->feat_en &= ~IXGBE_FEATURE_RSS;
                   5731:                adapter->feat_en &= ~IXGBE_FEATURE_SRIOV;
                   5732:        }
                   5733: } /* ixgbe_init_device_features */
1.44      msaitoh  5734:
1.99      msaitoh  5735: /************************************************************************
                   5736:  * ixgbe_probe - Device identification routine
1.98      msaitoh  5737:  *
1.99      msaitoh  5738:  *   Determines if the driver should be loaded on
                   5739:  *   adapter based on its PCI vendor/device ID.
1.98      msaitoh  5740:  *
1.99      msaitoh  5741:  *   return BUS_PROBE_DEFAULT on success, positive on failure
                   5742:  ************************************************************************/
1.98      msaitoh  5743: static int
                   5744: ixgbe_probe(device_t dev, cfdata_t cf, void *aux)
                   5745: {
                   5746:        const struct pci_attach_args *pa = aux;
                   5747:
                   5748:        return (ixgbe_lookup(pa) != NULL) ? 1 : 0;
                   5749: }
                   5750:
                   5751: static ixgbe_vendor_info_t *
                   5752: ixgbe_lookup(const struct pci_attach_args *pa)
                   5753: {
1.99      msaitoh  5754:        ixgbe_vendor_info_t *ent;
1.98      msaitoh  5755:        pcireg_t subid;
                   5756:
                   5757:        INIT_DEBUGOUT("ixgbe_lookup: begin");
                   5758:
                   5759:        if (PCI_VENDOR(pa->pa_id) != IXGBE_INTEL_VENDOR_ID)
                   5760:                return NULL;
                   5761:
                   5762:        subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
                   5763:
                   5764:        for (ent = ixgbe_vendor_info_array; ent->vendor_id != 0; ent++) {
1.99      msaitoh  5765:                if ((PCI_VENDOR(pa->pa_id) == ent->vendor_id) &&
                   5766:                    (PCI_PRODUCT(pa->pa_id) == ent->device_id) &&
                   5767:                    ((PCI_SUBSYS_VENDOR(subid) == ent->subvendor_id) ||
                   5768:                        (ent->subvendor_id == 0)) &&
                   5769:                    ((PCI_SUBSYS_ID(subid) == ent->subdevice_id) ||
                   5770:                        (ent->subdevice_id == 0))) {
1.98      msaitoh  5771:                        ++ixgbe_total_ports;
                   5772:                        return ent;
                   5773:                }
                   5774:        }
                   5775:        return NULL;
                   5776: }
                   5777:
                   5778: static int
                   5779: ixgbe_ifflags_cb(struct ethercom *ec)
                   5780: {
                   5781:        struct ifnet *ifp = &ec->ec_if;
                   5782:        struct adapter *adapter = ifp->if_softc;
1.146     msaitoh  5783:        int change, rc = 0;
1.98      msaitoh  5784:
                   5785:        IXGBE_CORE_LOCK(adapter);
                   5786:
1.146     msaitoh  5787:        change = ifp->if_flags ^ adapter->if_flags;
1.98      msaitoh  5788:        if (change != 0)
                   5789:                adapter->if_flags = ifp->if_flags;
                   5790:
                   5791:        if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0)
                   5792:                rc = ENETRESET;
                   5793:        else if ((change & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
                   5794:                ixgbe_set_promisc(adapter);
                   5795:
                   5796:        /* Set up VLAN support and filter */
                   5797:        ixgbe_setup_vlan_hw_support(adapter);
                   5798:
                   5799:        IXGBE_CORE_UNLOCK(adapter);
                   5800:
                   5801:        return rc;
                   5802: }
                   5803:
1.99      msaitoh  5804: /************************************************************************
                   5805:  * ixgbe_ioctl - Ioctl entry point
1.98      msaitoh  5806:  *
1.99      msaitoh  5807:  *   Called when the user wants to configure the interface.
1.98      msaitoh  5808:  *
1.99      msaitoh  5809:  *   return 0 on success, positive on failure
                   5810:  ************************************************************************/
1.98      msaitoh  5811: static int
                   5812: ixgbe_ioctl(struct ifnet * ifp, u_long command, void *data)
                   5813: {
                   5814:        struct adapter  *adapter = ifp->if_softc;
                   5815:        struct ixgbe_hw *hw = &adapter->hw;
                   5816:        struct ifcapreq *ifcr = data;
                   5817:        struct ifreq    *ifr = data;
                   5818:        int             error = 0;
                   5819:        int l4csum_en;
                   5820:        const int l4csum = IFCAP_CSUM_TCPv4_Rx|IFCAP_CSUM_UDPv4_Rx|
                   5821:             IFCAP_CSUM_TCPv6_Rx|IFCAP_CSUM_UDPv6_Rx;
                   5822:
                   5823:        switch (command) {
                   5824:        case SIOCSIFFLAGS:
                   5825:                IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
                   5826:                break;
                   5827:        case SIOCADDMULTI:
                   5828:        case SIOCDELMULTI:
                   5829:                IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
                   5830:                break;
                   5831:        case SIOCSIFMEDIA:
                   5832:        case SIOCGIFMEDIA:
                   5833:                IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
                   5834:                break;
                   5835:        case SIOCSIFCAP:
                   5836:                IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
                   5837:                break;
                   5838:        case SIOCSIFMTU:
                   5839:                IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
                   5840:                break;
                   5841: #ifdef __NetBSD__
                   5842:        case SIOCINITIFADDR:
                   5843:                IOCTL_DEBUGOUT("ioctl: SIOCINITIFADDR");
                   5844:                break;
                   5845:        case SIOCGIFFLAGS:
                   5846:                IOCTL_DEBUGOUT("ioctl: SIOCGIFFLAGS");
                   5847:                break;
                   5848:        case SIOCGIFAFLAG_IN:
                   5849:                IOCTL_DEBUGOUT("ioctl: SIOCGIFAFLAG_IN");
                   5850:                break;
                   5851:        case SIOCGIFADDR:
                   5852:                IOCTL_DEBUGOUT("ioctl: SIOCGIFADDR");
                   5853:                break;
                   5854:        case SIOCGIFMTU:
                   5855:                IOCTL_DEBUGOUT("ioctl: SIOCGIFMTU (Get Interface MTU)");
                   5856:                break;
                   5857:        case SIOCGIFCAP:
                   5858:                IOCTL_DEBUGOUT("ioctl: SIOCGIFCAP (Get IF cap)");
                   5859:                break;
                   5860:        case SIOCGETHERCAP:
                   5861:                IOCTL_DEBUGOUT("ioctl: SIOCGETHERCAP (Get ethercap)");
                   5862:                break;
                   5863:        case SIOCGLIFADDR:
                   5864:                IOCTL_DEBUGOUT("ioctl: SIOCGLIFADDR (Get Interface addr)");
                   5865:                break;
                   5866:        case SIOCZIFDATA:
                   5867:                IOCTL_DEBUGOUT("ioctl: SIOCZIFDATA (Zero counter)");
                   5868:                hw->mac.ops.clear_hw_cntrs(hw);
                   5869:                ixgbe_clear_evcnt(adapter);
                   5870:                break;
                   5871:        case SIOCAIFADDR:
                   5872:                IOCTL_DEBUGOUT("ioctl: SIOCAIFADDR (add/chg IF alias)");
                   5873:                break;
                   5874: #endif
                   5875:        default:
                   5876:                IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)", (int)command);
                   5877:                break;
                   5878:        }
1.24      msaitoh  5879:
1.98      msaitoh  5880:        switch (command) {
                   5881:        case SIOCSIFMEDIA:
                   5882:        case SIOCGIFMEDIA:
                   5883:                return ifmedia_ioctl(ifp, ifr, &adapter->media, command);
                   5884:        case SIOCGI2C:
                   5885:        {
                   5886:                struct ixgbe_i2c_req    i2c;
1.24      msaitoh  5887:
1.98      msaitoh  5888:                IOCTL_DEBUGOUT("ioctl: SIOCGI2C (Get I2C Data)");
                   5889:                error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
                   5890:                if (error != 0)
                   5891:                        break;
                   5892:                if (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2) {
                   5893:                        error = EINVAL;
                   5894:                        break;
                   5895:                }
                   5896:                if (i2c.len > sizeof(i2c.data)) {
                   5897:                        error = EINVAL;
                   5898:                        break;
                   5899:                }
1.24      msaitoh  5900:
1.98      msaitoh  5901:                hw->phy.ops.read_i2c_byte(hw, i2c.offset,
                   5902:                    i2c.dev_addr, i2c.data);
                   5903:                error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
                   5904:                break;
                   5905:        }
                   5906:        case SIOCSIFCAP:
                   5907:                /* Layer-4 Rx checksum offload has to be turned on and
                   5908:                 * off as a unit.
                   5909:                 */
                   5910:                l4csum_en = ifcr->ifcr_capenable & l4csum;
                   5911:                if (l4csum_en != l4csum && l4csum_en != 0)
                   5912:                        return EINVAL;
                   5913:                /*FALLTHROUGH*/
                   5914:        case SIOCADDMULTI:
                   5915:        case SIOCDELMULTI:
                   5916:        case SIOCSIFFLAGS:
                   5917:        case SIOCSIFMTU:
                   5918:        default:
                   5919:                if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
                   5920:                        return error;
                   5921:                if ((ifp->if_flags & IFF_RUNNING) == 0)
                   5922:                        ;
                   5923:                else if (command == SIOCSIFCAP || command == SIOCSIFMTU) {
                   5924:                        IXGBE_CORE_LOCK(adapter);
1.135     msaitoh  5925:                        if ((ifp->if_flags & IFF_RUNNING) != 0)
                   5926:                                ixgbe_init_locked(adapter);
1.98      msaitoh  5927:                        ixgbe_recalculate_max_frame(adapter);
                   5928:                        IXGBE_CORE_UNLOCK(adapter);
                   5929:                } else if (command == SIOCADDMULTI || command == SIOCDELMULTI) {
                   5930:                        /*
                   5931:                         * Multicast list has changed; set the hardware filter
                   5932:                         * accordingly.
                   5933:                         */
                   5934:                        IXGBE_CORE_LOCK(adapter);
                   5935:                        ixgbe_disable_intr(adapter);
                   5936:                        ixgbe_set_multi(adapter);
                   5937:                        ixgbe_enable_intr(adapter);
                   5938:                        IXGBE_CORE_UNLOCK(adapter);
                   5939:                }
                   5940:                return 0;
1.24      msaitoh  5941:        }
                   5942:
1.98      msaitoh  5943:        return error;
1.99      msaitoh  5944: } /* ixgbe_ioctl */
                   5945:
                   5946: /************************************************************************
                   5947:  * ixgbe_check_fan_failure
                   5948:  ************************************************************************/
                   5949: static void
                   5950: ixgbe_check_fan_failure(struct adapter *adapter, u32 reg, bool in_interrupt)
                   5951: {
                   5952:        u32 mask;
                   5953:
                   5954:        mask = (in_interrupt) ? IXGBE_EICR_GPI_SDP1_BY_MAC(&adapter->hw) :
                   5955:            IXGBE_ESDP_SDP1;
1.26      msaitoh  5956:
1.99      msaitoh  5957:        if (reg & mask)
                   5958:                device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! REPLACE IMMEDIATELY!!\n");
                   5959: } /* ixgbe_check_fan_failure */
                   5960:
                   5961: /************************************************************************
                   5962:  * ixgbe_handle_que
                   5963:  ************************************************************************/
1.98      msaitoh  5964: static void
                   5965: ixgbe_handle_que(void *context)
1.44      msaitoh  5966: {
1.98      msaitoh  5967:        struct ix_queue *que = context;
                   5968:        struct adapter  *adapter = que->adapter;
                   5969:        struct tx_ring  *txr = que->txr;
                   5970:        struct ifnet    *ifp = adapter->ifp;
1.121     msaitoh  5971:        bool            more = false;
1.44      msaitoh  5972:
1.129     msaitoh  5973:        que->handleq.ev_count++;
1.44      msaitoh  5974:
1.98      msaitoh  5975:        if (ifp->if_flags & IFF_RUNNING) {
1.121     msaitoh  5976:                more = ixgbe_rxeof(que);
1.98      msaitoh  5977:                IXGBE_TX_LOCK(txr);
1.126     msaitoh  5978:                more |= ixgbe_txeof(txr);
1.99      msaitoh  5979:                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
                   5980:                        if (!ixgbe_mq_ring_empty(ifp, txr->txr_interq))
                   5981:                                ixgbe_mq_start_locked(ifp, txr);
1.98      msaitoh  5982:                /* Only for queue 0 */
1.99      msaitoh  5983:                /* NetBSD still needs this for CBQ */
1.98      msaitoh  5984:                if ((&adapter->queues[0] == que)
1.99      msaitoh  5985:                    && (!ixgbe_legacy_ring_empty(ifp, NULL)))
                   5986:                        ixgbe_legacy_start_locked(ifp, txr);
1.98      msaitoh  5987:                IXGBE_TX_UNLOCK(txr);
1.44      msaitoh  5988:        }
                   5989:
1.128     knakahar 5990:        if (more) {
1.129     msaitoh  5991:                que->req.ev_count++;
1.133     knakahar 5992:                ixgbe_sched_handle_que(adapter, que);
1.128     knakahar 5993:        } else if (que->res != NULL) {
1.121     msaitoh  5994:                /* Re-enable this interrupt */
1.98      msaitoh  5995:                ixgbe_enable_queue(adapter, que->msix);
1.121     msaitoh  5996:        } else
1.98      msaitoh  5997:                ixgbe_enable_intr(adapter);
1.99      msaitoh  5998:
1.98      msaitoh  5999:        return;
1.99      msaitoh  6000: } /* ixgbe_handle_que */
1.44      msaitoh  6001:
1.99      msaitoh  6002: /************************************************************************
1.128     knakahar 6003:  * ixgbe_handle_que_work
                   6004:  ************************************************************************/
                   6005: static void
                   6006: ixgbe_handle_que_work(struct work *wk, void *context)
                   6007: {
                   6008:        struct ix_queue *que = container_of(wk, struct ix_queue, wq_cookie);
                   6009:
                   6010:        /*
                   6011:         * "enqueued flag" is not required here.
                   6012:         * See ixgbe_msix_que().
                   6013:         */
                   6014:        ixgbe_handle_que(que);
                   6015: }
                   6016:
                   6017: /************************************************************************
1.99      msaitoh  6018:  * ixgbe_allocate_legacy - Setup the Legacy or MSI Interrupt handler
                   6019:  ************************************************************************/
1.48      msaitoh  6020: static int
1.98      msaitoh  6021: ixgbe_allocate_legacy(struct adapter *adapter,
                   6022:     const struct pci_attach_args *pa)
1.48      msaitoh  6023: {
1.98      msaitoh  6024:        device_t        dev = adapter->dev;
1.99      msaitoh  6025:        struct ix_queue *que = adapter->queues;
                   6026:        struct tx_ring  *txr = adapter->tx_rings;
1.98      msaitoh  6027:        int             counts[PCI_INTR_TYPE_SIZE];
                   6028:        pci_intr_type_t intr_type, max_type;
1.99      msaitoh  6029:        char            intrbuf[PCI_INTRSTR_LEN];
1.98      msaitoh  6030:        const char      *intrstr = NULL;
                   6031:
1.99      msaitoh  6032:        /* We allocate a single interrupt resource */
1.98      msaitoh  6033:        max_type = PCI_INTR_TYPE_MSI;
                   6034:        counts[PCI_INTR_TYPE_MSIX] = 0;
1.99      msaitoh  6035:        counts[PCI_INTR_TYPE_MSI] =
                   6036:            (adapter->feat_en & IXGBE_FEATURE_MSI) ? 1 : 0;
1.118     msaitoh  6037:        /* Check not feat_en but feat_cap to fallback to INTx */
1.99      msaitoh  6038:        counts[PCI_INTR_TYPE_INTX] =
1.118     msaitoh  6039:            (adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ) ? 1 : 0;
1.48      msaitoh  6040:
1.98      msaitoh  6041: alloc_retry:
                   6042:        if (pci_intr_alloc(pa, &adapter->osdep.intrs, counts, max_type) != 0) {
                   6043:                aprint_error_dev(dev, "couldn't alloc interrupt\n");
                   6044:                return ENXIO;
                   6045:        }
                   6046:        adapter->osdep.nintrs = 1;
                   6047:        intrstr = pci_intr_string(adapter->osdep.pc, adapter->osdep.intrs[0],
                   6048:            intrbuf, sizeof(intrbuf));
                   6049:        adapter->osdep.ihs[0] = pci_intr_establish_xname(adapter->osdep.pc,
                   6050:            adapter->osdep.intrs[0], IPL_NET, ixgbe_legacy_irq, que,
                   6051:            device_xname(dev));
1.119     msaitoh  6052:        intr_type = pci_intr_type(adapter->osdep.pc, adapter->osdep.intrs[0]);
1.98      msaitoh  6053:        if (adapter->osdep.ihs[0] == NULL) {
                   6054:                aprint_error_dev(dev,"unable to establish %s\n",
                   6055:                    (intr_type == PCI_INTR_TYPE_MSI) ? "MSI" : "INTx");
                   6056:                pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1);
1.119     msaitoh  6057:                adapter->osdep.intrs = NULL;
1.98      msaitoh  6058:                switch (intr_type) {
                   6059:                case PCI_INTR_TYPE_MSI:
                   6060:                        /* The next try is for INTx: Disable MSI */
                   6061:                        max_type = PCI_INTR_TYPE_INTX;
                   6062:                        counts[PCI_INTR_TYPE_INTX] = 1;
1.118     msaitoh  6063:                        adapter->feat_en &= ~IXGBE_FEATURE_MSI;
                   6064:                        if (adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ) {
                   6065:                                adapter->feat_en |= IXGBE_FEATURE_LEGACY_IRQ;
                   6066:                                goto alloc_retry;
                   6067:                        } else
                   6068:                                break;
1.98      msaitoh  6069:                case PCI_INTR_TYPE_INTX:
                   6070:                default:
                   6071:                        /* See below */
                   6072:                        break;
                   6073:                }
                   6074:        }
1.119     msaitoh  6075:        if (intr_type == PCI_INTR_TYPE_INTX) {
                   6076:                adapter->feat_en &= ~IXGBE_FEATURE_MSI;
                   6077:                adapter->feat_en |= IXGBE_FEATURE_LEGACY_IRQ;
                   6078:        }
1.98      msaitoh  6079:        if (adapter->osdep.ihs[0] == NULL) {
                   6080:                aprint_error_dev(dev,
                   6081:                    "couldn't establish interrupt%s%s\n",
                   6082:                    intrstr ? " at " : "", intrstr ? intrstr : "");
                   6083:                pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1);
1.119     msaitoh  6084:                adapter->osdep.intrs = NULL;
1.98      msaitoh  6085:                return ENXIO;
                   6086:        }
                   6087:        aprint_normal_dev(dev, "interrupting at %s\n", intrstr);
                   6088:        /*
                   6089:         * Try allocating a fast interrupt and the associated deferred
                   6090:         * processing contexts.
                   6091:         */
1.99      msaitoh  6092:        if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
                   6093:                txr->txr_si =
                   6094:                    softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   6095:                        ixgbe_deferred_mq_start, txr);
1.98      msaitoh  6096:        que->que_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   6097:            ixgbe_handle_que, que);
1.48      msaitoh  6098:
1.119     msaitoh  6099:        if ((!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)
                   6100:                & (txr->txr_si == NULL)) || (que->que_si == NULL)) {
1.98      msaitoh  6101:                aprint_error_dev(dev,
                   6102:                    "could not establish software interrupts\n");
1.99      msaitoh  6103:
1.98      msaitoh  6104:                return ENXIO;
                   6105:        }
                   6106:        /* For simplicity in the handlers */
                   6107:        adapter->active_queues = IXGBE_EIMS_ENABLE_MASK;
1.44      msaitoh  6108:
                   6109:        return (0);
1.99      msaitoh  6110: } /* ixgbe_allocate_legacy */
1.44      msaitoh  6111:
1.99      msaitoh  6112: /************************************************************************
                   6113:  * ixgbe_allocate_msix - Setup MSI-X Interrupt resources and handlers
                   6114:  ************************************************************************/
1.44      msaitoh  6115: static int
1.98      msaitoh  6116: ixgbe_allocate_msix(struct adapter *adapter, const struct pci_attach_args *pa)
1.44      msaitoh  6117: {
1.98      msaitoh  6118:        device_t        dev = adapter->dev;
                   6119:        struct          ix_queue *que = adapter->queues;
                   6120:        struct          tx_ring *txr = adapter->tx_rings;
                   6121:        pci_chipset_tag_t pc;
                   6122:        char            intrbuf[PCI_INTRSTR_LEN];
                   6123:        char            intr_xname[32];
1.128     knakahar 6124:        char            wqname[MAXCOMLEN];
1.98      msaitoh  6125:        const char      *intrstr = NULL;
                   6126:        int             error, vector = 0;
                   6127:        int             cpu_id = 0;
                   6128:        kcpuset_t       *affinity;
1.99      msaitoh  6129: #ifdef RSS
                   6130:        unsigned int    rss_buckets = 0;
                   6131:        kcpuset_t       cpu_mask;
1.98      msaitoh  6132: #endif
                   6133:
                   6134:        pc = adapter->osdep.pc;
                   6135: #ifdef RSS
                   6136:        /*
                   6137:         * If we're doing RSS, the number of queues needs to
                   6138:         * match the number of RSS buckets that are configured.
                   6139:         *
                   6140:         * + If there's more queues than RSS buckets, we'll end
                   6141:         *   up with queues that get no traffic.
                   6142:         *
                   6143:         * + If there's more RSS buckets than queues, we'll end
                   6144:         *   up having multiple RSS buckets map to the same queue,
                   6145:         *   so there'll be some contention.
                   6146:         */
1.99      msaitoh  6147:        rss_buckets = rss_getnumbuckets();
                   6148:        if ((adapter->feat_en & IXGBE_FEATURE_RSS) &&
                   6149:            (adapter->num_queues != rss_buckets)) {
1.98      msaitoh  6150:                device_printf(dev,
                   6151:                    "%s: number of queues (%d) != number of RSS buckets (%d)"
                   6152:                    "; performance will be impacted.\n",
1.99      msaitoh  6153:                    __func__, adapter->num_queues, rss_buckets);
1.98      msaitoh  6154:        }
                   6155: #endif
                   6156:
                   6157:        adapter->osdep.nintrs = adapter->num_queues + 1;
                   6158:        if (pci_msix_alloc_exact(pa, &adapter->osdep.intrs,
                   6159:            adapter->osdep.nintrs) != 0) {
                   6160:                aprint_error_dev(dev,
                   6161:                    "failed to allocate MSI-X interrupt\n");
                   6162:                return (ENXIO);
                   6163:        }
                   6164:
                   6165:        kcpuset_create(&affinity, false);
                   6166:        for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
                   6167:                snprintf(intr_xname, sizeof(intr_xname), "%s TXRX%d",
                   6168:                    device_xname(dev), i);
                   6169:                intrstr = pci_intr_string(pc, adapter->osdep.intrs[i], intrbuf,
                   6170:                    sizeof(intrbuf));
                   6171: #ifdef IXGBE_MPSAFE
                   6172:                pci_intr_setattr(pc, &adapter->osdep.intrs[i], PCI_INTR_MPSAFE,
                   6173:                    true);
                   6174: #endif
                   6175:                /* Set the handler function */
                   6176:                que->res = adapter->osdep.ihs[i] = pci_intr_establish_xname(pc,
                   6177:                    adapter->osdep.intrs[i], IPL_NET, ixgbe_msix_que, que,
                   6178:                    intr_xname);
                   6179:                if (que->res == NULL) {
                   6180:                        aprint_error_dev(dev,
                   6181:                            "Failed to register QUE handler\n");
1.119     msaitoh  6182:                        error = ENXIO;
                   6183:                        goto err_out;
1.98      msaitoh  6184:                }
                   6185:                que->msix = vector;
                   6186:                adapter->active_queues |= (u64)(1 << que->msix);
1.99      msaitoh  6187:
                   6188:                if (adapter->feat_en & IXGBE_FEATURE_RSS) {
1.98      msaitoh  6189: #ifdef RSS
1.99      msaitoh  6190:                        /*
                   6191:                         * The queue ID is used as the RSS layer bucket ID.
                   6192:                         * We look up the queue ID -> RSS CPU ID and select
                   6193:                         * that.
                   6194:                         */
                   6195:                        cpu_id = rss_getcpu(i % rss_getnumbuckets());
                   6196:                        CPU_SETOF(cpu_id, &cpu_mask);
1.98      msaitoh  6197: #endif
1.99      msaitoh  6198:                } else {
                   6199:                        /*
                   6200:                         * Bind the MSI-X vector, and thus the
                   6201:                         * rings to the corresponding CPU.
                   6202:                         *
                   6203:                         * This just happens to match the default RSS
                   6204:                         * round-robin bucket -> queue -> CPU allocation.
                   6205:                         */
                   6206:                        if (adapter->num_queues > 1)
                   6207:                                cpu_id = i;
                   6208:                }
1.98      msaitoh  6209:                /* Round-robin affinity */
                   6210:                kcpuset_zero(affinity);
                   6211:                kcpuset_set(affinity, cpu_id % ncpu);
                   6212:                error = interrupt_distribute(adapter->osdep.ihs[i], affinity,
                   6213:                    NULL);
                   6214:                aprint_normal_dev(dev, "for TX/RX, interrupting at %s",
                   6215:                    intrstr);
                   6216:                if (error == 0) {
                   6217: #if 1 /* def IXGBE_DEBUG */
                   6218: #ifdef RSS
1.99      msaitoh  6219:                        aprintf_normal(", bound RSS bucket %d to CPU %d", i,
                   6220:                            cpu_id % ncpu);
1.98      msaitoh  6221: #else
1.99      msaitoh  6222:                        aprint_normal(", bound queue %d to cpu %d", i,
                   6223:                            cpu_id % ncpu);
1.98      msaitoh  6224: #endif
                   6225: #endif /* IXGBE_DEBUG */
                   6226:                }
                   6227:                aprint_normal("\n");
1.99      msaitoh  6228:
1.119     msaitoh  6229:                if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) {
1.99      msaitoh  6230:                        txr->txr_si = softint_establish(
                   6231:                                SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   6232:                                ixgbe_deferred_mq_start, txr);
1.119     msaitoh  6233:                        if (txr->txr_si == NULL) {
                   6234:                                aprint_error_dev(dev,
                   6235:                                    "couldn't establish software interrupt\n");
                   6236:                                error = ENXIO;
                   6237:                                goto err_out;
                   6238:                        }
                   6239:                }
1.98      msaitoh  6240:                que->que_si
                   6241:                    = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   6242:                        ixgbe_handle_que, que);
                   6243:                if (que->que_si == NULL) {
                   6244:                        aprint_error_dev(dev,
1.119     msaitoh  6245:                            "couldn't establish software interrupt\n");
                   6246:                        error = ENXIO;
                   6247:                        goto err_out;
1.98      msaitoh  6248:                }
                   6249:        }
1.128     knakahar 6250:        snprintf(wqname, sizeof(wqname), "%sdeferTx", device_xname(dev));
                   6251:        error = workqueue_create(&adapter->txr_wq, wqname,
                   6252:            ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
                   6253:            IXGBE_WORKQUEUE_FLAGS);
                   6254:        if (error) {
                   6255:                aprint_error_dev(dev, "couldn't create workqueue for deferred Tx\n");
                   6256:                goto err_out;
                   6257:        }
                   6258:        adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
                   6259:
                   6260:        snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(dev));
                   6261:        error = workqueue_create(&adapter->que_wq, wqname,
                   6262:            ixgbe_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
                   6263:            IXGBE_WORKQUEUE_FLAGS);
                   6264:        if (error) {
                   6265:                aprint_error_dev(dev, "couldn't create workqueue for Tx/Rx\n");
                   6266:                goto err_out;
                   6267:        }
1.44      msaitoh  6268:
1.98      msaitoh  6269:        /* and Link */
                   6270:        cpu_id++;
                   6271:        snprintf(intr_xname, sizeof(intr_xname), "%s link", device_xname(dev));
1.117     msaitoh  6272:        adapter->vector = vector;
1.98      msaitoh  6273:        intrstr = pci_intr_string(pc, adapter->osdep.intrs[vector], intrbuf,
                   6274:            sizeof(intrbuf));
                   6275: #ifdef IXGBE_MPSAFE
                   6276:        pci_intr_setattr(pc, &adapter->osdep.intrs[vector], PCI_INTR_MPSAFE,
                   6277:            true);
                   6278: #endif
                   6279:        /* Set the link handler function */
                   6280:        adapter->osdep.ihs[vector] = pci_intr_establish_xname(pc,
                   6281:            adapter->osdep.intrs[vector], IPL_NET, ixgbe_msix_link, adapter,
                   6282:            intr_xname);
                   6283:        if (adapter->osdep.ihs[vector] == NULL) {
                   6284:                aprint_error_dev(dev, "Failed to register LINK handler\n");
1.119     msaitoh  6285:                error = ENXIO;
                   6286:                goto err_out;
1.98      msaitoh  6287:        }
                   6288:        /* Round-robin affinity */
                   6289:        kcpuset_zero(affinity);
                   6290:        kcpuset_set(affinity, cpu_id % ncpu);
1.119     msaitoh  6291:        error = interrupt_distribute(adapter->osdep.ihs[vector], affinity,
                   6292:            NULL);
1.44      msaitoh  6293:
1.98      msaitoh  6294:        aprint_normal_dev(dev,
                   6295:            "for link, interrupting at %s", intrstr);
                   6296:        if (error == 0)
                   6297:                aprint_normal(", affinity to cpu %d\n", cpu_id % ncpu);
1.44      msaitoh  6298:        else
1.98      msaitoh  6299:                aprint_normal("\n");
1.44      msaitoh  6300:
1.119     msaitoh  6301:        if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) {
1.99      msaitoh  6302:                adapter->mbx_si =
                   6303:                    softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
                   6304:                        ixgbe_handle_mbx, adapter);
1.119     msaitoh  6305:                if (adapter->mbx_si == NULL) {
                   6306:                        aprint_error_dev(dev,
                   6307:                            "could not establish software interrupts\n");
                   6308:
                   6309:                        error = ENXIO;
                   6310:                        goto err_out;
                   6311:                }
                   6312:        }
1.44      msaitoh  6313:
1.98      msaitoh  6314:        kcpuset_destroy(affinity);
1.119     msaitoh  6315:        aprint_normal_dev(dev,
                   6316:            "Using MSI-X interrupts with %d vectors\n", vector + 1);
1.99      msaitoh  6317:
1.44      msaitoh  6318:        return (0);
1.119     msaitoh  6319:
                   6320: err_out:
                   6321:        kcpuset_destroy(affinity);
                   6322:        ixgbe_free_softint(adapter);
                   6323:        ixgbe_free_pciintr_resources(adapter);
                   6324:        return (error);
1.99      msaitoh  6325: } /* ixgbe_allocate_msix */
1.44      msaitoh  6326:
1.99      msaitoh  6327: /************************************************************************
                   6328:  * ixgbe_configure_interrupts
                   6329:  *
                   6330:  *   Setup MSI-X, MSI, or legacy interrupts (in that order).
                   6331:  *   This will also depend on user settings.
                   6332:  ************************************************************************/
1.44      msaitoh  6333: static int
1.99      msaitoh  6334: ixgbe_configure_interrupts(struct adapter *adapter)
1.44      msaitoh  6335: {
1.98      msaitoh  6336:        device_t dev = adapter->dev;
                   6337:        struct ixgbe_mac_info *mac = &adapter->hw.mac;
                   6338:        int want, queues, msgs;
1.44      msaitoh  6339:
1.99      msaitoh  6340:        /* Default to 1 queue if MSI-X setup fails */
                   6341:        adapter->num_queues = 1;
                   6342:
1.98      msaitoh  6343:        /* Override by tuneable */
1.99      msaitoh  6344:        if (!(adapter->feat_cap & IXGBE_FEATURE_MSIX))
1.98      msaitoh  6345:                goto msi;
1.44      msaitoh  6346:
1.118     msaitoh  6347:        /*
                   6348:         *  NetBSD only: Use single vector MSI when number of CPU is 1 to save
                   6349:         * interrupt slot.
                   6350:         */
                   6351:        if (ncpu == 1)
                   6352:                goto msi;
                   6353:
1.99      msaitoh  6354:        /* First try MSI-X */
1.98      msaitoh  6355:        msgs = pci_msix_count(adapter->osdep.pc, adapter->osdep.tag);
                   6356:        msgs = MIN(msgs, IXG_MAX_NINTR);
                   6357:        if (msgs < 2)
                   6358:                goto msi;
1.44      msaitoh  6359:
1.98      msaitoh  6360:        adapter->msix_mem = (void *)1; /* XXX */
1.44      msaitoh  6361:
1.98      msaitoh  6362:        /* Figure out a reasonable auto config value */
                   6363:        queues = (ncpu > (msgs - 1)) ? (msgs - 1) : ncpu;
1.44      msaitoh  6364:
1.98      msaitoh  6365: #ifdef RSS
                   6366:        /* If we're doing RSS, clamp at the number of RSS buckets */
1.99      msaitoh  6367:        if (adapter->feat_en & IXGBE_FEATURE_RSS)
                   6368:                queues = min(queues, rss_getnumbuckets());
1.98      msaitoh  6369: #endif
1.99      msaitoh  6370:        if (ixgbe_num_queues > queues) {
                   6371:                aprint_error_dev(adapter->dev, "ixgbe_num_queues (%d) is too large, using reduced amount (%d).\n", ixgbe_num_queues, queues);
                   6372:                ixgbe_num_queues = queues;
                   6373:        }
1.44      msaitoh  6374:
1.98      msaitoh  6375:        if (ixgbe_num_queues != 0)
                   6376:                queues = ixgbe_num_queues;
                   6377:        else
                   6378:                queues = min(queues,
                   6379:                    min(mac->max_tx_queues, mac->max_rx_queues));
1.44      msaitoh  6380:
1.98      msaitoh  6381:        /* reflect correct sysctl value */
                   6382:        ixgbe_num_queues = queues;
1.44      msaitoh  6383:
1.98      msaitoh  6384:        /*
1.99      msaitoh  6385:         * Want one vector (RX/TX pair) per queue
                   6386:         * plus an additional for Link.
                   6387:         */
1.98      msaitoh  6388:        want = queues + 1;
                   6389:        if (msgs >= want)
                   6390:                msgs = want;
1.44      msaitoh  6391:        else {
1.99      msaitoh  6392:                        aprint_error_dev(dev, "MSI-X Configuration Problem, "
1.98      msaitoh  6393:                    "%d vectors but %d queues wanted!\n",
                   6394:                    msgs, want);
                   6395:                goto msi;
1.44      msaitoh  6396:        }
1.98      msaitoh  6397:        adapter->num_queues = queues;
1.99      msaitoh  6398:        adapter->feat_en |= IXGBE_FEATURE_MSIX;
                   6399:        return (0);
1.44      msaitoh  6400:
1.98      msaitoh  6401:        /*
1.99      msaitoh  6402:         * MSI-X allocation failed or provided us with
                   6403:         * less vectors than needed. Free MSI-X resources
                   6404:         * and we'll try enabling MSI.
                   6405:         */
1.98      msaitoh  6406: msi:
1.99      msaitoh  6407:        /* Without MSI-X, some features are no longer supported */
                   6408:        adapter->feat_cap &= ~IXGBE_FEATURE_RSS;
                   6409:        adapter->feat_en  &= ~IXGBE_FEATURE_RSS;
                   6410:        adapter->feat_cap &= ~IXGBE_FEATURE_SRIOV;
                   6411:        adapter->feat_en  &= ~IXGBE_FEATURE_SRIOV;
                   6412:
1.98      msaitoh  6413:                msgs = pci_msi_count(adapter->osdep.pc, adapter->osdep.tag);
                   6414:        adapter->msix_mem = NULL; /* XXX */
1.99      msaitoh  6415:        if (msgs > 1)
                   6416:                msgs = 1;
                   6417:        if (msgs != 0) {
                   6418:                msgs = 1;
                   6419:                adapter->feat_en |= IXGBE_FEATURE_MSI;
                   6420:                return (0);
                   6421:        }
                   6422:
                   6423:        if (!(adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ)) {
                   6424:                aprint_error_dev(dev,
                   6425:                    "Device does not support legacy interrupts.\n");
                   6426:                return 1;
                   6427:        }
                   6428:
                   6429:        adapter->feat_en |= IXGBE_FEATURE_LEGACY_IRQ;
                   6430:
                   6431:        return (0);
                   6432: } /* ixgbe_configure_interrupts */
1.44      msaitoh  6433:
1.48      msaitoh  6434:
1.99      msaitoh  6435: /************************************************************************
                   6436:  * ixgbe_handle_link - Tasklet for MSI-X Link interrupts
                   6437:  *
                   6438:  *   Done outside of interrupt context since the driver might sleep
                   6439:  ************************************************************************/
1.26      msaitoh  6440: static void
1.98      msaitoh  6441: ixgbe_handle_link(void *context)
1.26      msaitoh  6442: {
1.98      msaitoh  6443:        struct adapter  *adapter = context;
                   6444:        struct ixgbe_hw *hw = &adapter->hw;
1.26      msaitoh  6445:
1.136     knakahar 6446:        IXGBE_CORE_LOCK(adapter);
1.137     msaitoh  6447:        ++adapter->link_sicount.ev_count;
1.99      msaitoh  6448:        ixgbe_check_link(hw, &adapter->link_speed, &adapter->link_up, 0);
1.98      msaitoh  6449:        ixgbe_update_link_status(adapter);
1.26      msaitoh  6450:
1.98      msaitoh  6451:        /* Re-enable link interrupts */
                   6452:        IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_LSC);
1.136     knakahar 6453:
                   6454:        IXGBE_CORE_UNLOCK(adapter);
1.99      msaitoh  6455: } /* ixgbe_handle_link */
1.45      msaitoh  6456:
1.99      msaitoh  6457: /************************************************************************
                   6458:  * ixgbe_rearm_queues
                   6459:  ************************************************************************/
1.63      msaitoh  6460: static void
                   6461: ixgbe_rearm_queues(struct adapter *adapter, u64 queues)
                   6462: {
                   6463:        u32 mask;
                   6464:
                   6465:        switch (adapter->hw.mac.type) {
                   6466:        case ixgbe_mac_82598EB:
                   6467:                mask = (IXGBE_EIMS_RTX_QUEUE & queues);
                   6468:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
                   6469:                break;
                   6470:        case ixgbe_mac_82599EB:
                   6471:        case ixgbe_mac_X540:
                   6472:        case ixgbe_mac_X550:
                   6473:        case ixgbe_mac_X550EM_x:
1.99      msaitoh  6474:        case ixgbe_mac_X550EM_a:
1.63      msaitoh  6475:                mask = (queues & 0xFFFFFFFF);
                   6476:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
                   6477:                mask = (queues >> 32);
                   6478:                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask);
                   6479:                break;
                   6480:        default:
                   6481:                break;
                   6482:        }
1.99      msaitoh  6483: } /* ixgbe_rearm_queues */

CVSweb <webmaster@jp.NetBSD.org>