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