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