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, ®)) {
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, ®)) {
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>