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