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