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

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

CVSweb <webmaster@jp.NetBSD.org>