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