Annotation of src/sys/dev/pci/ixgbe/ixv.c, Revision 1.120
1.120 ! msaitoh 1: /*$NetBSD: ixv.c,v 1.119 2019/07/17 03:09:16 msaitoh Exp $*/
1.58 msaitoh 2:
1.1 dyoung 3: /******************************************************************************
4:
1.58 msaitoh 5: Copyright (c) 2001-2017, Intel Corporation
1.1 dyoung 6: All rights reserved.
1.58 msaitoh 7:
8: Redistribution and use in source and binary forms, with or without
1.1 dyoung 9: modification, are permitted provided that the following conditions are met:
1.58 msaitoh 10:
11: 1. Redistributions of source code must retain the above copyright notice,
1.1 dyoung 12: this list of conditions and the following disclaimer.
1.58 msaitoh 13:
14: 2. Redistributions in binary form must reproduce the above copyright
15: notice, this list of conditions and the following disclaimer in the
1.1 dyoung 16: documentation and/or other materials provided with the distribution.
1.58 msaitoh 17:
18: 3. Neither the name of the Intel Corporation nor the names of its
19: contributors may be used to endorse or promote products derived from
1.1 dyoung 20: this software without specific prior written permission.
1.58 msaitoh 21:
1.1 dyoung 22: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1.58 msaitoh 23: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.1 dyoung 31: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32: POSSIBILITY OF SUCH DAMAGE.
33:
34: ******************************************************************************/
1.92 msaitoh 35: /*$FreeBSD: head/sys/dev/ixgbe/if_ixv.c 331224 2018-03-19 20:55:05Z erj $*/
1.1 dyoung 36:
1.55 msaitoh 37: #ifdef _KERNEL_OPT
1.1 dyoung 38: #include "opt_inet.h"
1.4 msaitoh 39: #include "opt_inet6.h"
1.55 msaitoh 40: #include "opt_net_mpsafe.h"
41: #endif
1.1 dyoung 42:
1.21 msaitoh 43: #include "ixgbe.h"
1.13 msaitoh 44: #include "vlan.h"
1.1 dyoung 45:
1.58 msaitoh 46: /************************************************************************
47: * Driver version
48: ************************************************************************/
1.103 maxv 49: static const char ixv_driver_version[] = "2.0.1-k";
1.117 msaitoh 50: /* XXX NetBSD: + 1.5.17 */
1.58 msaitoh 51:
52: /************************************************************************
53: * PCI Device ID Table
54: *
55: * Used by probe to select devices to load on
56: * Last field stores an index into ixv_strings
57: * Last entry must be all 0s
1.1 dyoung 58: *
1.58 msaitoh 59: * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
60: ************************************************************************/
1.103 maxv 61: static const ixgbe_vendor_info_t ixv_vendor_info_array[] =
1.1 dyoung 62: {
63: {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0},
1.5 msaitoh 64: {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0},
1.21 msaitoh 65: {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0},
66: {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0},
1.58 msaitoh 67: {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF, 0, 0, 0},
1.1 dyoung 68: /* required last entry */
69: {0, 0, 0, 0, 0}
70: };
71:
1.58 msaitoh 72: /************************************************************************
73: * Table of branding strings
74: ************************************************************************/
75: static const char *ixv_strings[] = {
1.1 dyoung 76: "Intel(R) PRO/10GbE Virtual Function Network Driver"
77: };
78:
79: /*********************************************************************
80: * Function prototypes
81: *********************************************************************/
1.114 msaitoh 82: static int ixv_probe(device_t, cfdata_t, void *);
1.22 msaitoh 83: static void ixv_attach(device_t, device_t, void *);
1.114 msaitoh 84: static int ixv_detach(device_t, int);
1.3 msaitoh 85: #if 0
1.114 msaitoh 86: static int ixv_shutdown(device_t);
1.3 msaitoh 87: #endif
1.57 msaitoh 88: static int ixv_ifflags_cb(struct ethercom *);
1.114 msaitoh 89: static int ixv_ioctl(struct ifnet *, u_long, void *);
1.3 msaitoh 90: static int ixv_init(struct ifnet *);
1.1 dyoung 91: static void ixv_init_locked(struct adapter *);
1.56 msaitoh 92: static void ixv_ifstop(struct ifnet *, int);
1.114 msaitoh 93: static void ixv_stop(void *);
94: static void ixv_init_device_features(struct adapter *);
95: static void ixv_media_status(struct ifnet *, struct ifmediareq *);
96: static int ixv_media_change(struct ifnet *);
97: static int ixv_allocate_pci_resources(struct adapter *,
1.3 msaitoh 98: const struct pci_attach_args *);
1.114 msaitoh 99: static int ixv_allocate_msix(struct adapter *,
1.11 msaitoh 100: const struct pci_attach_args *);
1.114 msaitoh 101: static int ixv_configure_interrupts(struct adapter *);
1.1 dyoung 102: static void ixv_free_pci_resources(struct adapter *);
1.114 msaitoh 103: static void ixv_local_timer(void *);
104: static void ixv_local_timer_locked(void *);
105: static int ixv_setup_interface(device_t, struct adapter *);
106: static int ixv_negotiate_api(struct adapter *);
107:
108: static void ixv_initialize_transmit_units(struct adapter *);
109: static void ixv_initialize_receive_units(struct adapter *);
110: static void ixv_initialize_rss_mapping(struct adapter *);
1.117 msaitoh 111: static s32 ixv_check_link(struct adapter *);
1.114 msaitoh 112:
113: static void ixv_enable_intr(struct adapter *);
114: static void ixv_disable_intr(struct adapter *);
115: static void ixv_set_multi(struct adapter *);
116: static void ixv_update_link_status(struct adapter *);
1.3 msaitoh 117: static int ixv_sysctl_debug(SYSCTLFN_PROTO);
1.1 dyoung 118: static void ixv_set_ivar(struct adapter *, u8, u8, s8);
119: static void ixv_configure_ivars(struct adapter *);
120: static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
1.95 msaitoh 121: static void ixv_eitr_write(struct adapter *, uint32_t, uint32_t);
1.1 dyoung 122:
1.120 ! msaitoh 123: static int ixv_setup_vlan_support(struct adapter *);
! 124: static int ixv_vlan_cb(struct ethercom *, uint16_t, bool);
! 125: static int ixv_register_vlan(void *, struct ifnet *, u16);
! 126: static int ixv_unregister_vlan(void *, struct ifnet *, u16);
1.1 dyoung 127:
1.48 msaitoh 128: static void ixv_add_device_sysctls(struct adapter *);
1.1 dyoung 129: static void ixv_save_stats(struct adapter *);
130: static void ixv_init_stats(struct adapter *);
131: static void ixv_update_stats(struct adapter *);
1.21 msaitoh 132: static void ixv_add_stats_sysctls(struct adapter *);
1.83 msaitoh 133:
134: /* Sysctl handlers */
1.25 msaitoh 135: static void ixv_set_sysctl_value(struct adapter *, const char *,
136: const char *, int *, int);
1.114 msaitoh 137: static int ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
138: static int ixv_sysctl_next_to_check_handler(SYSCTLFN_PROTO);
139: static int ixv_sysctl_rdh_handler(SYSCTLFN_PROTO);
140: static int ixv_sysctl_rdt_handler(SYSCTLFN_PROTO);
141: static int ixv_sysctl_tdt_handler(SYSCTLFN_PROTO);
142: static int ixv_sysctl_tdh_handler(SYSCTLFN_PROTO);
1.1 dyoung 143:
1.58 msaitoh 144: /* The MSI-X Interrupt handlers */
1.11 msaitoh 145: static int ixv_msix_que(void *);
146: static int ixv_msix_mbx(void *);
1.1 dyoung 147:
148: /* Deferred interrupt tasklets */
1.3 msaitoh 149: static void ixv_handle_que(void *);
1.114 msaitoh 150: static void ixv_handle_link(void *);
1.3 msaitoh 151:
1.84 knakahar 152: /* Workqueue handler for deferred work */
153: static void ixv_handle_que_work(struct work *, void *);
154:
1.3 msaitoh 155: const struct sysctlnode *ixv_sysctl_instance(struct adapter *);
1.103 maxv 156: static const ixgbe_vendor_info_t *ixv_lookup(const struct pci_attach_args *);
1.1 dyoung 157:
1.58 msaitoh 158: /************************************************************************
159: * FreeBSD Device Interface Entry Points
160: ************************************************************************/
1.3 msaitoh 161: CFATTACH_DECL3_NEW(ixv, sizeof(struct adapter),
162: ixv_probe, ixv_attach, ixv_detach, NULL, NULL, NULL,
163: DVF_DETACH_SHUTDOWN);
164:
1.1 dyoung 165: #if 0
166: static driver_t ixv_driver = {
1.21 msaitoh 167: "ixv", ixv_methods, sizeof(struct adapter),
1.1 dyoung 168: };
169:
1.22 msaitoh 170: devclass_t ixv_devclass;
171: DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0);
1.1 dyoung 172: MODULE_DEPEND(ixv, pci, 1, 1, 1);
173: MODULE_DEPEND(ixv, ether, 1, 1, 1);
174: #endif
175:
176: /*
1.58 msaitoh 177: * TUNEABLE PARAMETERS:
178: */
1.1 dyoung 179:
1.58 msaitoh 180: /* Number of Queues - do not exceed MSI-X vectors - 1 */
1.44 msaitoh 181: static int ixv_num_queues = 0;
1.23 msaitoh 182: #define TUNABLE_INT(__x, __y)
183: TUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues);
184:
1.1 dyoung 185: /*
1.58 msaitoh 186: * AIM: Adaptive Interrupt Moderation
187: * which means that the interrupt rate
188: * is varied over time based on the
189: * traffic for that interrupt vector
190: */
1.50 msaitoh 191: static bool ixv_enable_aim = false;
1.1 dyoung 192: TUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim);
193:
1.83 msaitoh 194: static int ixv_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY);
195: TUNABLE_INT("hw.ixv.max_interrupt_rate", &ixv_max_interrupt_rate);
196:
1.1 dyoung 197: /* How many packets rxeof tries to clean at a time */
1.21 msaitoh 198: static int ixv_rx_process_limit = 256;
1.1 dyoung 199: TUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit);
200:
1.21 msaitoh 201: /* How many packets txeof tries to clean at a time */
202: static int ixv_tx_process_limit = 256;
203: TUNABLE_INT("hw.ixv.tx_process_limit", &ixv_tx_process_limit);
1.1 dyoung 204:
1.112 msaitoh 205: /* Which packet processing uses workqueue or softint */
1.84 knakahar 206: static bool ixv_txrx_workqueue = false;
207:
1.1 dyoung 208: /*
1.58 msaitoh 209: * Number of TX descriptors per ring,
210: * setting higher than RX as this seems
211: * the better performing choice.
212: */
1.64 msaitoh 213: static int ixv_txd = PERFORM_TXD;
1.1 dyoung 214: TUNABLE_INT("hw.ixv.txd", &ixv_txd);
215:
216: /* Number of RX descriptors per ring */
1.64 msaitoh 217: static int ixv_rxd = PERFORM_RXD;
1.1 dyoung 218: TUNABLE_INT("hw.ixv.rxd", &ixv_rxd);
219:
1.58 msaitoh 220: /* Legacy Transmit (single queue) */
221: static int ixv_enable_legacy_tx = 0;
222: TUNABLE_INT("hw.ixv.enable_legacy_tx", &ixv_enable_legacy_tx);
223:
1.55 msaitoh 224: #ifdef NET_MPSAFE
225: #define IXGBE_MPSAFE 1
226: #define IXGBE_CALLOUT_FLAGS CALLOUT_MPSAFE
227: #define IXGBE_SOFTINFT_FLAGS SOFTINT_MPSAFE
1.84 knakahar 228: #define IXGBE_WORKQUEUE_FLAGS WQ_PERCPU | WQ_MPSAFE
1.55 msaitoh 229: #else
230: #define IXGBE_CALLOUT_FLAGS 0
231: #define IXGBE_SOFTINFT_FLAGS 0
1.84 knakahar 232: #define IXGBE_WORKQUEUE_FLAGS WQ_PERCPU
1.55 msaitoh 233: #endif
1.84 knakahar 234: #define IXGBE_WORKQUEUE_PRI PRI_SOFTNET
1.55 msaitoh 235:
1.58 msaitoh 236: #if 0
237: static int (*ixv_start_locked)(struct ifnet *, struct tx_ring *);
238: static int (*ixv_ring_empty)(struct ifnet *, struct buf_ring *);
239: #endif
240:
241: /************************************************************************
242: * ixv_probe - Device identification routine
1.1 dyoung 243: *
1.58 msaitoh 244: * Determines if the driver should be loaded on
245: * adapter based on its PCI vendor/device ID.
1.1 dyoung 246: *
1.58 msaitoh 247: * return BUS_PROBE_DEFAULT on success, positive on failure
248: ************************************************************************/
1.1 dyoung 249: static int
1.3 msaitoh 250: ixv_probe(device_t dev, cfdata_t cf, void *aux)
251: {
1.19 knakahar 252: #ifdef __HAVE_PCI_MSI_MSIX
1.3 msaitoh 253: const struct pci_attach_args *pa = aux;
254:
255: return (ixv_lookup(pa) != NULL) ? 1 : 0;
1.18 msaitoh 256: #else
257: return 0;
258: #endif
1.58 msaitoh 259: } /* ixv_probe */
1.3 msaitoh 260:
1.103 maxv 261: static const ixgbe_vendor_info_t *
1.3 msaitoh 262: ixv_lookup(const struct pci_attach_args *pa)
1.1 dyoung 263: {
1.103 maxv 264: const ixgbe_vendor_info_t *ent;
1.3 msaitoh 265: pcireg_t subid;
1.1 dyoung 266:
1.31 msaitoh 267: INIT_DEBUGOUT("ixv_lookup: begin");
1.1 dyoung 268:
1.3 msaitoh 269: if (PCI_VENDOR(pa->pa_id) != IXGBE_INTEL_VENDOR_ID)
270: return NULL;
1.1 dyoung 271:
1.3 msaitoh 272: subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
1.1 dyoung 273:
1.3 msaitoh 274: for (ent = ixv_vendor_info_array; ent->vendor_id != 0; ent++) {
275: if ((PCI_VENDOR(pa->pa_id) == ent->vendor_id) &&
276: (PCI_PRODUCT(pa->pa_id) == ent->device_id) &&
277: ((PCI_SUBSYS_VENDOR(subid) == ent->subvendor_id) ||
1.1 dyoung 278: (ent->subvendor_id == 0)) &&
1.3 msaitoh 279: ((PCI_SUBSYS_ID(subid) == ent->subdevice_id) ||
1.1 dyoung 280: (ent->subdevice_id == 0))) {
1.3 msaitoh 281: return ent;
1.1 dyoung 282: }
283: }
1.58 msaitoh 284:
1.3 msaitoh 285: return NULL;
286: }
287:
1.58 msaitoh 288: /************************************************************************
289: * ixv_attach - Device initialization routine
1.57 msaitoh 290: *
1.58 msaitoh 291: * Called when the driver is being loaded.
292: * Identifies the type of hardware, allocates all resources
293: * and initializes the hardware.
1.57 msaitoh 294: *
1.58 msaitoh 295: * return 0 on success, positive on failure
296: ************************************************************************/
1.3 msaitoh 297: static void
298: ixv_attach(device_t parent, device_t dev, void *aux)
1.1 dyoung 299: {
300: struct adapter *adapter;
301: struct ixgbe_hw *hw;
1.114 msaitoh 302: int error = 0;
1.58 msaitoh 303: pcireg_t id, subid;
1.103 maxv 304: const ixgbe_vendor_info_t *ent;
1.3 msaitoh 305: const struct pci_attach_args *pa = aux;
1.60 msaitoh 306: const char *apivstr;
1.66 msaitoh 307: const char *str;
1.63 msaitoh 308: char buf[256];
309:
1.1 dyoung 310: INIT_DEBUGOUT("ixv_attach: begin");
311:
1.58 msaitoh 312: /*
313: * Make sure BUSMASTER is set, on a VM under
314: * KVM it may not be and will break things.
315: */
316: ixgbe_pci_enable_busmaster(pa->pa_pc, pa->pa_tag);
317:
1.1 dyoung 318: /* Allocate, clear, and link in our adapter structure */
1.3 msaitoh 319: adapter = device_private(dev);
1.26 msaitoh 320: adapter->dev = dev;
1.58 msaitoh 321: adapter->hw.back = adapter;
1.1 dyoung 322: hw = &adapter->hw;
1.26 msaitoh 323:
324: adapter->init_locked = ixv_init_locked;
325: adapter->stop_locked = ixv_stop;
326:
1.13 msaitoh 327: adapter->osdep.pc = pa->pa_pc;
328: adapter->osdep.tag = pa->pa_tag;
1.43 msaitoh 329: if (pci_dma64_available(pa))
330: adapter->osdep.dmat = pa->pa_dmat64;
331: else
332: adapter->osdep.dmat = pa->pa_dmat;
1.13 msaitoh 333: adapter->osdep.attached = false;
1.1 dyoung 334:
1.3 msaitoh 335: ent = ixv_lookup(pa);
336:
337: KASSERT(ent != NULL);
338:
339: aprint_normal(": %s, Version - %s\n",
340: ixv_strings[ent->index], ixv_driver_version);
341:
1.1 dyoung 342: /* Core Lock Init*/
1.21 msaitoh 343: IXGBE_CORE_LOCK_INIT(adapter, device_xname(dev));
1.1 dyoung 344:
345: /* Do base PCI setup - map BAR0 */
1.3 msaitoh 346: if (ixv_allocate_pci_resources(adapter, pa)) {
1.26 msaitoh 347: aprint_error_dev(dev, "ixv_allocate_pci_resources() failed!\n");
1.1 dyoung 348: error = ENXIO;
349: goto err_out;
350: }
351:
1.58 msaitoh 352: /* SYSCTL APIs */
353: ixv_add_device_sysctls(adapter);
1.25 msaitoh 354:
1.58 msaitoh 355: /* Set up the timer callout */
356: callout_init(&adapter->timer, IXGBE_CALLOUT_FLAGS);
1.25 msaitoh 357:
1.58 msaitoh 358: /* Save off the information about this board */
359: id = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
360: subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
361: hw->vendor_id = PCI_VENDOR(id);
362: hw->device_id = PCI_PRODUCT(id);
363: hw->revision_id =
364: PCI_REVISION(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG));
365: hw->subsystem_vendor_id = PCI_SUBSYS_VENDOR(subid);
366: hw->subsystem_device_id = PCI_SUBSYS_ID(subid);
1.1 dyoung 367:
1.58 msaitoh 368: /* A subset of set_mac_type */
369: switch (hw->device_id) {
370: case IXGBE_DEV_ID_82599_VF:
371: hw->mac.type = ixgbe_mac_82599_vf;
1.66 msaitoh 372: str = "82599 VF";
1.58 msaitoh 373: break;
374: case IXGBE_DEV_ID_X540_VF:
375: hw->mac.type = ixgbe_mac_X540_vf;
1.66 msaitoh 376: str = "X540 VF";
1.58 msaitoh 377: break;
378: case IXGBE_DEV_ID_X550_VF:
379: hw->mac.type = ixgbe_mac_X550_vf;
1.66 msaitoh 380: str = "X550 VF";
1.58 msaitoh 381: break;
382: case IXGBE_DEV_ID_X550EM_X_VF:
383: hw->mac.type = ixgbe_mac_X550EM_x_vf;
1.66 msaitoh 384: str = "X550EM X VF";
1.58 msaitoh 385: break;
386: case IXGBE_DEV_ID_X550EM_A_VF:
387: hw->mac.type = ixgbe_mac_X550EM_a_vf;
1.66 msaitoh 388: str = "X550EM A VF";
1.58 msaitoh 389: break;
390: default:
391: /* Shouldn't get here since probe succeeded */
392: aprint_error_dev(dev, "Unknown device ID!\n");
393: error = ENXIO;
1.1 dyoung 394: goto err_out;
1.58 msaitoh 395: break;
1.1 dyoung 396: }
1.66 msaitoh 397: aprint_normal_dev(dev, "device %s\n", str);
1.1 dyoung 398:
1.58 msaitoh 399: ixv_init_device_features(adapter);
400:
401: /* Initialize the shared code */
402: error = ixgbe_init_ops_vf(hw);
1.1 dyoung 403: if (error) {
1.58 msaitoh 404: aprint_error_dev(dev, "ixgbe_init_ops_vf() failed!\n");
1.1 dyoung 405: error = EIO;
1.58 msaitoh 406: goto err_out;
1.1 dyoung 407: }
408:
409: /* Setup the mailbox */
410: ixgbe_init_mbx_params_vf(hw);
411:
1.58 msaitoh 412: /* Set the right number of segments */
413: adapter->num_segs = IXGBE_82599_SCATTER;
414:
1.26 msaitoh 415: /* Reset mbox api to 1.0 */
1.58 msaitoh 416: error = hw->mac.ops.reset_hw(hw);
1.26 msaitoh 417: if (error == IXGBE_ERR_RESET_FAILED)
1.58 msaitoh 418: aprint_error_dev(dev, "...reset_hw() failure: Reset Failed!\n");
1.26 msaitoh 419: else if (error)
1.58 msaitoh 420: aprint_error_dev(dev, "...reset_hw() failed with error %d\n",
421: error);
1.26 msaitoh 422: if (error) {
423: error = EIO;
1.58 msaitoh 424: goto err_out;
1.26 msaitoh 425: }
1.1 dyoung 426:
1.58 msaitoh 427: error = hw->mac.ops.init_hw(hw);
1.1 dyoung 428: if (error) {
1.58 msaitoh 429: aprint_error_dev(dev, "...init_hw() failed!\n");
1.1 dyoung 430: error = EIO;
1.58 msaitoh 431: goto err_out;
1.1 dyoung 432: }
1.63 msaitoh 433:
1.58 msaitoh 434: /* Negotiate mailbox API version */
435: error = ixv_negotiate_api(adapter);
436: if (error)
437: aprint_normal_dev(dev,
438: "MBX API negotiation failed during attach!\n");
1.60 msaitoh 439: switch (hw->api_version) {
440: case ixgbe_mbox_api_10:
441: apivstr = "1.0";
442: break;
443: case ixgbe_mbox_api_20:
444: apivstr = "2.0";
445: break;
446: case ixgbe_mbox_api_11:
447: apivstr = "1.1";
448: break;
449: case ixgbe_mbox_api_12:
450: apivstr = "1.2";
451: break;
452: case ixgbe_mbox_api_13:
453: apivstr = "1.3";
454: break;
455: default:
456: apivstr = "unknown";
457: break;
458: }
459: aprint_normal_dev(dev, "Mailbox API %s\n", apivstr);
1.1 dyoung 460:
1.21 msaitoh 461: /* If no mac address was assigned, make a random one */
462: if (!ixv_check_ether_addr(hw->mac.addr)) {
463: u8 addr[ETHER_ADDR_LEN];
1.59 msaitoh 464: uint64_t rndval = cprng_strong64();
1.21 msaitoh 465:
466: memcpy(addr, &rndval, sizeof(addr));
467: addr[0] &= 0xFE;
468: addr[0] |= 0x02;
469: bcopy(addr, hw->mac.addr, sizeof(addr));
470: }
471:
1.58 msaitoh 472: /* Register for VLAN events */
1.120 ! msaitoh 473: ether_set_vlan_cb(&adapter->osdep.ec, ixv_vlan_cb);
1.58 msaitoh 474:
475: /* Sysctls for limiting the amount of work done in the taskqueues */
476: ixv_set_sysctl_value(adapter, "rx_processing_limit",
477: "max number of rx packets to process",
478: &adapter->rx_process_limit, ixv_rx_process_limit);
479:
480: ixv_set_sysctl_value(adapter, "tx_processing_limit",
481: "max number of tx packets to process",
482: &adapter->tx_process_limit, ixv_tx_process_limit);
483:
484: /* Do descriptor calc and sanity checks */
485: if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
486: ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) {
487: aprint_error_dev(dev, "TXD config issue, using default!\n");
488: adapter->num_tx_desc = DEFAULT_TXD;
489: } else
490: adapter->num_tx_desc = ixv_txd;
491:
492: if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 ||
493: ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) {
494: aprint_error_dev(dev, "RXD config issue, using default!\n");
495: adapter->num_rx_desc = DEFAULT_RXD;
496: } else
497: adapter->num_rx_desc = ixv_rxd;
498:
499: /* Setup MSI-X */
1.63 msaitoh 500: error = ixv_configure_interrupts(adapter);
1.58 msaitoh 501: if (error)
502: goto err_out;
503:
504: /* Allocate our TX/RX Queues */
505: if (ixgbe_allocate_queues(adapter)) {
506: aprint_error_dev(dev, "ixgbe_allocate_queues() failed!\n");
507: error = ENOMEM;
508: goto err_out;
509: }
510:
1.50 msaitoh 511: /* hw.ix defaults init */
512: adapter->enable_aim = ixv_enable_aim;
513:
1.84 knakahar 514: adapter->txrx_use_workqueue = ixv_txrx_workqueue;
515:
1.76 msaitoh 516: error = ixv_allocate_msix(adapter, pa);
517: if (error) {
518: device_printf(dev, "ixv_allocate_msix() failed!\n");
519: goto err_late;
520: }
521:
1.1 dyoung 522: /* Setup OS specific network interface */
1.73 msaitoh 523: error = ixv_setup_interface(dev, adapter);
524: if (error != 0) {
525: aprint_error_dev(dev, "ixv_setup_interface() failed!\n");
526: goto err_late;
527: }
1.1 dyoung 528:
529: /* Do the stats setup */
530: ixv_save_stats(adapter);
531: ixv_init_stats(adapter);
1.58 msaitoh 532: ixv_add_stats_sysctls(adapter);
1.1 dyoung 533:
1.58 msaitoh 534: if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
535: ixgbe_netmap_attach(adapter);
1.48 msaitoh 536:
1.63 msaitoh 537: snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_cap);
538: aprint_verbose_dev(dev, "feature cap %s\n", buf);
539: snprintb(buf, sizeof(buf), IXGBE_FEATURE_FLAGS, adapter->feat_en);
540: aprint_verbose_dev(dev, "feature ena %s\n", buf);
541:
1.1 dyoung 542: INIT_DEBUGOUT("ixv_attach: end");
1.13 msaitoh 543: adapter->osdep.attached = true;
1.57 msaitoh 544:
1.3 msaitoh 545: return;
1.1 dyoung 546:
547: err_late:
1.21 msaitoh 548: ixgbe_free_transmit_structures(adapter);
549: ixgbe_free_receive_structures(adapter);
1.58 msaitoh 550: free(adapter->queues, M_DEVBUF);
1.1 dyoung 551: err_out:
552: ixv_free_pci_resources(adapter);
1.58 msaitoh 553: IXGBE_CORE_LOCK_DESTROY(adapter);
554:
1.3 msaitoh 555: return;
1.58 msaitoh 556: } /* ixv_attach */
1.1 dyoung 557:
1.58 msaitoh 558: /************************************************************************
559: * ixv_detach - Device removal routine
1.1 dyoung 560: *
1.58 msaitoh 561: * Called when the driver is being removed.
562: * Stops the adapter and deallocates all the resources
563: * that were allocated for driver operation.
1.1 dyoung 564: *
1.58 msaitoh 565: * return 0 on success, positive on failure
566: ************************************************************************/
1.1 dyoung 567: static int
1.3 msaitoh 568: ixv_detach(device_t dev, int flags)
1.1 dyoung 569: {
1.114 msaitoh 570: struct adapter *adapter = device_private(dev);
1.67 msaitoh 571: struct ixgbe_hw *hw = &adapter->hw;
1.1 dyoung 572: struct ix_queue *que = adapter->queues;
1.41 msaitoh 573: struct tx_ring *txr = adapter->tx_rings;
1.49 msaitoh 574: struct rx_ring *rxr = adapter->rx_rings;
575: struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.1 dyoung 576:
577: INIT_DEBUGOUT("ixv_detach: begin");
1.13 msaitoh 578: if (adapter->osdep.attached == false)
579: return 0;
1.1 dyoung 580:
1.56 msaitoh 581: /* Stop the interface. Callouts are stopped in it. */
582: ixv_ifstop(adapter->ifp, 1);
583:
1.13 msaitoh 584: #if NVLAN > 0
1.58 msaitoh 585: /* Make sure VLANs are not using driver */
1.3 msaitoh 586: if (!VLAN_ATTACHED(&adapter->osdep.ec))
1.113 msaitoh 587: ; /* nothing to do: no VLANs */
588: else if ((flags & (DETACH_SHUTDOWN | DETACH_FORCE)) != 0)
1.3 msaitoh 589: vlan_ifdetach(adapter->ifp);
590: else {
1.26 msaitoh 591: aprint_error_dev(dev, "VLANs in use, detach first\n");
1.3 msaitoh 592: return EBUSY;
1.1 dyoung 593: }
1.13 msaitoh 594: #endif
1.1 dyoung 595:
1.21 msaitoh 596: IXGBE_CORE_LOCK(adapter);
1.1 dyoung 597: ixv_stop(adapter);
1.21 msaitoh 598: IXGBE_CORE_UNLOCK(adapter);
1.1 dyoung 599:
1.41 msaitoh 600: for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
1.58 msaitoh 601: if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
602: softint_disestablish(txr->txr_si);
1.3 msaitoh 603: softint_disestablish(que->que_si);
1.1 dyoung 604: }
1.84 knakahar 605: if (adapter->txr_wq != NULL)
606: workqueue_destroy(adapter->txr_wq);
607: if (adapter->txr_wq_enqueued != NULL)
608: percpu_free(adapter->txr_wq_enqueued, sizeof(u_int));
609: if (adapter->que_wq != NULL)
610: workqueue_destroy(adapter->que_wq);
1.1 dyoung 611:
1.21 msaitoh 612: /* Drain the Mailbox(link) queue */
613: softint_disestablish(adapter->link_si);
1.1 dyoung 614:
615: ether_ifdetach(adapter->ifp);
1.3 msaitoh 616: callout_halt(&adapter->timer, NULL);
1.58 msaitoh 617:
618: if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
619: netmap_detach(adapter->ifp);
620:
1.1 dyoung 621: ixv_free_pci_resources(adapter);
1.3 msaitoh 622: #if 0 /* XXX the NetBSD port is probably missing something here */
1.1 dyoung 623: bus_generic_detach(dev);
1.3 msaitoh 624: #endif
625: if_detach(adapter->ifp);
1.52 msaitoh 626: if_percpuq_destroy(adapter->ipq);
1.1 dyoung 627:
1.41 msaitoh 628: sysctl_teardown(&adapter->sysctllog);
1.49 msaitoh 629: evcnt_detach(&adapter->efbig_tx_dma_setup);
630: evcnt_detach(&adapter->mbuf_defrag_failed);
631: evcnt_detach(&adapter->efbig2_tx_dma_setup);
632: evcnt_detach(&adapter->einval_tx_dma_setup);
633: evcnt_detach(&adapter->other_tx_dma_setup);
634: evcnt_detach(&adapter->eagain_tx_dma_setup);
635: evcnt_detach(&adapter->enomem_tx_dma_setup);
636: evcnt_detach(&adapter->watchdog_events);
637: evcnt_detach(&adapter->tso_err);
638: evcnt_detach(&adapter->link_irq);
639:
640: txr = adapter->tx_rings;
641: for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
642: evcnt_detach(&adapter->queues[i].irqs);
1.85 msaitoh 643: evcnt_detach(&adapter->queues[i].handleq);
644: evcnt_detach(&adapter->queues[i].req);
1.49 msaitoh 645: evcnt_detach(&txr->no_desc_avail);
646: evcnt_detach(&txr->total_packets);
647: evcnt_detach(&txr->tso_tx);
648: #ifndef IXGBE_LEGACY_TX
649: evcnt_detach(&txr->pcq_drops);
650: #endif
651:
652: evcnt_detach(&rxr->rx_packets);
653: evcnt_detach(&rxr->rx_bytes);
654: evcnt_detach(&rxr->rx_copies);
655: evcnt_detach(&rxr->no_jmbuf);
656: evcnt_detach(&rxr->rx_discarded);
657: }
658: evcnt_detach(&stats->ipcs);
659: evcnt_detach(&stats->l4cs);
660: evcnt_detach(&stats->ipcs_bad);
661: evcnt_detach(&stats->l4cs_bad);
662:
663: /* Packet Reception Stats */
664: evcnt_detach(&stats->vfgorc);
665: evcnt_detach(&stats->vfgprc);
666: evcnt_detach(&stats->vfmprc);
667:
668: /* Packet Transmission Stats */
669: evcnt_detach(&stats->vfgotc);
670: evcnt_detach(&stats->vfgptc);
1.41 msaitoh 671:
1.67 msaitoh 672: /* Mailbox Stats */
673: evcnt_detach(&hw->mbx.stats.msgs_tx);
674: evcnt_detach(&hw->mbx.stats.msgs_rx);
675: evcnt_detach(&hw->mbx.stats.acks);
676: evcnt_detach(&hw->mbx.stats.reqs);
677: evcnt_detach(&hw->mbx.stats.rsts);
678:
1.21 msaitoh 679: ixgbe_free_transmit_structures(adapter);
680: ixgbe_free_receive_structures(adapter);
1.82 knakahar 681: for (int i = 0; i < adapter->num_queues; i++) {
682: struct ix_queue *lque = &adapter->queues[i];
1.90 knakahar 683: mutex_destroy(&lque->dc_mtx);
1.82 knakahar 684: }
1.58 msaitoh 685: free(adapter->queues, M_DEVBUF);
1.1 dyoung 686:
1.21 msaitoh 687: IXGBE_CORE_LOCK_DESTROY(adapter);
1.58 msaitoh 688:
1.1 dyoung 689: return (0);
1.58 msaitoh 690: } /* ixv_detach */
1.1 dyoung 691:
1.58 msaitoh 692: /************************************************************************
693: * ixv_init_locked - Init entry point
694: *
695: * Used in two ways: It is used by the stack as an init entry
696: * point in network interface structure. It is also used
697: * by the driver as a hw/sw initialization routine to get
698: * to a consistent state.
1.1 dyoung 699: *
1.58 msaitoh 700: * return 0 on success, positive on failure
701: ************************************************************************/
1.1 dyoung 702: static void
703: ixv_init_locked(struct adapter *adapter)
704: {
705: struct ifnet *ifp = adapter->ifp;
1.114 msaitoh 706: device_t dev = adapter->dev;
1.1 dyoung 707: struct ixgbe_hw *hw = &adapter->hw;
1.102 msaitoh 708: struct ix_queue *que;
1.114 msaitoh 709: int error = 0;
1.68 msaitoh 710: uint32_t mask;
711: int i;
1.1 dyoung 712:
1.26 msaitoh 713: INIT_DEBUGOUT("ixv_init_locked: begin");
1.3 msaitoh 714: KASSERT(mutex_owned(&adapter->core_mtx));
1.1 dyoung 715: hw->adapter_stopped = FALSE;
1.58 msaitoh 716: hw->mac.ops.stop_adapter(hw);
1.63 msaitoh 717: callout_stop(&adapter->timer);
1.102 msaitoh 718: for (i = 0, que = adapter->queues; i < adapter->num_queues; i++, que++)
719: que->disabled_count = 0;
1.1 dyoung 720:
1.57 msaitoh 721: /* reprogram the RAR[0] in case user changed it. */
1.58 msaitoh 722: hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1.1 dyoung 723:
724: /* Get the latest mac address, User can use a LAA */
1.91 msaitoh 725: memcpy(hw->mac.addr, CLLADDR(ifp->if_sadl),
1.1 dyoung 726: IXGBE_ETH_LENGTH_OF_ADDRESS);
1.58 msaitoh 727: hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, 1);
1.1 dyoung 728:
729: /* Prepare transmit descriptors and buffers */
1.21 msaitoh 730: if (ixgbe_setup_transmit_structures(adapter)) {
1.26 msaitoh 731: aprint_error_dev(dev, "Could not setup transmit structures\n");
1.1 dyoung 732: ixv_stop(adapter);
733: return;
734: }
735:
1.26 msaitoh 736: /* Reset VF and renegotiate mailbox API version */
1.58 msaitoh 737: hw->mac.ops.reset_hw(hw);
1.92 msaitoh 738: hw->mac.ops.start_hw(hw);
1.58 msaitoh 739: error = ixv_negotiate_api(adapter);
1.26 msaitoh 740: if (error)
1.58 msaitoh 741: device_printf(dev,
742: "Mailbox API negotiation failed in init_locked!\n");
1.26 msaitoh 743:
1.1 dyoung 744: ixv_initialize_transmit_units(adapter);
745:
746: /* Setup Multicast table */
747: ixv_set_multi(adapter);
748:
749: /*
1.58 msaitoh 750: * Determine the correct mbuf pool
751: * for doing jumbo/headersplit
752: */
1.1 dyoung 753: if (ifp->if_mtu > ETHERMTU)
754: adapter->rx_mbuf_sz = MJUMPAGESIZE;
755: else
756: adapter->rx_mbuf_sz = MCLBYTES;
757:
758: /* Prepare receive descriptors and buffers */
1.21 msaitoh 759: if (ixgbe_setup_receive_structures(adapter)) {
1.26 msaitoh 760: device_printf(dev, "Could not setup receive structures\n");
1.1 dyoung 761: ixv_stop(adapter);
762: return;
763: }
764:
765: /* Configure RX settings */
766: ixv_initialize_receive_units(adapter);
767:
1.3 msaitoh 768: #if 0 /* XXX isn't it required? -- msaitoh */
1.1 dyoung 769: /* Set the various hardware offload abilities */
770: ifp->if_hwassist = 0;
771: if (ifp->if_capenable & IFCAP_TSO4)
772: ifp->if_hwassist |= CSUM_TSO;
773: if (ifp->if_capenable & IFCAP_TXCSUM) {
774: ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
775: #if __FreeBSD_version >= 800000
776: ifp->if_hwassist |= CSUM_SCTP;
777: #endif
778: }
1.3 msaitoh 779: #endif
1.113 msaitoh 780:
1.1 dyoung 781: /* Set up VLAN offload and filter */
782: ixv_setup_vlan_support(adapter);
783:
1.58 msaitoh 784: /* Set up MSI-X routing */
1.1 dyoung 785: ixv_configure_ivars(adapter);
786:
787: /* Set up auto-mask */
1.68 msaitoh 788: mask = (1 << adapter->vector);
1.102 msaitoh 789: for (i = 0, que = adapter->queues; i < adapter->num_queues; i++, que++)
1.68 msaitoh 790: mask |= (1 << que->msix);
791: IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, mask);
1.1 dyoung 792:
1.57 msaitoh 793: /* Set moderation on the Link interrupt */
1.95 msaitoh 794: ixv_eitr_write(adapter, adapter->vector, IXGBE_LINK_ITR);
1.1 dyoung 795:
796: /* Stats init */
797: ixv_init_stats(adapter);
798:
799: /* Config/Enable Link */
1.62 msaitoh 800: hw->mac.get_link_status = TRUE;
1.58 msaitoh 801: hw->mac.ops.check_link(hw, &adapter->link_speed, &adapter->link_up,
802: FALSE);
1.1 dyoung 803:
1.26 msaitoh 804: /* Start watchdog */
805: callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
806:
1.1 dyoung 807: /* And now turn on interrupts */
808: ixv_enable_intr(adapter);
809:
1.79 msaitoh 810: /* Update saved flags. See ixgbe_ifflags_cb() */
811: adapter->if_flags = ifp->if_flags;
1.120 ! msaitoh 812: adapter->ec_capenable = adapter->osdep.ec.ec_capenable;
1.79 msaitoh 813:
1.1 dyoung 814: /* Now inform the stack we're ready */
1.3 msaitoh 815: ifp->if_flags |= IFF_RUNNING;
816: ifp->if_flags &= ~IFF_OACTIVE;
1.1 dyoung 817:
818: return;
1.58 msaitoh 819: } /* ixv_init_locked */
1.1 dyoung 820:
1.88 msaitoh 821: /************************************************************************
822: * ixv_enable_queue
823: ************************************************************************/
1.1 dyoung 824: static inline void
825: ixv_enable_queue(struct adapter *adapter, u32 vector)
826: {
827: struct ixgbe_hw *hw = &adapter->hw;
1.82 knakahar 828: struct ix_queue *que = &adapter->queues[vector];
1.114 msaitoh 829: u32 queue = 1 << vector;
830: u32 mask;
1.1 dyoung 831:
1.90 knakahar 832: mutex_enter(&que->dc_mtx);
833: if (que->disabled_count > 0 && --que->disabled_count > 0)
1.82 knakahar 834: goto out;
835:
1.1 dyoung 836: mask = (IXGBE_EIMS_RTX_QUEUE & queue);
837: IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
1.82 knakahar 838: out:
1.90 knakahar 839: mutex_exit(&que->dc_mtx);
1.58 msaitoh 840: } /* ixv_enable_queue */
1.1 dyoung 841:
1.88 msaitoh 842: /************************************************************************
843: * ixv_disable_queue
844: ************************************************************************/
1.1 dyoung 845: static inline void
846: ixv_disable_queue(struct adapter *adapter, u32 vector)
847: {
848: struct ixgbe_hw *hw = &adapter->hw;
1.82 knakahar 849: struct ix_queue *que = &adapter->queues[vector];
1.114 msaitoh 850: u64 queue = (u64)(1 << vector);
851: u32 mask;
1.1 dyoung 852:
1.90 knakahar 853: mutex_enter(&que->dc_mtx);
854: if (que->disabled_count++ > 0)
1.82 knakahar 855: goto out;
856:
1.1 dyoung 857: mask = (IXGBE_EIMS_RTX_QUEUE & queue);
858: IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
1.82 knakahar 859: out:
1.90 knakahar 860: mutex_exit(&que->dc_mtx);
1.58 msaitoh 861: } /* ixv_disable_queue */
1.1 dyoung 862:
1.105 kamil 863: #if 0
1.1 dyoung 864: static inline void
865: ixv_rearm_queues(struct adapter *adapter, u64 queues)
866: {
867: u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues);
868: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask);
1.58 msaitoh 869: } /* ixv_rearm_queues */
1.105 kamil 870: #endif
1.1 dyoung 871:
872:
1.58 msaitoh 873: /************************************************************************
1.91 msaitoh 874: * ixv_msix_que - MSI-X Queue Interrupt Service routine
1.58 msaitoh 875: ************************************************************************/
876: static int
1.1 dyoung 877: ixv_msix_que(void *arg)
878: {
879: struct ix_queue *que = arg;
1.114 msaitoh 880: struct adapter *adapter = que->adapter;
1.1 dyoung 881: struct tx_ring *txr = que->txr;
882: struct rx_ring *rxr = que->rxr;
1.21 msaitoh 883: bool more;
1.1 dyoung 884: u32 newitr = 0;
885:
886: ixv_disable_queue(adapter, que->msix);
1.21 msaitoh 887: ++que->irqs.ev_count;
1.1 dyoung 888:
1.34 msaitoh 889: #ifdef __NetBSD__
890: /* Don't run ixgbe_rxeof in interrupt context */
891: more = true;
892: #else
1.21 msaitoh 893: more = ixgbe_rxeof(que);
1.34 msaitoh 894: #endif
1.1 dyoung 895:
1.21 msaitoh 896: IXGBE_TX_LOCK(txr);
897: ixgbe_txeof(txr);
898: IXGBE_TX_UNLOCK(txr);
1.1 dyoung 899:
900: /* Do AIM now? */
901:
1.50 msaitoh 902: if (adapter->enable_aim == false)
1.1 dyoung 903: goto no_calc;
904: /*
1.58 msaitoh 905: * Do Adaptive Interrupt Moderation:
906: * - Write out last calculated setting
907: * - Calculate based on average size over
908: * the last interval.
909: */
1.63 msaitoh 910: if (que->eitr_setting)
1.95 msaitoh 911: ixv_eitr_write(adapter, que->msix, que->eitr_setting);
1.58 msaitoh 912:
1.57 msaitoh 913: que->eitr_setting = 0;
914:
915: /* Idle, do nothing */
916: if ((txr->bytes == 0) && (rxr->bytes == 0))
917: goto no_calc;
1.1 dyoung 918:
919: if ((txr->bytes) && (txr->packets))
1.57 msaitoh 920: newitr = txr->bytes/txr->packets;
1.1 dyoung 921: if ((rxr->bytes) && (rxr->packets))
1.106 riastrad 922: newitr = uimax(newitr, (rxr->bytes / rxr->packets));
1.1 dyoung 923: newitr += 24; /* account for hardware frame, crc */
924:
925: /* set an upper boundary */
1.106 riastrad 926: newitr = uimin(newitr, 3000);
1.1 dyoung 927:
928: /* Be nice to the mid range */
929: if ((newitr > 300) && (newitr < 1200))
930: newitr = (newitr / 3);
931: else
932: newitr = (newitr / 2);
933:
1.80 msaitoh 934: /*
935: * When RSC is used, ITR interval must be larger than RSC_DELAY.
936: * Currently, we use 2us for RSC_DELAY. The minimum value is always
937: * greater than 2us on 100M (and 10M?(not documented)), but it's not
938: * on 1G and higher.
939: */
940: if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
941: && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
942: if (newitr < IXGBE_MIN_RSC_EITR_10G1G)
943: newitr = IXGBE_MIN_RSC_EITR_10G1G;
944: }
1.58 msaitoh 945:
946: /* save for next interrupt */
947: que->eitr_setting = newitr;
1.1 dyoung 948:
1.57 msaitoh 949: /* Reset state */
950: txr->bytes = 0;
951: txr->packets = 0;
952: rxr->bytes = 0;
953: rxr->packets = 0;
1.1 dyoung 954:
955: no_calc:
1.86 msaitoh 956: if (more)
1.3 msaitoh 957: softint_schedule(que->que_si);
1.86 msaitoh 958: else /* Re-enable this interrupt */
1.1 dyoung 959: ixv_enable_queue(adapter, que->msix);
1.58 msaitoh 960:
1.11 msaitoh 961: return 1;
1.58 msaitoh 962: } /* ixv_msix_que */
1.1 dyoung 963:
1.58 msaitoh 964: /************************************************************************
965: * ixv_msix_mbx
966: ************************************************************************/
1.11 msaitoh 967: static int
1.1 dyoung 968: ixv_msix_mbx(void *arg)
969: {
970: struct adapter *adapter = arg;
971: struct ixgbe_hw *hw = &adapter->hw;
972:
1.22 msaitoh 973: ++adapter->link_irq.ev_count;
1.69 msaitoh 974: /* NetBSD: We use auto-clear, so it's not required to write VTEICR */
1.1 dyoung 975:
976: /* Link status change */
1.69 msaitoh 977: hw->mac.get_link_status = TRUE;
978: softint_schedule(adapter->link_si);
1.1 dyoung 979:
1.68 msaitoh 980: IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector));
1.57 msaitoh 981:
1.11 msaitoh 982: return 1;
1.58 msaitoh 983: } /* ixv_msix_mbx */
1.1 dyoung 984:
1.80 msaitoh 985: static void
1.95 msaitoh 986: ixv_eitr_write(struct adapter *adapter, uint32_t index, uint32_t itr)
1.80 msaitoh 987: {
988:
989: /*
990: * Newer devices than 82598 have VF function, so this function is
991: * simple.
992: */
993: itr |= IXGBE_EITR_CNT_WDIS;
994:
1.95 msaitoh 995: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(index), itr);
1.80 msaitoh 996: }
997:
998:
1.58 msaitoh 999: /************************************************************************
1000: * ixv_media_status - Media Ioctl callback
1.1 dyoung 1001: *
1.58 msaitoh 1002: * Called whenever the user queries the status of
1003: * the interface using ifconfig.
1004: ************************************************************************/
1.1 dyoung 1005: static void
1.63 msaitoh 1006: ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1 dyoung 1007: {
1008: struct adapter *adapter = ifp->if_softc;
1009:
1010: INIT_DEBUGOUT("ixv_media_status: begin");
1.21 msaitoh 1011: IXGBE_CORE_LOCK(adapter);
1.1 dyoung 1012: ixv_update_link_status(adapter);
1013:
1014: ifmr->ifm_status = IFM_AVALID;
1015: ifmr->ifm_active = IFM_ETHER;
1016:
1.109 msaitoh 1017: if (adapter->link_active != LINK_STATE_UP) {
1.39 msaitoh 1018: ifmr->ifm_active |= IFM_NONE;
1.21 msaitoh 1019: IXGBE_CORE_UNLOCK(adapter);
1.1 dyoung 1020: return;
1021: }
1022:
1023: ifmr->ifm_status |= IFM_ACTIVE;
1024:
1025: switch (adapter->link_speed) {
1.42 msaitoh 1026: case IXGBE_LINK_SPEED_10GB_FULL:
1027: ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
1028: break;
1.71 msaitoh 1029: case IXGBE_LINK_SPEED_5GB_FULL:
1030: ifmr->ifm_active |= IFM_5000_T | IFM_FDX;
1031: break;
1032: case IXGBE_LINK_SPEED_2_5GB_FULL:
1033: ifmr->ifm_active |= IFM_2500_T | IFM_FDX;
1034: break;
1.1 dyoung 1035: case IXGBE_LINK_SPEED_1GB_FULL:
1036: ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
1037: break;
1.42 msaitoh 1038: case IXGBE_LINK_SPEED_100_FULL:
1039: ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
1.1 dyoung 1040: break;
1.58 msaitoh 1041: case IXGBE_LINK_SPEED_10_FULL:
1042: ifmr->ifm_active |= IFM_10_T | IFM_FDX;
1043: break;
1.1 dyoung 1044: }
1045:
1.70 msaitoh 1046: ifp->if_baudrate = ifmedia_baudrate(ifmr->ifm_active);
1047:
1.21 msaitoh 1048: IXGBE_CORE_UNLOCK(adapter);
1.58 msaitoh 1049: } /* ixv_media_status */
1.1 dyoung 1050:
1.58 msaitoh 1051: /************************************************************************
1052: * ixv_media_change - Media Ioctl callback
1.1 dyoung 1053: *
1.58 msaitoh 1054: * Called when the user changes speed/duplex using
1055: * media/mediopt option with ifconfig.
1056: ************************************************************************/
1.1 dyoung 1057: static int
1.57 msaitoh 1058: ixv_media_change(struct ifnet *ifp)
1.1 dyoung 1059: {
1060: struct adapter *adapter = ifp->if_softc;
1061: struct ifmedia *ifm = &adapter->media;
1062:
1063: INIT_DEBUGOUT("ixv_media_change: begin");
1064:
1065: if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1066: return (EINVAL);
1067:
1.57 msaitoh 1068: switch (IFM_SUBTYPE(ifm->ifm_media)) {
1069: case IFM_AUTO:
1070: break;
1071: default:
1072: device_printf(adapter->dev, "Only auto media type\n");
1.1 dyoung 1073: return (EINVAL);
1.57 msaitoh 1074: }
1.1 dyoung 1075:
1076: return (0);
1.58 msaitoh 1077: } /* ixv_media_change */
1.1 dyoung 1078:
1079:
1.58 msaitoh 1080: /************************************************************************
1081: * ixv_negotiate_api
1.1 dyoung 1082: *
1.58 msaitoh 1083: * Negotiate the Mailbox API with the PF;
1084: * start with the most featured API first.
1085: ************************************************************************/
1086: static int
1087: ixv_negotiate_api(struct adapter *adapter)
1088: {
1089: struct ixgbe_hw *hw = &adapter->hw;
1.114 msaitoh 1090: int mbx_api[] = { ixgbe_mbox_api_11,
1091: ixgbe_mbox_api_10,
1092: ixgbe_mbox_api_unknown };
1093: int i = 0;
1.58 msaitoh 1094:
1095: while (mbx_api[i] != ixgbe_mbox_api_unknown) {
1096: if (ixgbevf_negotiate_api_version(hw, mbx_api[i]) == 0)
1097: return (0);
1098: i++;
1099: }
1100:
1101: return (EINVAL);
1102: } /* ixv_negotiate_api */
1103:
1104:
1105: /************************************************************************
1106: * ixv_set_multi - Multicast Update
1.1 dyoung 1107: *
1.58 msaitoh 1108: * Called whenever multicast address list is updated.
1109: ************************************************************************/
1.1 dyoung 1110: static void
1111: ixv_set_multi(struct adapter *adapter)
1112: {
1.3 msaitoh 1113: struct ether_multi *enm;
1114: struct ether_multistep step;
1.58 msaitoh 1115: struct ethercom *ec = &adapter->osdep.ec;
1.1 dyoung 1116: u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
1.114 msaitoh 1117: u8 *update_ptr;
1118: int mcnt = 0;
1.1 dyoung 1119:
1.72 msaitoh 1120: KASSERT(mutex_owned(&adapter->core_mtx));
1.1 dyoung 1121: IOCTL_DEBUGOUT("ixv_set_multi: begin");
1122:
1.72 msaitoh 1123: ETHER_LOCK(ec);
1.3 msaitoh 1124: ETHER_FIRST_MULTI(step, ec, enm);
1125: while (enm != NULL) {
1126: bcopy(enm->enm_addrlo,
1.1 dyoung 1127: &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
1128: IXGBE_ETH_LENGTH_OF_ADDRESS);
1129: mcnt++;
1.3 msaitoh 1130: /* XXX This might be required --msaitoh */
1131: if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES)
1132: break;
1133: ETHER_NEXT_MULTI(step, enm);
1.1 dyoung 1134: }
1.72 msaitoh 1135: ETHER_UNLOCK(ec);
1.1 dyoung 1136:
1137: update_ptr = mta;
1138:
1.58 msaitoh 1139: adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
1140: ixv_mc_array_itr, TRUE);
1141: } /* ixv_set_multi */
1.1 dyoung 1142:
1.58 msaitoh 1143: /************************************************************************
1144: * ixv_mc_array_itr
1145: *
1146: * An iterator function needed by the multicast shared code.
1147: * It feeds the shared code routine the addresses in the
1148: * array of ixv_set_multi() one by one.
1149: ************************************************************************/
1.1 dyoung 1150: static u8 *
1151: ixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
1152: {
1153: u8 *addr = *update_ptr;
1154: u8 *newptr;
1.88 msaitoh 1155:
1.1 dyoung 1156: *vmdq = 0;
1157:
1158: newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS;
1159: *update_ptr = newptr;
1.57 msaitoh 1160:
1.1 dyoung 1161: return addr;
1.58 msaitoh 1162: } /* ixv_mc_array_itr */
1.1 dyoung 1163:
1.58 msaitoh 1164: /************************************************************************
1165: * ixv_local_timer - Timer routine
1.1 dyoung 1166: *
1.58 msaitoh 1167: * Checks for link status, updates statistics,
1168: * and runs the watchdog check.
1169: ************************************************************************/
1.1 dyoung 1170: static void
1.22 msaitoh 1171: ixv_local_timer(void *arg)
1172: {
1173: struct adapter *adapter = arg;
1174:
1175: IXGBE_CORE_LOCK(adapter);
1176: ixv_local_timer_locked(adapter);
1177: IXGBE_CORE_UNLOCK(adapter);
1178: }
1179:
1180: static void
1181: ixv_local_timer_locked(void *arg)
1.1 dyoung 1182: {
1183: struct adapter *adapter = arg;
1.98 msaitoh 1184: device_t dev = adapter->dev;
1.22 msaitoh 1185: struct ix_queue *que = adapter->queues;
1.98 msaitoh 1186: u64 queues = 0;
1.87 msaitoh 1187: u64 v0, v1, v2, v3, v4, v5, v6, v7;
1.98 msaitoh 1188: int hung = 0;
1.87 msaitoh 1189: int i;
1.1 dyoung 1190:
1.3 msaitoh 1191: KASSERT(mutex_owned(&adapter->core_mtx));
1.1 dyoung 1192:
1.117 msaitoh 1193: if (ixv_check_link(adapter)) {
1194: ixv_init_locked(adapter);
1195: return;
1196: }
1.1 dyoung 1197:
1198: /* Stats Update */
1199: ixv_update_stats(adapter);
1200:
1.87 msaitoh 1201: /* Update some event counters */
1202: v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = 0;
1203: que = adapter->queues;
1204: for (i = 0; i < adapter->num_queues; i++, que++) {
1.114 msaitoh 1205: struct tx_ring *txr = que->txr;
1.87 msaitoh 1206:
1207: v0 += txr->q_efbig_tx_dma_setup;
1208: v1 += txr->q_mbuf_defrag_failed;
1209: v2 += txr->q_efbig2_tx_dma_setup;
1210: v3 += txr->q_einval_tx_dma_setup;
1211: v4 += txr->q_other_tx_dma_setup;
1212: v5 += txr->q_eagain_tx_dma_setup;
1213: v6 += txr->q_enomem_tx_dma_setup;
1214: v7 += txr->q_tso_err;
1215: }
1216: adapter->efbig_tx_dma_setup.ev_count = v0;
1217: adapter->mbuf_defrag_failed.ev_count = v1;
1218: adapter->efbig2_tx_dma_setup.ev_count = v2;
1219: adapter->einval_tx_dma_setup.ev_count = v3;
1220: adapter->other_tx_dma_setup.ev_count = v4;
1221: adapter->eagain_tx_dma_setup.ev_count = v5;
1222: adapter->enomem_tx_dma_setup.ev_count = v6;
1223: adapter->tso_err.ev_count = v7;
1224:
1.98 msaitoh 1225: /*
1226: * Check the TX queues status
1.114 msaitoh 1227: * - mark hung queues so we don't schedule on them
1228: * - watchdog only if all queues show hung
1.98 msaitoh 1229: */
1230: que = adapter->queues;
1231: for (i = 0; i < adapter->num_queues; i++, que++) {
1232: /* Keep track of queues with work for soft irq */
1233: if (que->txr->busy)
1234: queues |= ((u64)1 << que->me);
1.21 msaitoh 1235: /*
1.98 msaitoh 1236: * Each time txeof runs without cleaning, but there
1237: * are uncleaned descriptors it increments busy. If
1238: * we get to the MAX we declare it hung.
1.58 msaitoh 1239: */
1.98 msaitoh 1240: if (que->busy == IXGBE_QUEUE_HUNG) {
1241: ++hung;
1242: /* Mark the queue as inactive */
1243: adapter->active_queues &= ~((u64)1 << que->me);
1244: continue;
1245: } else {
1246: /* Check if we've come back from hung */
1247: if ((adapter->active_queues & ((u64)1 << que->me)) == 0)
1248: adapter->active_queues |= ((u64)1 << que->me);
1.1 dyoung 1249: }
1.98 msaitoh 1250: if (que->busy >= IXGBE_MAX_TX_BUSY) {
1251: device_printf(dev,
1252: "Warning queue %d appears to be hung!\n", i);
1253: que->txr->busy = IXGBE_QUEUE_HUNG;
1254: ++hung;
1255: }
1256: }
1257:
1258: /* Only truly watchdog if all queues show hung */
1259: if (hung == adapter->num_queues)
1260: goto watchdog;
1.104 msaitoh 1261: #if 0
1.98 msaitoh 1262: else if (queues != 0) { /* Force an IRQ on queues with work */
1263: ixv_rearm_queues(adapter, queues);
1.21 msaitoh 1264: }
1.104 msaitoh 1265: #endif
1.21 msaitoh 1266:
1.98 msaitoh 1267: callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
1268:
1269: return;
1.96 msaitoh 1270:
1.98 msaitoh 1271: watchdog:
1.21 msaitoh 1272:
1.98 msaitoh 1273: device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
1274: adapter->ifp->if_flags &= ~IFF_RUNNING;
1275: adapter->watchdog_events.ev_count++;
1276: ixv_init_locked(adapter);
1277: } /* ixv_local_timer */
1.1 dyoung 1278:
1.58 msaitoh 1279: /************************************************************************
1280: * ixv_update_link_status - Update OS on link state
1281: *
1282: * Note: Only updates the OS on the cached link state.
1.114 msaitoh 1283: * The real check of the hardware only happens with
1284: * a link interrupt.
1.58 msaitoh 1285: ************************************************************************/
1.1 dyoung 1286: static void
1287: ixv_update_link_status(struct adapter *adapter)
1288: {
1.58 msaitoh 1289: struct ifnet *ifp = adapter->ifp;
1290: device_t dev = adapter->dev;
1.1 dyoung 1291:
1.89 knakahar 1292: KASSERT(mutex_owned(&adapter->core_mtx));
1293:
1.57 msaitoh 1294: if (adapter->link_up) {
1.109 msaitoh 1295: if (adapter->link_active != LINK_STATE_UP) {
1.42 msaitoh 1296: if (bootverbose) {
1297: const char *bpsmsg;
1298:
1299: switch (adapter->link_speed) {
1300: case IXGBE_LINK_SPEED_10GB_FULL:
1301: bpsmsg = "10 Gbps";
1302: break;
1.58 msaitoh 1303: case IXGBE_LINK_SPEED_5GB_FULL:
1304: bpsmsg = "5 Gbps";
1305: break;
1306: case IXGBE_LINK_SPEED_2_5GB_FULL:
1307: bpsmsg = "2.5 Gbps";
1308: break;
1.42 msaitoh 1309: case IXGBE_LINK_SPEED_1GB_FULL:
1310: bpsmsg = "1 Gbps";
1311: break;
1312: case IXGBE_LINK_SPEED_100_FULL:
1313: bpsmsg = "100 Mbps";
1314: break;
1.58 msaitoh 1315: case IXGBE_LINK_SPEED_10_FULL:
1316: bpsmsg = "10 Mbps";
1317: break;
1.42 msaitoh 1318: default:
1319: bpsmsg = "unknown speed";
1320: break;
1321: }
1.63 msaitoh 1322: device_printf(dev, "Link is up %s %s \n",
1.42 msaitoh 1323: bpsmsg, "Full Duplex");
1324: }
1.109 msaitoh 1325: adapter->link_active = LINK_STATE_UP;
1.1 dyoung 1326: if_link_state_change(ifp, LINK_STATE_UP);
1327: }
1.109 msaitoh 1328: } else {
1329: /*
1330: * Do it when link active changes to DOWN. i.e.
1331: * a) LINK_STATE_UNKNOWN -> LINK_STATE_DOWN
1.114 msaitoh 1332: * b) LINK_STATE_UP -> LINK_STATE_DOWN
1.109 msaitoh 1333: */
1334: if (adapter->link_active != LINK_STATE_DOWN) {
1.1 dyoung 1335: if (bootverbose)
1.63 msaitoh 1336: device_printf(dev, "Link is Down\n");
1.1 dyoung 1337: if_link_state_change(ifp, LINK_STATE_DOWN);
1.109 msaitoh 1338: adapter->link_active = LINK_STATE_DOWN;
1.1 dyoung 1339: }
1340: }
1.58 msaitoh 1341: } /* ixv_update_link_status */
1.1 dyoung 1342:
1343:
1.58 msaitoh 1344: /************************************************************************
1345: * ixv_stop - Stop the hardware
1346: *
1347: * Disables all traffic on the adapter by issuing a
1348: * global reset on the MAC and deallocates TX/RX buffers.
1349: ************************************************************************/
1.3 msaitoh 1350: static void
1351: ixv_ifstop(struct ifnet *ifp, int disable)
1352: {
1353: struct adapter *adapter = ifp->if_softc;
1354:
1.21 msaitoh 1355: IXGBE_CORE_LOCK(adapter);
1.3 msaitoh 1356: ixv_stop(adapter);
1.21 msaitoh 1357: IXGBE_CORE_UNLOCK(adapter);
1.3 msaitoh 1358: }
1359:
1.1 dyoung 1360: static void
1361: ixv_stop(void *arg)
1362: {
1.114 msaitoh 1363: struct ifnet *ifp;
1364: struct adapter *adapter = arg;
1.1 dyoung 1365: struct ixgbe_hw *hw = &adapter->hw;
1.58 msaitoh 1366:
1.1 dyoung 1367: ifp = adapter->ifp;
1368:
1.3 msaitoh 1369: KASSERT(mutex_owned(&adapter->core_mtx));
1.1 dyoung 1370:
1371: INIT_DEBUGOUT("ixv_stop: begin\n");
1372: ixv_disable_intr(adapter);
1373:
1374: /* Tell the stack that the interface is no longer active */
1.3 msaitoh 1375: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1.1 dyoung 1376:
1.58 msaitoh 1377: hw->mac.ops.reset_hw(hw);
1.1 dyoung 1378: adapter->hw.adapter_stopped = FALSE;
1.58 msaitoh 1379: hw->mac.ops.stop_adapter(hw);
1.98 msaitoh 1380: callout_stop(&adapter->timer);
1.1 dyoung 1381:
1382: /* reprogram the RAR[0] in case user changed it. */
1.58 msaitoh 1383: hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1.1 dyoung 1384:
1385: return;
1.58 msaitoh 1386: } /* ixv_stop */
1.1 dyoung 1387:
1388:
1.58 msaitoh 1389: /************************************************************************
1390: * ixv_allocate_pci_resources
1391: ************************************************************************/
1.57 msaitoh 1392: static int
1393: ixv_allocate_pci_resources(struct adapter *adapter,
1394: const struct pci_attach_args *pa)
1.1 dyoung 1395: {
1.108 msaitoh 1396: pcireg_t memtype, csr;
1.114 msaitoh 1397: device_t dev = adapter->dev;
1.57 msaitoh 1398: bus_addr_t addr;
1399: int flags;
1.3 msaitoh 1400:
1.57 msaitoh 1401: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR(0));
1402: switch (memtype) {
1403: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
1404: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
1405: adapter->osdep.mem_bus_space_tag = pa->pa_memt;
1406: if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_BAR(0),
1.114 msaitoh 1407: memtype, &addr, &adapter->osdep.mem_size, &flags) != 0)
1.57 msaitoh 1408: goto map_err;
1409: if ((flags & BUS_SPACE_MAP_PREFETCHABLE) != 0) {
1410: aprint_normal_dev(dev, "clearing prefetchable bit\n");
1411: flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
1412: }
1413: if (bus_space_map(adapter->osdep.mem_bus_space_tag, addr,
1414: adapter->osdep.mem_size, flags,
1.3 msaitoh 1415: &adapter->osdep.mem_bus_space_handle) != 0) {
1416: map_err:
1417: adapter->osdep.mem_size = 0;
1418: aprint_error_dev(dev, "unable to map BAR0\n");
1419: return ENXIO;
1420: }
1.108 msaitoh 1421: /*
1422: * Enable address decoding for memory range in case it's not
1423: * set.
1424: */
1425: csr = pci_conf_read(pa->pa_pc, pa->pa_tag,
1426: PCI_COMMAND_STATUS_REG);
1427: csr |= PCI_COMMAND_MEM_ENABLE;
1428: pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1429: csr);
1.3 msaitoh 1430: break;
1431: default:
1432: aprint_error_dev(dev, "unexpected type on BAR0\n");
1433: return ENXIO;
1.1 dyoung 1434: }
1435:
1.23 msaitoh 1436: /* Pick up the tuneable queues */
1437: adapter->num_queues = ixv_num_queues;
1.1 dyoung 1438:
1.58 msaitoh 1439: return (0);
1440: } /* ixv_allocate_pci_resources */
1.1 dyoung 1441:
1.58 msaitoh 1442: /************************************************************************
1443: * ixv_free_pci_resources
1444: ************************************************************************/
1.1 dyoung 1445: static void
1446: ixv_free_pci_resources(struct adapter * adapter)
1447: {
1.114 msaitoh 1448: struct ix_queue *que = adapter->queues;
1.11 msaitoh 1449: int rid;
1.1 dyoung 1450:
1451: /*
1.58 msaitoh 1452: * Release all msix queue resources:
1453: */
1.1 dyoung 1454: for (int i = 0; i < adapter->num_queues; i++, que++) {
1455: if (que->res != NULL)
1.11 msaitoh 1456: pci_intr_disestablish(adapter->osdep.pc,
1457: adapter->osdep.ihs[i]);
1.1 dyoung 1458: }
1459:
1.12 msaitoh 1460:
1.58 msaitoh 1461: /* Clean the Mailbox interrupt last */
1.49 msaitoh 1462: rid = adapter->vector;
1.1 dyoung 1463:
1.41 msaitoh 1464: if (adapter->osdep.ihs[rid] != NULL) {
1.11 msaitoh 1465: pci_intr_disestablish(adapter->osdep.pc,
1466: adapter->osdep.ihs[rid]);
1.41 msaitoh 1467: adapter->osdep.ihs[rid] = NULL;
1468: }
1.11 msaitoh 1469:
1470: pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs,
1471: adapter->osdep.nintrs);
1472:
1473: if (adapter->osdep.mem_size != 0) {
1474: bus_space_unmap(adapter->osdep.mem_bus_space_tag,
1475: adapter->osdep.mem_bus_space_handle,
1476: adapter->osdep.mem_size);
1477: }
1.1 dyoung 1478:
1479: return;
1.58 msaitoh 1480: } /* ixv_free_pci_resources */
1.1 dyoung 1481:
1.58 msaitoh 1482: /************************************************************************
1483: * ixv_setup_interface
1.1 dyoung 1484: *
1.58 msaitoh 1485: * Setup networking device structure and register an interface.
1486: ************************************************************************/
1.73 msaitoh 1487: static int
1.1 dyoung 1488: ixv_setup_interface(device_t dev, struct adapter *adapter)
1489: {
1.3 msaitoh 1490: struct ethercom *ec = &adapter->osdep.ec;
1.1 dyoung 1491: struct ifnet *ifp;
1.73 msaitoh 1492: int rv;
1.1 dyoung 1493:
1494: INIT_DEBUGOUT("ixv_setup_interface: begin");
1495:
1.3 msaitoh 1496: ifp = adapter->ifp = &ec->ec_if;
1497: strlcpy(ifp->if_xname, device_xname(dev), IFNAMSIZ);
1.46 msaitoh 1498: ifp->if_baudrate = IF_Gbps(10);
1.1 dyoung 1499: ifp->if_init = ixv_init;
1.3 msaitoh 1500: ifp->if_stop = ixv_ifstop;
1.1 dyoung 1501: ifp->if_softc = adapter;
1502: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1.55 msaitoh 1503: #ifdef IXGBE_MPSAFE
1.74 ozaki-r 1504: ifp->if_extflags = IFEF_MPSAFE;
1.55 msaitoh 1505: #endif
1.1 dyoung 1506: ifp->if_ioctl = ixv_ioctl;
1.58 msaitoh 1507: if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) {
1508: #if 0
1509: ixv_start_locked = ixgbe_legacy_start_locked;
1510: #endif
1511: } else {
1512: ifp->if_transmit = ixgbe_mq_start;
1513: #if 0
1514: ixv_start_locked = ixgbe_mq_start_locked;
1.35 msaitoh 1515: #endif
1.58 msaitoh 1516: }
1517: ifp->if_start = ixgbe_legacy_start;
1.45 msaitoh 1518: IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
1519: IFQ_SET_READY(&ifp->if_snd);
1.1 dyoung 1520:
1.73 msaitoh 1521: rv = if_initialize(ifp);
1522: if (rv != 0) {
1523: aprint_error_dev(dev, "if_initialize failed(%d)\n", rv);
1524: return rv;
1525: }
1.52 msaitoh 1526: adapter->ipq = if_percpuq_create(&adapter->osdep.ec.ec_if);
1.1 dyoung 1527: ether_ifattach(ifp, adapter->hw.mac.addr);
1.51 msaitoh 1528: /*
1529: * We use per TX queue softint, so if_deferred_start_init() isn't
1530: * used.
1531: */
1.3 msaitoh 1532: ether_set_ifflags_cb(ec, ixv_ifflags_cb);
1.1 dyoung 1533:
1.58 msaitoh 1534: adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR;
1.1 dyoung 1535:
1536: /*
1537: * Tell the upper layer(s) we support long frames.
1538: */
1.3 msaitoh 1539: ifp->if_hdrlen = sizeof(struct ether_vlan_header);
1540:
1.58 msaitoh 1541: /* Set capability flags */
1542: ifp->if_capabilities |= IFCAP_HWCSUM
1.114 msaitoh 1543: | IFCAP_TSOv4
1544: | IFCAP_TSOv6;
1.3 msaitoh 1545: ifp->if_capenable = 0;
1.1 dyoung 1546:
1.120 ! msaitoh 1547: ec->ec_capabilities |= ETHERCAP_VLAN_HWFILTER
! 1548: | ETHERCAP_VLAN_HWTAGGING
1.58 msaitoh 1549: | ETHERCAP_VLAN_HWCSUM
1550: | ETHERCAP_JUMBO_MTU
1551: | ETHERCAP_VLAN_MTU;
1552:
1553: /* Enable the above capabilities by default */
1.3 msaitoh 1554: ec->ec_capenable = ec->ec_capabilities;
1.1 dyoung 1555:
1.3 msaitoh 1556: /* Don't enable LRO by default */
1.107 msaitoh 1557: #if 0
1558: /* NetBSD doesn't support LRO yet */
1.3 msaitoh 1559: ifp->if_capabilities |= IFCAP_LRO;
1.21 msaitoh 1560: #endif
1.3 msaitoh 1561:
1562: /*
1.1 dyoung 1563: * Specify the media types supported by this adapter and register
1564: * callbacks to update media and link information
1565: */
1.115 msaitoh 1566: ec->ec_ifmedia = &adapter->media;
1.1 dyoung 1567: ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change,
1.57 msaitoh 1568: ixv_media_status);
1.1 dyoung 1569: ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1570: ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1571:
1.101 ozaki-r 1572: if_register(ifp);
1573:
1.73 msaitoh 1574: return 0;
1.58 msaitoh 1575: } /* ixv_setup_interface */
1576:
1577:
1578: /************************************************************************
1579: * ixv_initialize_transmit_units - Enable transmit unit.
1580: ************************************************************************/
1.21 msaitoh 1581: static void
1582: ixv_initialize_transmit_units(struct adapter *adapter)
1.1 dyoung 1583: {
1.21 msaitoh 1584: struct tx_ring *txr = adapter->tx_rings;
1585: struct ixgbe_hw *hw = &adapter->hw;
1.91 msaitoh 1586: int i;
1.1 dyoung 1587:
1.91 msaitoh 1588: for (i = 0; i < adapter->num_queues; i++, txr++) {
1.58 msaitoh 1589: u64 tdba = txr->txdma.dma_paddr;
1590: u32 txctrl, txdctl;
1.91 msaitoh 1591: int j = txr->me;
1.1 dyoung 1592:
1.21 msaitoh 1593: /* Set WTHRESH to 8, burst writeback */
1.91 msaitoh 1594: txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
1.21 msaitoh 1595: txdctl |= (8 << 16);
1.91 msaitoh 1596: IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
1.1 dyoung 1597:
1.21 msaitoh 1598: /* Set the HW Tx Head and Tail indices */
1.91 msaitoh 1599: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(j), 0);
1600: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(j), 0);
1.1 dyoung 1601:
1.21 msaitoh 1602: /* Set Tx Tail register */
1.91 msaitoh 1603: txr->tail = IXGBE_VFTDT(j);
1.1 dyoung 1604:
1.100 msaitoh 1605: txr->txr_no_space = false;
1606:
1.21 msaitoh 1607: /* Set Ring parameters */
1.91 msaitoh 1608: IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(j),
1.57 msaitoh 1609: (tdba & 0x00000000ffffffffULL));
1.91 msaitoh 1610: IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(j), (tdba >> 32));
1611: IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(j),
1.58 msaitoh 1612: adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc));
1.91 msaitoh 1613: txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(j));
1.21 msaitoh 1614: txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
1.91 msaitoh 1615: IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(j), txctrl);
1.1 dyoung 1616:
1.21 msaitoh 1617: /* Now enable */
1.91 msaitoh 1618: txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(j));
1.21 msaitoh 1619: txdctl |= IXGBE_TXDCTL_ENABLE;
1.91 msaitoh 1620: IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(j), txdctl);
1.1 dyoung 1621: }
1622:
1.21 msaitoh 1623: return;
1.58 msaitoh 1624: } /* ixv_initialize_transmit_units */
1625:
1626:
1627: /************************************************************************
1628: * ixv_initialize_rss_mapping
1629: ************************************************************************/
1630: static void
1631: ixv_initialize_rss_mapping(struct adapter *adapter)
1632: {
1633: struct ixgbe_hw *hw = &adapter->hw;
1.114 msaitoh 1634: u32 reta = 0, mrqc, rss_key[10];
1635: int queue_id;
1636: int i, j;
1637: u32 rss_hash_config;
1.58 msaitoh 1638:
1.78 knakahar 1639: /* force use default RSS key. */
1640: #ifdef __NetBSD__
1641: rss_getkey((uint8_t *) &rss_key);
1642: #else
1.58 msaitoh 1643: if (adapter->feat_en & IXGBE_FEATURE_RSS) {
1644: /* Fetch the configured RSS key */
1645: rss_getkey((uint8_t *)&rss_key);
1646: } else {
1647: /* set up random bits */
1648: cprng_fast(&rss_key, sizeof(rss_key));
1649: }
1.78 knakahar 1650: #endif
1.58 msaitoh 1651:
1652: /* Now fill out hash function seeds */
1653: for (i = 0; i < 10; i++)
1654: IXGBE_WRITE_REG(hw, IXGBE_VFRSSRK(i), rss_key[i]);
1655:
1656: /* Set up the redirection table */
1657: for (i = 0, j = 0; i < 64; i++, j++) {
1658: if (j == adapter->num_queues)
1659: j = 0;
1.1 dyoung 1660:
1.58 msaitoh 1661: if (adapter->feat_en & IXGBE_FEATURE_RSS) {
1662: /*
1663: * Fetch the RSS bucket id for the given indirection
1664: * entry. Cap it at the number of configured buckets
1665: * (which is num_queues.)
1666: */
1667: queue_id = rss_get_indirection_to_bucket(i);
1668: queue_id = queue_id % adapter->num_queues;
1669: } else
1670: queue_id = j;
1.1 dyoung 1671:
1.58 msaitoh 1672: /*
1673: * The low 8 bits are for hash value (n+0);
1674: * The next 8 bits are for hash value (n+1), etc.
1675: */
1676: reta >>= 8;
1677: reta |= ((uint32_t)queue_id) << 24;
1678: if ((i & 3) == 3) {
1679: IXGBE_WRITE_REG(hw, IXGBE_VFRETA(i >> 2), reta);
1680: reta = 0;
1681: }
1682: }
1.21 msaitoh 1683:
1.58 msaitoh 1684: /* Perform hash on these packet types */
1685: if (adapter->feat_en & IXGBE_FEATURE_RSS)
1686: rss_hash_config = rss_gethashconfig();
1687: else {
1688: /*
1689: * Disable UDP - IP fragments aren't currently being handled
1690: * and so we end up with a mix of 2-tuple and 4-tuple
1691: * traffic.
1692: */
1693: rss_hash_config = RSS_HASHTYPE_RSS_IPV4
1.114 msaitoh 1694: | RSS_HASHTYPE_RSS_TCP_IPV4
1695: | RSS_HASHTYPE_RSS_IPV6
1696: | RSS_HASHTYPE_RSS_TCP_IPV6;
1.58 msaitoh 1697: }
1698:
1699: mrqc = IXGBE_MRQC_RSSEN;
1700: if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
1701: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4;
1702: if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
1703: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP;
1704: if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
1705: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6;
1706: if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
1707: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
1708: if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
1709: device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_IPV6_EX defined, but not supported\n",
1710: __func__);
1711: if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX)
1712: device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_TCP_IPV6_EX defined, but not supported\n",
1713: __func__);
1714: if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
1715: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
1716: if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
1717: mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
1718: if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX)
1719: device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV6_EX defined, but not supported\n",
1720: __func__);
1721: IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, mrqc);
1722: } /* ixv_initialize_rss_mapping */
1723:
1724:
1725: /************************************************************************
1726: * ixv_initialize_receive_units - Setup receive registers and features.
1727: ************************************************************************/
1.21 msaitoh 1728: static void
1729: ixv_initialize_receive_units(struct adapter *adapter)
1.1 dyoung 1730: {
1.21 msaitoh 1731: struct rx_ring *rxr = adapter->rx_rings;
1732: struct ixgbe_hw *hw = &adapter->hw;
1.23 msaitoh 1733: struct ifnet *ifp = adapter->ifp;
1.117 msaitoh 1734: u32 bufsz, psrtype;
1.1 dyoung 1735:
1.23 msaitoh 1736: if (ifp->if_mtu > ETHERMTU)
1737: bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1738: else
1739: bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1.1 dyoung 1740:
1.58 msaitoh 1741: psrtype = IXGBE_PSRTYPE_TCPHDR
1.114 msaitoh 1742: | IXGBE_PSRTYPE_UDPHDR
1743: | IXGBE_PSRTYPE_IPV4HDR
1744: | IXGBE_PSRTYPE_IPV6HDR
1745: | IXGBE_PSRTYPE_L2HDR;
1.58 msaitoh 1746:
1747: if (adapter->num_queues > 1)
1748: psrtype |= 1 << 29;
1.1 dyoung 1749:
1.23 msaitoh 1750: IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
1751:
1.26 msaitoh 1752: /* Tell PF our max_frame size */
1.58 msaitoh 1753: if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) {
1754: device_printf(adapter->dev, "There is a problem with the PF setup. It is likely the receive unit for this VF will not function correctly.\n");
1755: }
1.1 dyoung 1756:
1.23 msaitoh 1757: for (int i = 0; i < adapter->num_queues; i++, rxr++) {
1.1 dyoung 1758: u64 rdba = rxr->rxdma.dma_paddr;
1759: u32 reg, rxdctl;
1.91 msaitoh 1760: int j = rxr->me;
1.1 dyoung 1761:
1.23 msaitoh 1762: /* Disable the queue */
1.91 msaitoh 1763: rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j));
1.28 msaitoh 1764: rxdctl &= ~IXGBE_RXDCTL_ENABLE;
1.91 msaitoh 1765: IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl);
1766: for (int k = 0; k < 10; k++) {
1767: if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) &
1.23 msaitoh 1768: IXGBE_RXDCTL_ENABLE)
1769: msec_delay(1);
1770: else
1771: break;
1772: }
1773: wmb();
1.1 dyoung 1774: /* Setup the Base and Length of the Rx Descriptor Ring */
1.91 msaitoh 1775: IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(j),
1.1 dyoung 1776: (rdba & 0x00000000ffffffffULL));
1.91 msaitoh 1777: IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(j), (rdba >> 32));
1778: IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(j),
1.1 dyoung 1779: adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
1780:
1.23 msaitoh 1781: /* Reset the ring indices */
1782: IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0);
1783: IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0);
1784:
1.1 dyoung 1785: /* Set up the SRRCTL register */
1.91 msaitoh 1786: reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(j));
1.1 dyoung 1787: reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
1788: reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
1789: reg |= bufsz;
1.21 msaitoh 1790: reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
1.91 msaitoh 1791: IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(j), reg);
1.1 dyoung 1792:
1.23 msaitoh 1793: /* Capture Rx Tail index */
1.21 msaitoh 1794: rxr->tail = IXGBE_VFRDT(rxr->me);
1795:
1796: /* Do the queue enabling last */
1.28 msaitoh 1797: rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME;
1.91 msaitoh 1798: IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl);
1.21 msaitoh 1799: for (int k = 0; k < 10; k++) {
1.91 msaitoh 1800: if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)) &
1.21 msaitoh 1801: IXGBE_RXDCTL_ENABLE)
1802: break;
1.58 msaitoh 1803: msec_delay(1);
1.21 msaitoh 1804: }
1805: wmb();
1.24 msaitoh 1806:
1807: /* Set the Tail Pointer */
1.88 msaitoh 1808: #ifdef DEV_NETMAP
1.25 msaitoh 1809: /*
1810: * In netmap mode, we must preserve the buffers made
1811: * available to userspace before the if_init()
1812: * (this is true by default on the TX side, because
1813: * init makes all buffers available to userspace).
1814: *
1815: * netmap_reset() and the device specific routines
1816: * (e.g. ixgbe_setup_receive_rings()) map these
1817: * buffers at the end of the NIC ring, so here we
1818: * must set the RDT (tail) register to make sure
1819: * they are not overwritten.
1820: *
1821: * In this driver the NIC ring starts at RDH = 0,
1822: * RDT points to the last slot available for reception (?),
1823: * so RDT = num_rx_desc - 1 means the whole ring is available.
1824: */
1.58 msaitoh 1825: if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) &&
1826: (ifp->if_capenable & IFCAP_NETMAP)) {
1.25 msaitoh 1827: struct netmap_adapter *na = NA(adapter->ifp);
1.117 msaitoh 1828: struct netmap_kring *kring = na->rx_rings[i];
1.25 msaitoh 1829: int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
1830:
1831: IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t);
1832: } else
1833: #endif /* DEV_NETMAP */
1834: IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
1835: adapter->num_rx_desc - 1);
1.1 dyoung 1836: }
1837:
1.58 msaitoh 1838: ixv_initialize_rss_mapping(adapter);
1839: } /* ixv_initialize_receive_units */
1.1 dyoung 1840:
1.58 msaitoh 1841: /************************************************************************
1.83 msaitoh 1842: * ixv_sysctl_tdh_handler - Transmit Descriptor Head handler function
1843: *
1844: * Retrieves the TDH value from the hardware
1845: ************************************************************************/
1.113 msaitoh 1846: static int
1.83 msaitoh 1847: ixv_sysctl_tdh_handler(SYSCTLFN_ARGS)
1848: {
1849: struct sysctlnode node = *rnode;
1850: struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
1851: uint32_t val;
1852:
1853: if (!txr)
1854: return (0);
1855:
1856: val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDH(txr->me));
1857: node.sysctl_data = &val;
1858: return sysctl_lookup(SYSCTLFN_CALL(&node));
1859: } /* ixv_sysctl_tdh_handler */
1860:
1861: /************************************************************************
1862: * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function
1863: *
1864: * Retrieves the TDT value from the hardware
1865: ************************************************************************/
1.113 msaitoh 1866: static int
1.83 msaitoh 1867: ixv_sysctl_tdt_handler(SYSCTLFN_ARGS)
1868: {
1869: struct sysctlnode node = *rnode;
1870: struct tx_ring *txr = (struct tx_ring *)node.sysctl_data;
1871: uint32_t val;
1872:
1873: if (!txr)
1874: return (0);
1875:
1876: val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDT(txr->me));
1877: node.sysctl_data = &val;
1878: return sysctl_lookup(SYSCTLFN_CALL(&node));
1879: } /* ixv_sysctl_tdt_handler */
1880:
1881: /************************************************************************
1.99 msaitoh 1882: * ixv_sysctl_next_to_check_handler - Receive Descriptor next to check
1883: * handler function
1884: *
1885: * Retrieves the next_to_check value
1886: ************************************************************************/
1.113 msaitoh 1887: static int
1.99 msaitoh 1888: ixv_sysctl_next_to_check_handler(SYSCTLFN_ARGS)
1889: {
1890: struct sysctlnode node = *rnode;
1891: struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
1892: uint32_t val;
1893:
1894: if (!rxr)
1895: return (0);
1896:
1897: val = rxr->next_to_check;
1898: node.sysctl_data = &val;
1899: return sysctl_lookup(SYSCTLFN_CALL(&node));
1900: } /* ixv_sysctl_next_to_check_handler */
1901:
1902: /************************************************************************
1.83 msaitoh 1903: * ixv_sysctl_rdh_handler - Receive Descriptor Head handler function
1904: *
1905: * Retrieves the RDH value from the hardware
1906: ************************************************************************/
1.113 msaitoh 1907: static int
1.83 msaitoh 1908: ixv_sysctl_rdh_handler(SYSCTLFN_ARGS)
1909: {
1910: struct sysctlnode node = *rnode;
1911: struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
1912: uint32_t val;
1913:
1914: if (!rxr)
1915: return (0);
1916:
1917: val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDH(rxr->me));
1918: node.sysctl_data = &val;
1919: return sysctl_lookup(SYSCTLFN_CALL(&node));
1920: } /* ixv_sysctl_rdh_handler */
1921:
1922: /************************************************************************
1923: * ixv_sysctl_rdt_handler - Receive Descriptor Tail handler function
1924: *
1925: * Retrieves the RDT value from the hardware
1926: ************************************************************************/
1.113 msaitoh 1927: static int
1.83 msaitoh 1928: ixv_sysctl_rdt_handler(SYSCTLFN_ARGS)
1929: {
1930: struct sysctlnode node = *rnode;
1931: struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data;
1932: uint32_t val;
1933:
1934: if (!rxr)
1935: return (0);
1936:
1937: val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDT(rxr->me));
1938: node.sysctl_data = &val;
1939: return sysctl_lookup(SYSCTLFN_CALL(&node));
1940: } /* ixv_sysctl_rdt_handler */
1941:
1942: /************************************************************************
1.58 msaitoh 1943: * ixv_setup_vlan_support
1944: ************************************************************************/
1.120 ! msaitoh 1945: static int
1.1 dyoung 1946: ixv_setup_vlan_support(struct adapter *adapter)
1947: {
1.65 msaitoh 1948: struct ethercom *ec = &adapter->osdep.ec;
1.1 dyoung 1949: struct ixgbe_hw *hw = &adapter->hw;
1.114 msaitoh 1950: struct rx_ring *rxr;
1.1 dyoung 1951: u32 ctrl, vid, vfta, retry;
1.120 ! msaitoh 1952: struct vlanid_list *vlanidp;
! 1953: int rv, error = 0;
! 1954: bool usevlan;
1.110 msaitoh 1955: bool hwtagging;
1.1 dyoung 1956:
1957: /*
1.110 msaitoh 1958: * This function is called from both if_init and ifflags_cb()
1959: * on NetBSD.
1.58 msaitoh 1960: */
1.120 ! msaitoh 1961: usevlan = VLAN_ATTACHED(ec);
1.110 msaitoh 1962:
1.111 msaitoh 1963: /* Enable HW tagging only if any vlan is attached */
1.110 msaitoh 1964: hwtagging = (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING)
1.111 msaitoh 1965: && VLAN_ATTACHED(ec);
1.1 dyoung 1966:
1967: /* Enable the queues */
1968: for (int i = 0; i < adapter->num_queues; i++) {
1.65 msaitoh 1969: rxr = &adapter->rx_rings[i];
1970: ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(rxr->me));
1.110 msaitoh 1971: if (hwtagging)
1972: ctrl |= IXGBE_RXDCTL_VME;
1973: else
1974: ctrl &= ~IXGBE_RXDCTL_VME;
1.65 msaitoh 1975: IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(rxr->me), ctrl);
1.26 msaitoh 1976: /*
1977: * Let Rx path know that it needs to store VLAN tag
1978: * as part of extra mbuf info.
1979: */
1.110 msaitoh 1980: rxr->vtag_strip = hwtagging ? TRUE : FALSE;
1.1 dyoung 1981: }
1982:
1.120 ! msaitoh 1983: if (!usevlan)
! 1984: return 0;
! 1985:
! 1986: /* Cleanup shadow_vfta */
1.65 msaitoh 1987: for (int i = 0; i < IXGBE_VFTA_SIZE; i++)
1.120 ! msaitoh 1988: adapter->shadow_vfta[i] = 0;
! 1989: /* Generate shadow_vfta from ec_vids */
! 1990: mutex_enter(ec->ec_lock);
! 1991: SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
! 1992: uint32_t idx;
! 1993:
! 1994: idx = vlanidp->vid / 32;
! 1995: KASSERT(idx < IXGBE_VFTA_SIZE);
! 1996: adapter->shadow_vfta[idx] |= 1 << vlanidp->vid % 32;
! 1997: }
! 1998: mutex_exit(ec->ec_lock);
! 1999:
1.1 dyoung 2000: /*
1.58 msaitoh 2001: * A soft reset zero's out the VFTA, so
2002: * we need to repopulate it now.
2003: */
1.21 msaitoh 2004: for (int i = 0; i < IXGBE_VFTA_SIZE; i++) {
1.65 msaitoh 2005: if (adapter->shadow_vfta[i] == 0)
1.1 dyoung 2006: continue;
1.65 msaitoh 2007: vfta = adapter->shadow_vfta[i];
1.1 dyoung 2008: /*
1.58 msaitoh 2009: * Reconstruct the vlan id's
2010: * based on the bits set in each
2011: * of the array ints.
2012: */
1.26 msaitoh 2013: for (int j = 0; j < 32; j++) {
1.1 dyoung 2014: retry = 0;
2015: if ((vfta & (1 << j)) == 0)
2016: continue;
2017: vid = (i * 32) + j;
1.120 ! msaitoh 2018:
1.1 dyoung 2019: /* Call the shared code mailbox routine */
1.120 ! msaitoh 2020: while ((rv = hw->mac.ops.set_vfta(hw, vid, 0, TRUE,
! 2021: FALSE)) != 0) {
! 2022: if (++retry > 5) {
! 2023: device_printf(adapter->dev,
! 2024: "%s: max retry exceeded\n",
! 2025: __func__);
1.1 dyoung 2026: break;
1.120 ! msaitoh 2027: }
! 2028: }
! 2029: if (rv != 0) {
! 2030: device_printf(adapter->dev,
! 2031: "failed to set vlan %d\n", vid);
! 2032: error = EACCES;
1.1 dyoung 2033: }
2034: }
2035: }
1.120 ! msaitoh 2036: return error;
1.58 msaitoh 2037: } /* ixv_setup_vlan_support */
1.1 dyoung 2038:
1.120 ! msaitoh 2039: static int
! 2040: ixv_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
! 2041: {
! 2042: struct ifnet *ifp = &ec->ec_if;
! 2043: int rv;
! 2044:
! 2045: if (set)
! 2046: rv = ixv_register_vlan(ifp->if_softc, ifp, vid);
! 2047: else
! 2048: rv = ixv_unregister_vlan(ifp->if_softc, ifp, vid);
! 2049:
! 2050: return rv;
! 2051: }
! 2052:
1.58 msaitoh 2053: /************************************************************************
2054: * ixv_register_vlan
2055: *
2056: * Run via a vlan config EVENT, it enables us to use the
2057: * HW Filter table since we can get the vlan id. This just
2058: * creates the entry in the soft version of the VFTA, init
2059: * will repopulate the real table.
2060: ************************************************************************/
1.120 ! msaitoh 2061: static int
1.1 dyoung 2062: ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
2063: {
2064: struct adapter *adapter = ifp->if_softc;
1.120 ! msaitoh 2065: struct ixgbe_hw *hw = &adapter->hw;
1.1 dyoung 2066: u16 index, bit;
1.120 ! msaitoh 2067: int error;
1.1 dyoung 2068:
1.26 msaitoh 2069: if (ifp->if_softc != arg) /* Not our event */
1.120 ! msaitoh 2070: return EINVAL;
1.1 dyoung 2071:
1.26 msaitoh 2072: if ((vtag == 0) || (vtag > 4095)) /* Invalid */
1.120 ! msaitoh 2073: return EINVAL;
1.21 msaitoh 2074: IXGBE_CORE_LOCK(adapter);
1.1 dyoung 2075: index = (vtag >> 5) & 0x7F;
2076: bit = vtag & 0x1F;
1.65 msaitoh 2077: adapter->shadow_vfta[index] |= (1 << bit);
1.120 ! msaitoh 2078: error = hw->mac.ops.set_vfta(hw, vtag, 0, true, false);
1.21 msaitoh 2079: IXGBE_CORE_UNLOCK(adapter);
1.120 ! msaitoh 2080:
! 2081: if (error != 0) {
! 2082: device_printf(adapter->dev, "failed to register vlan %hu\n",
! 2083: vtag);
! 2084: error = EACCES;
! 2085: }
! 2086: return error;
1.58 msaitoh 2087: } /* ixv_register_vlan */
1.1 dyoung 2088:
1.58 msaitoh 2089: /************************************************************************
2090: * ixv_unregister_vlan
2091: *
2092: * Run via a vlan unconfig EVENT, remove our entry
2093: * in the soft vfta.
2094: ************************************************************************/
1.120 ! msaitoh 2095: static int
1.1 dyoung 2096: ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
2097: {
2098: struct adapter *adapter = ifp->if_softc;
1.120 ! msaitoh 2099: struct ixgbe_hw *hw = &adapter->hw;
1.1 dyoung 2100: u16 index, bit;
1.120 ! msaitoh 2101: int error;
1.1 dyoung 2102:
2103: if (ifp->if_softc != arg)
1.120 ! msaitoh 2104: return EINVAL;
1.1 dyoung 2105:
1.58 msaitoh 2106: if ((vtag == 0) || (vtag > 4095)) /* Invalid */
1.120 ! msaitoh 2107: return EINVAL;
1.1 dyoung 2108:
1.21 msaitoh 2109: IXGBE_CORE_LOCK(adapter);
1.1 dyoung 2110: index = (vtag >> 5) & 0x7F;
2111: bit = vtag & 0x1F;
1.65 msaitoh 2112: adapter->shadow_vfta[index] &= ~(1 << bit);
1.120 ! msaitoh 2113: error = hw->mac.ops.set_vfta(hw, vtag, 0, false, false);
1.21 msaitoh 2114: IXGBE_CORE_UNLOCK(adapter);
1.120 ! msaitoh 2115:
! 2116: if (error != 0) {
! 2117: device_printf(adapter->dev, "failed to unregister vlan %hu\n",
! 2118: vtag);
! 2119: error = EIO;
! 2120: }
! 2121: return error;
1.58 msaitoh 2122: } /* ixv_unregister_vlan */
1.1 dyoung 2123:
1.58 msaitoh 2124: /************************************************************************
2125: * ixv_enable_intr
2126: ************************************************************************/
1.1 dyoung 2127: static void
2128: ixv_enable_intr(struct adapter *adapter)
2129: {
2130: struct ixgbe_hw *hw = &adapter->hw;
2131: struct ix_queue *que = adapter->queues;
1.114 msaitoh 2132: u32 mask;
1.68 msaitoh 2133: int i;
1.1 dyoung 2134:
1.68 msaitoh 2135: /* For VTEIAC */
2136: mask = (1 << adapter->vector);
2137: for (i = 0; i < adapter->num_queues; i++, que++)
2138: mask |= (1 << que->msix);
1.1 dyoung 2139: IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask);
2140:
1.68 msaitoh 2141: /* For VTEIMS */
2142: IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector));
1.69 msaitoh 2143: que = adapter->queues;
1.68 msaitoh 2144: for (i = 0; i < adapter->num_queues; i++, que++)
1.1 dyoung 2145: ixv_enable_queue(adapter, que->msix);
2146:
2147: IXGBE_WRITE_FLUSH(hw);
1.58 msaitoh 2148: } /* ixv_enable_intr */
1.1 dyoung 2149:
1.58 msaitoh 2150: /************************************************************************
2151: * ixv_disable_intr
2152: ************************************************************************/
1.1 dyoung 2153: static void
2154: ixv_disable_intr(struct adapter *adapter)
2155: {
1.82 knakahar 2156: struct ix_queue *que = adapter->queues;
2157:
1.1 dyoung 2158: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0);
1.82 knakahar 2159:
2160: /* disable interrupts other than queues */
2161: IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, adapter->vector);
2162:
2163: for (int i = 0; i < adapter->num_queues; i++, que++)
2164: ixv_disable_queue(adapter, que->msix);
2165:
1.1 dyoung 2166: IXGBE_WRITE_FLUSH(&adapter->hw);
1.58 msaitoh 2167: } /* ixv_disable_intr */
1.1 dyoung 2168:
1.58 msaitoh 2169: /************************************************************************
2170: * ixv_set_ivar
2171: *
2172: * Setup the correct IVAR register for a particular MSI-X interrupt
2173: * - entry is the register array entry
2174: * - vector is the MSI-X vector for this queue
2175: * - type is RX/TX/MISC
2176: ************************************************************************/
1.1 dyoung 2177: static void
2178: ixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
2179: {
2180: struct ixgbe_hw *hw = &adapter->hw;
1.114 msaitoh 2181: u32 ivar, index;
1.1 dyoung 2182:
2183: vector |= IXGBE_IVAR_ALLOC_VAL;
2184:
2185: if (type == -1) { /* MISC IVAR */
2186: ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
2187: ivar &= ~0xFF;
2188: ivar |= vector;
2189: IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar);
1.114 msaitoh 2190: } else { /* RX/TX IVARS */
1.1 dyoung 2191: index = (16 * (entry & 1)) + (8 * type);
2192: ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1));
2193: ivar &= ~(0xFF << index);
2194: ivar |= (vector << index);
2195: IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar);
2196: }
1.58 msaitoh 2197: } /* ixv_set_ivar */
1.1 dyoung 2198:
1.58 msaitoh 2199: /************************************************************************
2200: * ixv_configure_ivars
2201: ************************************************************************/
1.1 dyoung 2202: static void
2203: ixv_configure_ivars(struct adapter *adapter)
2204: {
1.58 msaitoh 2205: struct ix_queue *que = adapter->queues;
1.1 dyoung 2206:
1.80 msaitoh 2207: /* XXX We should sync EITR value calculation with ixgbe.c? */
2208:
1.57 msaitoh 2209: for (int i = 0; i < adapter->num_queues; i++, que++) {
1.1 dyoung 2210: /* First the RX queue entry */
1.57 msaitoh 2211: ixv_set_ivar(adapter, i, que->msix, 0);
1.1 dyoung 2212: /* ... and the TX */
2213: ixv_set_ivar(adapter, i, que->msix, 1);
2214: /* Set an initial value in EITR */
1.95 msaitoh 2215: ixv_eitr_write(adapter, que->msix, IXGBE_EITR_DEFAULT);
1.1 dyoung 2216: }
2217:
1.21 msaitoh 2218: /* For the mailbox interrupt */
1.57 msaitoh 2219: ixv_set_ivar(adapter, 1, adapter->vector, -1);
1.58 msaitoh 2220: } /* ixv_configure_ivars */
1.1 dyoung 2221:
2222:
1.58 msaitoh 2223: /************************************************************************
2224: * ixv_save_stats
2225: *
2226: * The VF stats registers never have a truly virgin
2227: * starting point, so this routine tries to make an
2228: * artificial one, marking ground zero on attach as
2229: * it were.
2230: ************************************************************************/
1.1 dyoung 2231: static void
2232: ixv_save_stats(struct adapter *adapter)
2233: {
1.21 msaitoh 2234: struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
2235:
2236: if (stats->vfgprc.ev_count || stats->vfgptc.ev_count) {
2237: stats->saved_reset_vfgprc +=
2238: stats->vfgprc.ev_count - stats->base_vfgprc;
2239: stats->saved_reset_vfgptc +=
2240: stats->vfgptc.ev_count - stats->base_vfgptc;
2241: stats->saved_reset_vfgorc +=
2242: stats->vfgorc.ev_count - stats->base_vfgorc;
2243: stats->saved_reset_vfgotc +=
2244: stats->vfgotc.ev_count - stats->base_vfgotc;
2245: stats->saved_reset_vfmprc +=
2246: stats->vfmprc.ev_count - stats->base_vfmprc;
1.1 dyoung 2247: }
1.58 msaitoh 2248: } /* ixv_save_stats */
1.63 msaitoh 2249:
1.58 msaitoh 2250: /************************************************************************
2251: * ixv_init_stats
2252: ************************************************************************/
1.1 dyoung 2253: static void
2254: ixv_init_stats(struct adapter *adapter)
2255: {
2256: struct ixgbe_hw *hw = &adapter->hw;
1.57 msaitoh 2257:
1.21 msaitoh 2258: adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
2259: adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
2260: adapter->stats.vf.last_vfgorc |=
1.1 dyoung 2261: (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
2262:
1.21 msaitoh 2263: adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
2264: adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
2265: adapter->stats.vf.last_vfgotc |=
1.1 dyoung 2266: (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
2267:
1.21 msaitoh 2268: adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
1.1 dyoung 2269:
1.21 msaitoh 2270: adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc;
2271: adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc;
2272: adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc;
2273: adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc;
2274: adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc;
1.58 msaitoh 2275: } /* ixv_init_stats */
1.1 dyoung 2276:
2277: #define UPDATE_STAT_32(reg, last, count) \
1.114 msaitoh 2278: { \
1.58 msaitoh 2279: u32 current = IXGBE_READ_REG(hw, (reg)); \
2280: if (current < (last)) \
1.21 msaitoh 2281: count.ev_count += 0x100000000LL; \
1.58 msaitoh 2282: (last) = current; \
1.21 msaitoh 2283: count.ev_count &= 0xFFFFFFFF00000000LL; \
2284: count.ev_count |= current; \
1.1 dyoung 2285: }
2286:
1.114 msaitoh 2287: #define UPDATE_STAT_36(lsb, msb, last, count) \
2288: { \
1.58 msaitoh 2289: u64 cur_lsb = IXGBE_READ_REG(hw, (lsb)); \
2290: u64 cur_msb = IXGBE_READ_REG(hw, (msb)); \
1.114 msaitoh 2291: u64 current = ((cur_msb << 32) | cur_lsb); \
1.58 msaitoh 2292: if (current < (last)) \
1.21 msaitoh 2293: count.ev_count += 0x1000000000LL; \
1.58 msaitoh 2294: (last) = current; \
1.21 msaitoh 2295: count.ev_count &= 0xFFFFFFF000000000LL; \
2296: count.ev_count |= current; \
1.1 dyoung 2297: }
2298:
1.58 msaitoh 2299: /************************************************************************
2300: * ixv_update_stats - Update the board statistics counters.
2301: ************************************************************************/
1.1 dyoung 2302: void
2303: ixv_update_stats(struct adapter *adapter)
2304: {
1.63 msaitoh 2305: struct ixgbe_hw *hw = &adapter->hw;
1.58 msaitoh 2306: struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.1 dyoung 2307:
1.88 msaitoh 2308: UPDATE_STAT_32(IXGBE_VFGPRC, stats->last_vfgprc, stats->vfgprc);
2309: UPDATE_STAT_32(IXGBE_VFGPTC, stats->last_vfgptc, stats->vfgptc);
2310: UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB, stats->last_vfgorc,
1.58 msaitoh 2311: stats->vfgorc);
1.88 msaitoh 2312: UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB, stats->last_vfgotc,
1.58 msaitoh 2313: stats->vfgotc);
1.88 msaitoh 2314: UPDATE_STAT_32(IXGBE_VFMPRC, stats->last_vfmprc, stats->vfmprc);
1.58 msaitoh 2315:
2316: /* Fill out the OS statistics structure */
2317: /*
2318: * NetBSD: Don't override if_{i|o}{packets|bytes|mcasts} with
2319: * adapter->stats counters. It's required to make ifconfig -z
2320: * (SOICZIFDATA) work.
2321: */
2322: } /* ixv_update_stats */
1.1 dyoung 2323:
1.83 msaitoh 2324: /************************************************************************
2325: * ixv_sysctl_interrupt_rate_handler
2326: ************************************************************************/
2327: static int
2328: ixv_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS)
2329: {
2330: struct sysctlnode node = *rnode;
2331: struct ix_queue *que = (struct ix_queue *)node.sysctl_data;
1.114 msaitoh 2332: struct adapter *adapter = que->adapter;
1.83 msaitoh 2333: uint32_t reg, usec, rate;
2334: int error;
2335:
2336: if (que == NULL)
2337: return 0;
2338: reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_VTEITR(que->msix));
2339: usec = ((reg & 0x0FF8) >> 3);
2340: if (usec > 0)
2341: rate = 500000 / usec;
2342: else
2343: rate = 0;
2344: node.sysctl_data = &rate;
2345: error = sysctl_lookup(SYSCTLFN_CALL(&node));
2346: if (error || newp == NULL)
2347: return error;
2348: reg &= ~0xfff; /* default, no limitation */
2349: if (rate > 0 && rate < 500000) {
2350: if (rate < 1000)
2351: rate = 1000;
2352: reg |= ((4000000/rate) & 0xff8);
2353: /*
2354: * When RSC is used, ITR interval must be larger than
2355: * RSC_DELAY. Currently, we use 2us for RSC_DELAY.
2356: * The minimum value is always greater than 2us on 100M
2357: * (and 10M?(not documented)), but it's not on 1G and higher.
2358: */
2359: if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL)
2360: && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) {
2361: if ((adapter->num_queues > 1)
2362: && (reg < IXGBE_MIN_RSC_EITR_10G1G))
2363: return EINVAL;
2364: }
2365: ixv_max_interrupt_rate = rate;
2366: } else
2367: ixv_max_interrupt_rate = 0;
1.95 msaitoh 2368: ixv_eitr_write(adapter, que->msix, reg);
1.83 msaitoh 2369:
2370: return (0);
2371: } /* ixv_sysctl_interrupt_rate_handler */
2372:
1.3 msaitoh 2373: const struct sysctlnode *
2374: ixv_sysctl_instance(struct adapter *adapter)
2375: {
2376: const char *dvname;
2377: struct sysctllog **log;
2378: int rc;
2379: const struct sysctlnode *rnode;
2380:
2381: log = &adapter->sysctllog;
2382: dvname = device_xname(adapter->dev);
2383:
2384: if ((rc = sysctl_createv(log, 0, NULL, &rnode,
2385: 0, CTLTYPE_NODE, dvname,
2386: SYSCTL_DESCR("ixv information and settings"),
2387: NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
2388: goto err;
2389:
2390: return rnode;
2391: err:
2392: printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
2393: return NULL;
2394: }
1.48 msaitoh 2395:
2396: static void
2397: ixv_add_device_sysctls(struct adapter *adapter)
2398: {
2399: struct sysctllog **log;
2400: const struct sysctlnode *rnode, *cnode;
2401: device_t dev;
2402:
2403: dev = adapter->dev;
2404: log = &adapter->sysctllog;
2405:
2406: if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
2407: aprint_error_dev(dev, "could not create sysctl root\n");
2408: return;
2409: }
2410:
2411: if (sysctl_createv(log, 0, &rnode, &cnode,
2412: CTLFLAG_READWRITE, CTLTYPE_INT,
2413: "debug", SYSCTL_DESCR("Debug Info"),
2414: ixv_sysctl_debug, 0, (void *)adapter, 0, CTL_CREATE, CTL_EOL) != 0)
2415: aprint_error_dev(dev, "could not create sysctl\n");
2416:
2417: if (sysctl_createv(log, 0, &rnode, &cnode,
1.50 msaitoh 2418: CTLFLAG_READWRITE, CTLTYPE_BOOL,
1.48 msaitoh 2419: "enable_aim", SYSCTL_DESCR("Interrupt Moderation"),
1.50 msaitoh 2420: NULL, 0, &adapter->enable_aim, 0, CTL_CREATE, CTL_EOL) != 0)
1.48 msaitoh 2421: aprint_error_dev(dev, "could not create sysctl\n");
1.84 knakahar 2422:
2423: if (sysctl_createv(log, 0, &rnode, &cnode,
2424: CTLFLAG_READWRITE, CTLTYPE_BOOL,
2425: "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"),
2426: NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL) != 0)
2427: aprint_error_dev(dev, "could not create sysctl\n");
1.48 msaitoh 2428: }
2429:
1.58 msaitoh 2430: /************************************************************************
2431: * ixv_add_stats_sysctls - Add statistic sysctls for the VF.
2432: ************************************************************************/
1.48 msaitoh 2433: static void
2434: ixv_add_stats_sysctls(struct adapter *adapter)
2435: {
1.114 msaitoh 2436: device_t dev = adapter->dev;
2437: struct tx_ring *txr = adapter->tx_rings;
2438: struct rx_ring *rxr = adapter->rx_rings;
1.58 msaitoh 2439: struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
1.67 msaitoh 2440: struct ixgbe_hw *hw = &adapter->hw;
1.83 msaitoh 2441: const struct sysctlnode *rnode, *cnode;
1.49 msaitoh 2442: struct sysctllog **log = &adapter->sysctllog;
1.48 msaitoh 2443: const char *xname = device_xname(dev);
2444:
2445: /* Driver Statistics */
1.49 msaitoh 2446: evcnt_attach_dynamic(&adapter->efbig_tx_dma_setup, EVCNT_TYPE_MISC,
2447: NULL, xname, "Driver tx dma soft fail EFBIG");
1.48 msaitoh 2448: evcnt_attach_dynamic(&adapter->mbuf_defrag_failed, EVCNT_TYPE_MISC,
2449: NULL, xname, "m_defrag() failed");
1.49 msaitoh 2450: evcnt_attach_dynamic(&adapter->efbig2_tx_dma_setup, EVCNT_TYPE_MISC,
2451: NULL, xname, "Driver tx dma hard fail EFBIG");
2452: evcnt_attach_dynamic(&adapter->einval_tx_dma_setup, EVCNT_TYPE_MISC,
2453: NULL, xname, "Driver tx dma hard fail EINVAL");
2454: evcnt_attach_dynamic(&adapter->other_tx_dma_setup, EVCNT_TYPE_MISC,
2455: NULL, xname, "Driver tx dma hard fail other");
2456: evcnt_attach_dynamic(&adapter->eagain_tx_dma_setup, EVCNT_TYPE_MISC,
2457: NULL, xname, "Driver tx dma soft fail EAGAIN");
2458: evcnt_attach_dynamic(&adapter->enomem_tx_dma_setup, EVCNT_TYPE_MISC,
2459: NULL, xname, "Driver tx dma soft fail ENOMEM");
1.48 msaitoh 2460: evcnt_attach_dynamic(&adapter->watchdog_events, EVCNT_TYPE_MISC,
2461: NULL, xname, "Watchdog timeouts");
1.49 msaitoh 2462: evcnt_attach_dynamic(&adapter->tso_err, EVCNT_TYPE_MISC,
2463: NULL, xname, "TSO errors");
2464: evcnt_attach_dynamic(&adapter->link_irq, EVCNT_TYPE_INTR,
1.58 msaitoh 2465: NULL, xname, "Link MSI-X IRQ Handled");
1.49 msaitoh 2466:
2467: for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
2468: snprintf(adapter->queues[i].evnamebuf,
2469: sizeof(adapter->queues[i].evnamebuf), "%s q%d",
2470: xname, i);
2471: snprintf(adapter->queues[i].namebuf,
2472: sizeof(adapter->queues[i].namebuf), "q%d", i);
2473:
2474: if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
2475: aprint_error_dev(dev, "could not create sysctl root\n");
2476: break;
2477: }
2478:
2479: if (sysctl_createv(log, 0, &rnode, &rnode,
2480: 0, CTLTYPE_NODE,
2481: adapter->queues[i].namebuf, SYSCTL_DESCR("Queue Name"),
2482: NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
2483: break;
2484:
2485: if (sysctl_createv(log, 0, &rnode, &cnode,
2486: CTLFLAG_READWRITE, CTLTYPE_INT,
2487: "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"),
1.83 msaitoh 2488: ixv_sysctl_interrupt_rate_handler, 0,
1.49 msaitoh 2489: (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0)
2490: break;
2491:
2492: if (sysctl_createv(log, 0, &rnode, &cnode,
2493: CTLFLAG_READONLY, CTLTYPE_INT,
2494: "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"),
1.83 msaitoh 2495: ixv_sysctl_tdh_handler, 0, (void *)txr,
1.49 msaitoh 2496: 0, CTL_CREATE, CTL_EOL) != 0)
2497: break;
2498:
2499: if (sysctl_createv(log, 0, &rnode, &cnode,
2500: CTLFLAG_READONLY, CTLTYPE_INT,
2501: "txd_tail", SYSCTL_DESCR("Transmit Descriptor Tail"),
1.83 msaitoh 2502: ixv_sysctl_tdt_handler, 0, (void *)txr,
1.49 msaitoh 2503: 0, CTL_CREATE, CTL_EOL) != 0)
2504: break;
1.83 msaitoh 2505:
1.49 msaitoh 2506: evcnt_attach_dynamic(&adapter->queues[i].irqs, EVCNT_TYPE_INTR,
2507: NULL, adapter->queues[i].evnamebuf, "IRQs on queue");
1.85 msaitoh 2508: evcnt_attach_dynamic(&adapter->queues[i].handleq,
2509: EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf,
2510: "Handled queue in softint");
2511: evcnt_attach_dynamic(&adapter->queues[i].req, EVCNT_TYPE_MISC,
2512: NULL, adapter->queues[i].evnamebuf, "Requeued in softint");
1.49 msaitoh 2513: evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC,
2514: NULL, adapter->queues[i].evnamebuf, "TSO");
2515: evcnt_attach_dynamic(&txr->no_desc_avail, EVCNT_TYPE_MISC,
2516: NULL, adapter->queues[i].evnamebuf,
2517: "Queue No Descriptor Available");
2518: evcnt_attach_dynamic(&txr->total_packets, EVCNT_TYPE_MISC,
2519: NULL, adapter->queues[i].evnamebuf,
2520: "Queue Packets Transmitted");
2521: #ifndef IXGBE_LEGACY_TX
2522: evcnt_attach_dynamic(&txr->pcq_drops, EVCNT_TYPE_MISC,
2523: NULL, adapter->queues[i].evnamebuf,
2524: "Packets dropped in pcq");
2525: #endif
2526:
2527: #ifdef LRO
2528: struct lro_ctrl *lro = &rxr->lro;
2529: #endif /* LRO */
2530:
2531: if (sysctl_createv(log, 0, &rnode, &cnode,
2532: CTLFLAG_READONLY,
2533: CTLTYPE_INT,
1.99 msaitoh 2534: "rxd_nxck", SYSCTL_DESCR("Receive Descriptor next to check"),
2535: ixv_sysctl_next_to_check_handler, 0, (void *)rxr, 0,
2536: CTL_CREATE, CTL_EOL) != 0)
2537: break;
2538:
2539: if (sysctl_createv(log, 0, &rnode, &cnode,
2540: CTLFLAG_READONLY,
2541: CTLTYPE_INT,
1.49 msaitoh 2542: "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"),
1.83 msaitoh 2543: ixv_sysctl_rdh_handler, 0, (void *)rxr, 0,
1.49 msaitoh 2544: CTL_CREATE, CTL_EOL) != 0)
2545: break;
2546:
2547: if (sysctl_createv(log, 0, &rnode, &cnode,
2548: CTLFLAG_READONLY,
2549: CTLTYPE_INT,
2550: "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"),
1.83 msaitoh 2551: ixv_sysctl_rdt_handler, 0, (void *)rxr, 0,
1.49 msaitoh 2552: CTL_CREATE, CTL_EOL) != 0)
2553: break;
2554:
2555: evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC,
2556: NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");
2557: evcnt_attach_dynamic(&rxr->rx_bytes, EVCNT_TYPE_MISC,
2558: NULL, adapter->queues[i].evnamebuf, "Queue Bytes Received");
2559: evcnt_attach_dynamic(&rxr->rx_copies, EVCNT_TYPE_MISC,
2560: NULL, adapter->queues[i].evnamebuf, "Copied RX Frames");
2561: evcnt_attach_dynamic(&rxr->no_jmbuf, EVCNT_TYPE_MISC,
2562: NULL, adapter->queues[i].evnamebuf, "Rx no jumbo mbuf");
2563: evcnt_attach_dynamic(&rxr->rx_discarded, EVCNT_TYPE_MISC,
2564: NULL, adapter->queues[i].evnamebuf, "Rx discarded");
2565: #ifdef LRO
2566: SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_queued",
2567: CTLFLAG_RD, &lro->lro_queued, 0,
2568: "LRO Queued");
2569: SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO, "lro_flushed",
2570: CTLFLAG_RD, &lro->lro_flushed, 0,
2571: "LRO Flushed");
2572: #endif /* LRO */
2573: }
2574:
1.58 msaitoh 2575: /* MAC stats get their own sub node */
1.49 msaitoh 2576:
2577: snprintf(stats->namebuf,
2578: sizeof(stats->namebuf), "%s MAC Statistics", xname);
2579:
2580: evcnt_attach_dynamic(&stats->ipcs, EVCNT_TYPE_MISC, NULL,
2581: stats->namebuf, "rx csum offload - IP");
2582: evcnt_attach_dynamic(&stats->l4cs, EVCNT_TYPE_MISC, NULL,
2583: stats->namebuf, "rx csum offload - L4");
2584: evcnt_attach_dynamic(&stats->ipcs_bad, EVCNT_TYPE_MISC, NULL,
2585: stats->namebuf, "rx csum offload - IP bad");
2586: evcnt_attach_dynamic(&stats->l4cs_bad, EVCNT_TYPE_MISC, NULL,
2587: stats->namebuf, "rx csum offload - L4 bad");
1.48 msaitoh 2588:
1.49 msaitoh 2589: /* Packet Reception Stats */
1.48 msaitoh 2590: evcnt_attach_dynamic(&stats->vfgprc, EVCNT_TYPE_MISC, NULL,
2591: xname, "Good Packets Received");
2592: evcnt_attach_dynamic(&stats->vfgorc, EVCNT_TYPE_MISC, NULL,
2593: xname, "Good Octets Received");
2594: evcnt_attach_dynamic(&stats->vfmprc, EVCNT_TYPE_MISC, NULL,
2595: xname, "Multicast Packets Received");
2596: evcnt_attach_dynamic(&stats->vfgptc, EVCNT_TYPE_MISC, NULL,
2597: xname, "Good Packets Transmitted");
2598: evcnt_attach_dynamic(&stats->vfgotc, EVCNT_TYPE_MISC, NULL,
2599: xname, "Good Octets Transmitted");
1.67 msaitoh 2600:
2601: /* Mailbox Stats */
2602: evcnt_attach_dynamic(&hw->mbx.stats.msgs_tx, EVCNT_TYPE_MISC, NULL,
2603: xname, "message TXs");
2604: evcnt_attach_dynamic(&hw->mbx.stats.msgs_rx, EVCNT_TYPE_MISC, NULL,
2605: xname, "message RXs");
2606: evcnt_attach_dynamic(&hw->mbx.stats.acks, EVCNT_TYPE_MISC, NULL,
2607: xname, "ACKs");
2608: evcnt_attach_dynamic(&hw->mbx.stats.reqs, EVCNT_TYPE_MISC, NULL,
2609: xname, "REQs");
2610: evcnt_attach_dynamic(&hw->mbx.stats.rsts, EVCNT_TYPE_MISC, NULL,
2611: xname, "RSTs");
2612:
1.58 msaitoh 2613: } /* ixv_add_stats_sysctls */
1.48 msaitoh 2614:
1.58 msaitoh 2615: /************************************************************************
2616: * ixv_set_sysctl_value
2617: ************************************************************************/
1.48 msaitoh 2618: static void
2619: ixv_set_sysctl_value(struct adapter *adapter, const char *name,
2620: const char *description, int *limit, int value)
2621: {
1.114 msaitoh 2622: device_t dev = adapter->dev;
1.48 msaitoh 2623: struct sysctllog **log;
2624: const struct sysctlnode *rnode, *cnode;
2625:
2626: log = &adapter->sysctllog;
2627: if ((rnode = ixv_sysctl_instance(adapter)) == NULL) {
2628: aprint_error_dev(dev, "could not create sysctl root\n");
2629: return;
2630: }
2631: if (sysctl_createv(log, 0, &rnode, &cnode,
2632: CTLFLAG_READWRITE, CTLTYPE_INT,
2633: name, SYSCTL_DESCR(description),
2634: NULL, 0, limit, 0, CTL_CREATE, CTL_EOL) != 0)
2635: aprint_error_dev(dev, "could not create sysctl\n");
2636: *limit = value;
1.58 msaitoh 2637: } /* ixv_set_sysctl_value */
1.57 msaitoh 2638:
1.58 msaitoh 2639: /************************************************************************
2640: * ixv_print_debug_info
1.57 msaitoh 2641: *
1.58 msaitoh 2642: * Called only when em_display_debug_stats is enabled.
2643: * Provides a way to take a look at important statistics
2644: * maintained by the driver and hardware.
2645: ************************************************************************/
1.57 msaitoh 2646: static void
2647: ixv_print_debug_info(struct adapter *adapter)
2648: {
1.114 msaitoh 2649: device_t dev = adapter->dev;
2650: struct ix_queue *que = adapter->queues;
2651: struct rx_ring *rxr;
2652: struct tx_ring *txr;
1.57 msaitoh 2653: #ifdef LRO
1.114 msaitoh 2654: struct lro_ctrl *lro;
1.57 msaitoh 2655: #endif /* LRO */
2656:
1.58 msaitoh 2657: for (int i = 0; i < adapter->num_queues; i++, que++) {
2658: txr = que->txr;
2659: rxr = que->rxr;
1.57 msaitoh 2660: #ifdef LRO
1.58 msaitoh 2661: lro = &rxr->lro;
1.57 msaitoh 2662: #endif /* LRO */
1.63 msaitoh 2663: device_printf(dev, "QUE(%d) IRQs Handled: %lu\n",
1.58 msaitoh 2664: que->msix, (long)que->irqs.ev_count);
1.63 msaitoh 2665: device_printf(dev, "RX(%d) Packets Received: %lld\n",
1.58 msaitoh 2666: rxr->me, (long long)rxr->rx_packets.ev_count);
1.63 msaitoh 2667: device_printf(dev, "RX(%d) Bytes Received: %lu\n",
1.58 msaitoh 2668: rxr->me, (long)rxr->rx_bytes.ev_count);
1.57 msaitoh 2669: #ifdef LRO
1.117 msaitoh 2670: device_printf(dev, "RX(%d) LRO Queued= %ju\n",
2671: rxr->me, (uintmax_t)lro->lro_queued);
2672: device_printf(dev, "RX(%d) LRO Flushed= %ju\n",
2673: rxr->me, (uintmax_t)lro->lro_flushed);
1.57 msaitoh 2674: #endif /* LRO */
1.63 msaitoh 2675: device_printf(dev, "TX(%d) Packets Sent: %lu\n",
1.58 msaitoh 2676: txr->me, (long)txr->total_packets.ev_count);
1.63 msaitoh 2677: device_printf(dev, "TX(%d) NO Desc Avail: %lu\n",
1.58 msaitoh 2678: txr->me, (long)txr->no_desc_avail.ev_count);
2679: }
1.57 msaitoh 2680:
1.58 msaitoh 2681: device_printf(dev, "MBX IRQ Handled: %lu\n",
2682: (long)adapter->link_irq.ev_count);
2683: } /* ixv_print_debug_info */
2684:
2685: /************************************************************************
2686: * ixv_sysctl_debug
2687: ************************************************************************/
1.57 msaitoh 2688: static int
2689: ixv_sysctl_debug(SYSCTLFN_ARGS)
2690: {
1.97 msaitoh 2691: struct sysctlnode node = *rnode;
2692: struct adapter *adapter = (struct adapter *)node.sysctl_data;
1.114 msaitoh 2693: int error, result;
1.57 msaitoh 2694:
2695: node.sysctl_data = &result;
2696: error = sysctl_lookup(SYSCTLFN_CALL(&node));
2697:
1.58 msaitoh 2698: if (error || newp == NULL)
1.57 msaitoh 2699: return error;
2700:
1.97 msaitoh 2701: if (result == 1)
1.57 msaitoh 2702: ixv_print_debug_info(adapter);
2703:
2704: return 0;
1.58 msaitoh 2705: } /* ixv_sysctl_debug */
2706:
2707: /************************************************************************
2708: * ixv_init_device_features
2709: ************************************************************************/
2710: static void
2711: ixv_init_device_features(struct adapter *adapter)
2712: {
2713: adapter->feat_cap = IXGBE_FEATURE_NETMAP
1.114 msaitoh 2714: | IXGBE_FEATURE_VF
2715: | IXGBE_FEATURE_RSS
2716: | IXGBE_FEATURE_LEGACY_TX;
1.58 msaitoh 2717:
2718: /* A tad short on feature flags for VFs, atm. */
2719: switch (adapter->hw.mac.type) {
2720: case ixgbe_mac_82599_vf:
2721: break;
2722: case ixgbe_mac_X540_vf:
2723: break;
2724: case ixgbe_mac_X550_vf:
2725: case ixgbe_mac_X550EM_x_vf:
2726: case ixgbe_mac_X550EM_a_vf:
2727: adapter->feat_cap |= IXGBE_FEATURE_NEEDS_CTXD;
2728: break;
2729: default:
2730: break;
2731: }
1.57 msaitoh 2732:
1.58 msaitoh 2733: /* Enabled by default... */
2734: /* Is a virtual function (VF) */
2735: if (adapter->feat_cap & IXGBE_FEATURE_VF)
2736: adapter->feat_en |= IXGBE_FEATURE_VF;
2737: /* Netmap */
2738: if (adapter->feat_cap & IXGBE_FEATURE_NETMAP)
2739: adapter->feat_en |= IXGBE_FEATURE_NETMAP;
2740: /* Receive-Side Scaling (RSS) */
2741: if (adapter->feat_cap & IXGBE_FEATURE_RSS)
2742: adapter->feat_en |= IXGBE_FEATURE_RSS;
2743: /* Needs advanced context descriptor regardless of offloads req'd */
2744: if (adapter->feat_cap & IXGBE_FEATURE_NEEDS_CTXD)
2745: adapter->feat_en |= IXGBE_FEATURE_NEEDS_CTXD;
2746:
2747: /* Enabled via sysctl... */
2748: /* Legacy (single queue) transmit */
2749: if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) &&
2750: ixv_enable_legacy_tx)
2751: adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX;
2752: } /* ixv_init_device_features */
2753:
2754: /************************************************************************
2755: * ixv_shutdown - Shutdown entry point
2756: ************************************************************************/
1.57 msaitoh 2757: #if 0 /* XXX NetBSD ought to register something like this through pmf(9) */
2758: static int
2759: ixv_shutdown(device_t dev)
2760: {
2761: struct adapter *adapter = device_private(dev);
2762: IXGBE_CORE_LOCK(adapter);
2763: ixv_stop(adapter);
2764: IXGBE_CORE_UNLOCK(adapter);
2765:
2766: return (0);
1.58 msaitoh 2767: } /* ixv_shutdown */
1.57 msaitoh 2768: #endif
2769:
2770: static int
2771: ixv_ifflags_cb(struct ethercom *ec)
2772: {
2773: struct ifnet *ifp = &ec->ec_if;
2774: struct adapter *adapter = ifp->if_softc;
1.118 msaitoh 2775: int change, rv = 0;
1.57 msaitoh 2776:
2777: IXGBE_CORE_LOCK(adapter);
2778:
1.93 msaitoh 2779: change = ifp->if_flags ^ adapter->if_flags;
1.57 msaitoh 2780: if (change != 0)
2781: adapter->if_flags = ifp->if_flags;
2782:
1.118 msaitoh 2783: if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) {
2784: rv = ENETRESET;
2785: goto out;
2786: }
1.57 msaitoh 2787:
1.120 ! msaitoh 2788: /* Check for ec_capenable. */
! 2789: change = ec->ec_capenable ^ adapter->ec_capenable;
! 2790: adapter->ec_capenable = ec->ec_capenable;
! 2791: if ((change & ~(ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING
! 2792: | ETHERCAP_VLAN_HWFILTER)) != 0) {
! 2793: rv = ENETRESET;
! 2794: goto out;
! 2795: }
! 2796:
! 2797: /*
! 2798: * Special handling is not required for ETHERCAP_VLAN_MTU.
! 2799: * PF's MAXFRS(MHADD) does not include the 4bytes of the VLAN header.
! 2800: */
! 2801:
1.65 msaitoh 2802: /* Set up VLAN support and filter */
1.120 ! msaitoh 2803: if ((change & (ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_HWFILTER)) != 0)
! 2804: rv = ixv_setup_vlan_support(adapter);
1.65 msaitoh 2805:
1.118 msaitoh 2806: out:
1.57 msaitoh 2807: IXGBE_CORE_UNLOCK(adapter);
2808:
1.118 msaitoh 2809: return rv;
1.57 msaitoh 2810: }
2811:
1.58 msaitoh 2812:
2813: /************************************************************************
2814: * ixv_ioctl - Ioctl entry point
1.57 msaitoh 2815: *
1.58 msaitoh 2816: * Called when the user wants to configure the interface.
1.57 msaitoh 2817: *
1.58 msaitoh 2818: * return 0 on success, positive on failure
2819: ************************************************************************/
1.57 msaitoh 2820: static int
1.58 msaitoh 2821: ixv_ioctl(struct ifnet *ifp, u_long command, void *data)
1.57 msaitoh 2822: {
2823: struct adapter *adapter = ifp->if_softc;
2824: struct ifcapreq *ifcr = data;
1.114 msaitoh 2825: int error = 0;
1.57 msaitoh 2826: int l4csum_en;
1.113 msaitoh 2827: const int l4csum = IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
2828: IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx;
1.57 msaitoh 2829:
2830: switch (command) {
2831: case SIOCSIFFLAGS:
2832: IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
2833: break;
2834: case SIOCADDMULTI:
2835: case SIOCDELMULTI:
2836: IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
2837: break;
2838: case SIOCSIFMEDIA:
2839: case SIOCGIFMEDIA:
2840: IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
2841: break;
2842: case SIOCSIFCAP:
2843: IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
2844: break;
2845: case SIOCSIFMTU:
2846: IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
2847: break;
2848: default:
2849: IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)", (int)command);
2850: break;
2851: }
2852:
2853: switch (command) {
2854: case SIOCSIFCAP:
2855: /* Layer-4 Rx checksum offload has to be turned on and
2856: * off as a unit.
2857: */
2858: l4csum_en = ifcr->ifcr_capenable & l4csum;
2859: if (l4csum_en != l4csum && l4csum_en != 0)
2860: return EINVAL;
2861: /*FALLTHROUGH*/
2862: case SIOCADDMULTI:
2863: case SIOCDELMULTI:
2864: case SIOCSIFFLAGS:
2865: case SIOCSIFMTU:
2866: default:
2867: if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
2868: return error;
2869: if ((ifp->if_flags & IFF_RUNNING) == 0)
2870: ;
2871: else if (command == SIOCSIFCAP || command == SIOCSIFMTU) {
2872: IXGBE_CORE_LOCK(adapter);
2873: ixv_init_locked(adapter);
2874: IXGBE_CORE_UNLOCK(adapter);
2875: } else if (command == SIOCADDMULTI || command == SIOCDELMULTI) {
2876: /*
2877: * Multicast list has changed; set the hardware filter
2878: * accordingly.
2879: */
2880: IXGBE_CORE_LOCK(adapter);
2881: ixv_disable_intr(adapter);
2882: ixv_set_multi(adapter);
2883: ixv_enable_intr(adapter);
2884: IXGBE_CORE_UNLOCK(adapter);
2885: }
2886: return 0;
2887: }
1.58 msaitoh 2888: } /* ixv_ioctl */
1.57 msaitoh 2889:
1.58 msaitoh 2890: /************************************************************************
2891: * ixv_init
2892: ************************************************************************/
1.57 msaitoh 2893: static int
2894: ixv_init(struct ifnet *ifp)
2895: {
2896: struct adapter *adapter = ifp->if_softc;
2897:
2898: IXGBE_CORE_LOCK(adapter);
2899: ixv_init_locked(adapter);
2900: IXGBE_CORE_UNLOCK(adapter);
2901:
2902: return 0;
1.58 msaitoh 2903: } /* ixv_init */
1.57 msaitoh 2904:
1.58 msaitoh 2905: /************************************************************************
2906: * ixv_handle_que
2907: ************************************************************************/
1.57 msaitoh 2908: static void
2909: ixv_handle_que(void *context)
2910: {
2911: struct ix_queue *que = context;
1.114 msaitoh 2912: struct adapter *adapter = que->adapter;
1.57 msaitoh 2913: struct tx_ring *txr = que->txr;
1.114 msaitoh 2914: struct ifnet *ifp = adapter->ifp;
1.57 msaitoh 2915: bool more;
2916:
1.85 msaitoh 2917: que->handleq.ev_count++;
1.57 msaitoh 2918:
2919: if (ifp->if_flags & IFF_RUNNING) {
2920: more = ixgbe_rxeof(que);
2921: IXGBE_TX_LOCK(txr);
1.81 msaitoh 2922: more |= ixgbe_txeof(txr);
1.58 msaitoh 2923: if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX))
2924: if (!ixgbe_mq_ring_empty(ifp, txr->txr_interq))
2925: ixgbe_mq_start_locked(ifp, txr);
1.57 msaitoh 2926: /* Only for queue 0 */
1.61 msaitoh 2927: /* NetBSD still needs this for CBQ */
1.57 msaitoh 2928: if ((&adapter->queues[0] == que)
1.58 msaitoh 2929: && (!ixgbe_legacy_ring_empty(ifp, NULL)))
2930: ixgbe_legacy_start_locked(ifp, txr);
1.57 msaitoh 2931: IXGBE_TX_UNLOCK(txr);
2932: if (more) {
1.85 msaitoh 2933: que->req.ev_count++;
1.84 knakahar 2934: if (adapter->txrx_use_workqueue) {
2935: /*
2936: * "enqueued flag" is not required here
2937: * the same as ixg(4). See ixgbe_msix_que().
2938: */
2939: workqueue_enqueue(adapter->que_wq,
2940: &que->wq_cookie, curcpu());
2941: } else
2942: softint_schedule(que->que_si);
1.57 msaitoh 2943: return;
2944: }
2945: }
2946:
1.58 msaitoh 2947: /* Re-enable this interrupt */
1.57 msaitoh 2948: ixv_enable_queue(adapter, que->msix);
2949:
2950: return;
1.58 msaitoh 2951: } /* ixv_handle_que */
1.57 msaitoh 2952:
1.58 msaitoh 2953: /************************************************************************
1.84 knakahar 2954: * ixv_handle_que_work
2955: ************************************************************************/
2956: static void
2957: ixv_handle_que_work(struct work *wk, void *context)
2958: {
2959: struct ix_queue *que = container_of(wk, struct ix_queue, wq_cookie);
2960:
2961: /*
2962: * "enqueued flag" is not required here the same as ixg(4).
2963: * See ixgbe_msix_que().
2964: */
2965: ixv_handle_que(que);
2966: }
2967:
2968: /************************************************************************
1.58 msaitoh 2969: * ixv_allocate_msix - Setup MSI-X Interrupt resources and handlers
2970: ************************************************************************/
1.57 msaitoh 2971: static int
2972: ixv_allocate_msix(struct adapter *adapter, const struct pci_attach_args *pa)
2973: {
2974: device_t dev = adapter->dev;
2975: struct ix_queue *que = adapter->queues;
1.98 msaitoh 2976: struct tx_ring *txr = adapter->tx_rings;
1.114 msaitoh 2977: int error, msix_ctrl, rid, vector = 0;
1.57 msaitoh 2978: pci_chipset_tag_t pc;
2979: pcitag_t tag;
2980: char intrbuf[PCI_INTRSTR_LEN];
1.84 knakahar 2981: char wqname[MAXCOMLEN];
1.57 msaitoh 2982: char intr_xname[32];
2983: const char *intrstr = NULL;
2984: kcpuset_t *affinity;
2985: int cpu_id = 0;
2986:
2987: pc = adapter->osdep.pc;
2988: tag = adapter->osdep.tag;
2989:
2990: adapter->osdep.nintrs = adapter->num_queues + 1;
2991: if (pci_msix_alloc_exact(pa, &adapter->osdep.intrs,
2992: adapter->osdep.nintrs) != 0) {
2993: aprint_error_dev(dev,
2994: "failed to allocate MSI-X interrupt\n");
2995: return (ENXIO);
2996: }
2997:
2998: kcpuset_create(&affinity, false);
2999: for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
3000: snprintf(intr_xname, sizeof(intr_xname), "%s TXRX%d",
3001: device_xname(dev), i);
3002: intrstr = pci_intr_string(pc, adapter->osdep.intrs[i], intrbuf,
3003: sizeof(intrbuf));
3004: #ifdef IXGBE_MPSAFE
3005: pci_intr_setattr(pc, &adapter->osdep.intrs[i], PCI_INTR_MPSAFE,
3006: true);
3007: #endif
3008: /* Set the handler function */
3009: que->res = adapter->osdep.ihs[i] = pci_intr_establish_xname(pc,
3010: adapter->osdep.intrs[i], IPL_NET, ixv_msix_que, que,
3011: intr_xname);
3012: if (que->res == NULL) {
3013: pci_intr_release(pc, adapter->osdep.intrs,
3014: adapter->osdep.nintrs);
3015: aprint_error_dev(dev,
3016: "Failed to register QUE handler\n");
3017: kcpuset_destroy(affinity);
3018: return (ENXIO);
3019: }
3020: que->msix = vector;
1.114 msaitoh 3021: adapter->active_queues |= (u64)(1 << que->msix);
1.57 msaitoh 3022:
3023: cpu_id = i;
3024: /* Round-robin affinity */
3025: kcpuset_zero(affinity);
3026: kcpuset_set(affinity, cpu_id % ncpu);
3027: error = interrupt_distribute(adapter->osdep.ihs[i], affinity,
3028: NULL);
3029: aprint_normal_dev(dev, "for TX/RX, interrupting at %s",
3030: intrstr);
3031: if (error == 0)
3032: aprint_normal(", bound queue %d to cpu %d\n",
3033: i, cpu_id % ncpu);
3034: else
3035: aprint_normal("\n");
3036:
3037: #ifndef IXGBE_LEGACY_TX
3038: txr->txr_si
3039: = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
3040: ixgbe_deferred_mq_start, txr);
3041: #endif
3042: que->que_si
3043: = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
3044: ixv_handle_que, que);
3045: if (que->que_si == NULL) {
3046: aprint_error_dev(dev,
1.113 msaitoh 3047: "could not establish software interrupt\n");
1.57 msaitoh 3048: }
3049: }
1.84 knakahar 3050: snprintf(wqname, sizeof(wqname), "%sdeferTx", device_xname(dev));
3051: error = workqueue_create(&adapter->txr_wq, wqname,
3052: ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
3053: IXGBE_WORKQUEUE_FLAGS);
3054: if (error) {
3055: aprint_error_dev(dev, "couldn't create workqueue for deferred Tx\n");
3056: }
3057: adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
3058:
3059: snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(dev));
3060: error = workqueue_create(&adapter->que_wq, wqname,
3061: ixv_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
3062: IXGBE_WORKQUEUE_FLAGS);
3063: if (error) {
3064: aprint_error_dev(dev,
3065: "couldn't create workqueue\n");
3066: }
1.57 msaitoh 3067:
3068: /* and Mailbox */
3069: cpu_id++;
3070: snprintf(intr_xname, sizeof(intr_xname), "%s link", device_xname(dev));
1.77 msaitoh 3071: adapter->vector = vector;
1.57 msaitoh 3072: intrstr = pci_intr_string(pc, adapter->osdep.intrs[vector], intrbuf,
3073: sizeof(intrbuf));
3074: #ifdef IXGBE_MPSAFE
3075: pci_intr_setattr(pc, &adapter->osdep.intrs[vector], PCI_INTR_MPSAFE,
3076: true);
3077: #endif
3078: /* Set the mbx handler function */
3079: adapter->osdep.ihs[vector] = pci_intr_establish_xname(pc,
3080: adapter->osdep.intrs[vector], IPL_NET, ixv_msix_mbx, adapter,
3081: intr_xname);
3082: if (adapter->osdep.ihs[vector] == NULL) {
3083: aprint_error_dev(dev, "Failed to register LINK handler\n");
3084: kcpuset_destroy(affinity);
3085: return (ENXIO);
3086: }
3087: /* Round-robin affinity */
3088: kcpuset_zero(affinity);
3089: kcpuset_set(affinity, cpu_id % ncpu);
1.113 msaitoh 3090: error = interrupt_distribute(adapter->osdep.ihs[vector],
3091: affinity, NULL);
1.57 msaitoh 3092:
3093: aprint_normal_dev(dev,
3094: "for link, interrupting at %s", intrstr);
3095: if (error == 0)
3096: aprint_normal(", affinity to cpu %d\n", cpu_id % ncpu);
3097: else
3098: aprint_normal("\n");
3099:
3100: /* Tasklets for Mailbox */
3101: adapter->link_si = softint_establish(SOFTINT_NET |IXGBE_SOFTINFT_FLAGS,
1.58 msaitoh 3102: ixv_handle_link, adapter);
1.57 msaitoh 3103: /*
1.58 msaitoh 3104: * Due to a broken design QEMU will fail to properly
3105: * enable the guest for MSI-X unless the vectors in
3106: * the table are all set up, so we must rewrite the
3107: * ENABLE in the MSI-X control register again at this
3108: * point to cause it to successfully initialize us.
3109: */
1.57 msaitoh 3110: if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
3111: pci_get_capability(pc, tag, PCI_CAP_MSIX, &rid, NULL);
3112: rid += PCI_MSIX_CTL;
3113: msix_ctrl = pci_conf_read(pc, tag, rid);
3114: msix_ctrl |= PCI_MSIX_CTL_ENABLE;
3115: pci_conf_write(pc, tag, rid, msix_ctrl);
3116: }
3117:
3118: kcpuset_destroy(affinity);
3119: return (0);
1.58 msaitoh 3120: } /* ixv_allocate_msix */
1.57 msaitoh 3121:
1.58 msaitoh 3122: /************************************************************************
3123: * ixv_configure_interrupts - Setup MSI-X resources
3124: *
3125: * Note: The VF device MUST use MSI-X, there is no fallback.
3126: ************************************************************************/
1.57 msaitoh 3127: static int
1.58 msaitoh 3128: ixv_configure_interrupts(struct adapter *adapter)
1.57 msaitoh 3129: {
3130: device_t dev = adapter->dev;
3131: int want, queues, msgs;
3132:
1.58 msaitoh 3133: /* Must have at least 2 MSI-X vectors */
1.57 msaitoh 3134: msgs = pci_msix_count(adapter->osdep.pc, adapter->osdep.tag);
3135: if (msgs < 2) {
1.63 msaitoh 3136: aprint_error_dev(dev, "MSIX config error\n");
1.57 msaitoh 3137: return (ENXIO);
3138: }
3139: msgs = MIN(msgs, IXG_MAX_NINTR);
3140:
3141: /* Figure out a reasonable auto config value */
3142: queues = (ncpu > (msgs - 1)) ? (msgs - 1) : ncpu;
3143:
3144: if (ixv_num_queues != 0)
3145: queues = ixv_num_queues;
3146: else if ((ixv_num_queues == 0) && (queues > IXGBE_VF_MAX_TX_QUEUES))
3147: queues = IXGBE_VF_MAX_TX_QUEUES;
3148:
3149: /*
1.58 msaitoh 3150: * Want vectors for the queues,
3151: * plus an additional for mailbox.
3152: */
1.57 msaitoh 3153: want = queues + 1;
3154: if (msgs >= want)
3155: msgs = want;
3156: else {
1.114 msaitoh 3157: aprint_error_dev(dev,
1.58 msaitoh 3158: "MSI-X Configuration Problem, "
1.57 msaitoh 3159: "%d vectors but %d queues wanted!\n",
3160: msgs, want);
3161: return -1;
3162: }
3163:
3164: adapter->msix_mem = (void *)1; /* XXX */
3165: aprint_normal_dev(dev,
1.58 msaitoh 3166: "Using MSI-X interrupts with %d vectors\n", msgs);
1.57 msaitoh 3167: adapter->num_queues = queues;
3168:
1.58 msaitoh 3169: return (0);
3170: } /* ixv_configure_interrupts */
3171:
3172:
3173: /************************************************************************
3174: * ixv_handle_link - Tasklet handler for MSI-X MBX interrupts
3175: *
3176: * Done outside of interrupt context since the driver might sleep
3177: ************************************************************************/
1.57 msaitoh 3178: static void
1.58 msaitoh 3179: ixv_handle_link(void *context)
1.57 msaitoh 3180: {
1.58 msaitoh 3181: struct adapter *adapter = context;
1.57 msaitoh 3182:
1.89 knakahar 3183: IXGBE_CORE_LOCK(adapter);
3184:
1.58 msaitoh 3185: adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed,
3186: &adapter->link_up, FALSE);
1.57 msaitoh 3187: ixv_update_link_status(adapter);
1.89 knakahar 3188:
3189: IXGBE_CORE_UNLOCK(adapter);
1.58 msaitoh 3190: } /* ixv_handle_link */
1.57 msaitoh 3191:
1.58 msaitoh 3192: /************************************************************************
3193: * ixv_check_link - Used in the local timer to poll for link changes
3194: ************************************************************************/
1.117 msaitoh 3195: static s32
1.58 msaitoh 3196: ixv_check_link(struct adapter *adapter)
1.57 msaitoh 3197: {
1.117 msaitoh 3198: s32 error;
1.89 knakahar 3199:
3200: KASSERT(mutex_owned(&adapter->core_mtx));
3201:
1.58 msaitoh 3202: adapter->hw.mac.get_link_status = TRUE;
1.57 msaitoh 3203:
1.117 msaitoh 3204: error = adapter->hw.mac.ops.check_link(&adapter->hw,
3205: &adapter->link_speed, &adapter->link_up, FALSE);
1.58 msaitoh 3206: ixv_update_link_status(adapter);
1.117 msaitoh 3207:
3208: return error;
1.58 msaitoh 3209: } /* ixv_check_link */
CVSweb <webmaster@jp.NetBSD.org>