1280182Sjfv/******************************************************************************
2280182Sjfv
3280182Sjfv  Copyright (c) 2001-2015, Intel Corporation
4280182Sjfv  All rights reserved.
5280182Sjfv
6280182Sjfv  Redistribution and use in source and binary forms, with or without
7280182Sjfv  modification, are permitted provided that the following conditions are met:
8280182Sjfv
9280182Sjfv   1. Redistributions of source code must retain the above copyright notice,
10280182Sjfv      this list of conditions and the following disclaimer.
11280182Sjfv
12280182Sjfv   2. Redistributions in binary form must reproduce the above copyright
13280182Sjfv      notice, this list of conditions and the following disclaimer in the
14280182Sjfv      documentation and/or other materials provided with the distribution.
15280182Sjfv
16280182Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17280182Sjfv      contributors may be used to endorse or promote products derived from
18280182Sjfv      this software without specific prior written permission.
19280182Sjfv
20280182Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21280182Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22280182Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23280182Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24280182Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25280182Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26280182Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27280182Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28280182Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29280182Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30280182Sjfv  POSSIBILITY OF SUCH DAMAGE.
31280182Sjfv
32280182Sjfv******************************************************************************/
33280182Sjfv/*$FreeBSD: releng/10.3/sys/dev/ixgbe/if_ixv.c 295524 2016-02-11 16:16:10Z sbruno $*/
34280182Sjfv
35280182Sjfv
36280182Sjfv#ifndef IXGBE_STANDALONE_BUILD
37280182Sjfv#include "opt_inet.h"
38280182Sjfv#include "opt_inet6.h"
39280182Sjfv#endif
40280182Sjfv
41280182Sjfv#include "ixgbe.h"
42280182Sjfv
43280182Sjfv/*********************************************************************
44280182Sjfv *  Driver version
45280182Sjfv *********************************************************************/
46295524Ssbrunochar ixv_driver_version[] = "1.4.6-k";
47280182Sjfv
48280182Sjfv/*********************************************************************
49280182Sjfv *  PCI Device ID Table
50280182Sjfv *
51280182Sjfv *  Used by probe to select devices to load on
52280182Sjfv *  Last field stores an index into ixv_strings
53280182Sjfv *  Last entry must be all 0s
54280182Sjfv *
55280182Sjfv *  { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
56280182Sjfv *********************************************************************/
57280182Sjfv
58280182Sjfvstatic ixgbe_vendor_info_t ixv_vendor_info_array[] =
59280182Sjfv{
60280182Sjfv	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0},
61280182Sjfv	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0},
62280182Sjfv	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0},
63280182Sjfv	{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0},
64280182Sjfv	/* required last entry */
65280182Sjfv	{0, 0, 0, 0, 0}
66280182Sjfv};
67280182Sjfv
68280182Sjfv/*********************************************************************
69280182Sjfv *  Table of branding strings
70280182Sjfv *********************************************************************/
71280182Sjfv
72280182Sjfvstatic char    *ixv_strings[] = {
73280182Sjfv	"Intel(R) PRO/10GbE Virtual Function Network Driver"
74280182Sjfv};
75280182Sjfv
76280182Sjfv/*********************************************************************
77280182Sjfv *  Function prototypes
78280182Sjfv *********************************************************************/
79280182Sjfvstatic int      ixv_probe(device_t);
80280182Sjfvstatic int      ixv_attach(device_t);
81280182Sjfvstatic int      ixv_detach(device_t);
82280182Sjfvstatic int      ixv_shutdown(device_t);
83280182Sjfvstatic int      ixv_ioctl(struct ifnet *, u_long, caddr_t);
84280182Sjfvstatic void	ixv_init(void *);
85280182Sjfvstatic void	ixv_init_locked(struct adapter *);
86280182Sjfvstatic void     ixv_stop(void *);
87280182Sjfvstatic void     ixv_media_status(struct ifnet *, struct ifmediareq *);
88280182Sjfvstatic int      ixv_media_change(struct ifnet *);
89280182Sjfvstatic void     ixv_identify_hardware(struct adapter *);
90280182Sjfvstatic int      ixv_allocate_pci_resources(struct adapter *);
91280182Sjfvstatic int      ixv_allocate_msix(struct adapter *);
92280182Sjfvstatic int	ixv_setup_msix(struct adapter *);
93280182Sjfvstatic void	ixv_free_pci_resources(struct adapter *);
94280182Sjfvstatic void     ixv_local_timer(void *);
95280182Sjfvstatic void     ixv_setup_interface(device_t, struct adapter *);
96280182Sjfvstatic void     ixv_config_link(struct adapter *);
97280182Sjfv
98280182Sjfvstatic void     ixv_initialize_transmit_units(struct adapter *);
99280182Sjfvstatic void     ixv_initialize_receive_units(struct adapter *);
100280182Sjfv
101280182Sjfvstatic void     ixv_enable_intr(struct adapter *);
102280182Sjfvstatic void     ixv_disable_intr(struct adapter *);
103280182Sjfvstatic void     ixv_set_multi(struct adapter *);
104280182Sjfvstatic void     ixv_update_link_status(struct adapter *);
105280182Sjfvstatic int	ixv_sysctl_debug(SYSCTL_HANDLER_ARGS);
106280182Sjfvstatic void	ixv_set_ivar(struct adapter *, u8, u8, s8);
107280182Sjfvstatic void	ixv_configure_ivars(struct adapter *);
108280182Sjfvstatic u8 *	ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
109280182Sjfv
110280182Sjfvstatic void	ixv_setup_vlan_support(struct adapter *);
111280182Sjfvstatic void	ixv_register_vlan(void *, struct ifnet *, u16);
112280182Sjfvstatic void	ixv_unregister_vlan(void *, struct ifnet *, u16);
113280182Sjfv
114280182Sjfvstatic void	ixv_save_stats(struct adapter *);
115280182Sjfvstatic void	ixv_init_stats(struct adapter *);
116280182Sjfvstatic void	ixv_update_stats(struct adapter *);
117280182Sjfvstatic void	ixv_add_stats_sysctls(struct adapter *);
118294034Ssbrunostatic void	ixv_set_sysctl_value(struct adapter *, const char *,
119294034Ssbruno		    const char *, int *, int);
120280182Sjfv
121280182Sjfv/* The MSI/X Interrupt handlers */
122280182Sjfvstatic void	ixv_msix_que(void *);
123280182Sjfvstatic void	ixv_msix_mbx(void *);
124280182Sjfv
125280182Sjfv/* Deferred interrupt tasklets */
126280182Sjfvstatic void	ixv_handle_que(void *, int);
127280182Sjfvstatic void	ixv_handle_mbx(void *, int);
128280182Sjfv
129295008Ssbruno#ifdef DEV_NETMAP
130295008Ssbruno/*
131295008Ssbruno * This is defined in <dev/netmap/ixgbe_netmap.h>, which is included by
132295008Ssbruno * if_ix.c.
133295008Ssbruno */
134295008Ssbrunoextern void ixgbe_netmap_attach(struct adapter *adapter);
135295008Ssbruno
136295008Ssbruno#include <net/netmap.h>
137295008Ssbruno#include <sys/selinfo.h>
138295008Ssbruno#include <dev/netmap/netmap_kern.h>
139295008Ssbruno#endif /* DEV_NETMAP */
140295008Ssbruno
141280182Sjfv/*********************************************************************
142280182Sjfv *  FreeBSD Device Interface Entry Points
143280182Sjfv *********************************************************************/
144280182Sjfv
145280182Sjfvstatic device_method_t ixv_methods[] = {
146280182Sjfv	/* Device interface */
147280182Sjfv	DEVMETHOD(device_probe, ixv_probe),
148280182Sjfv	DEVMETHOD(device_attach, ixv_attach),
149280182Sjfv	DEVMETHOD(device_detach, ixv_detach),
150280182Sjfv	DEVMETHOD(device_shutdown, ixv_shutdown),
151280182Sjfv	DEVMETHOD_END
152280182Sjfv};
153280182Sjfv
154280182Sjfvstatic driver_t ixv_driver = {
155280182Sjfv	"ixv", ixv_methods, sizeof(struct adapter),
156280182Sjfv};
157280182Sjfv
158283620Serjdevclass_t ixv_devclass;
159283620SerjDRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0);
160280182SjfvMODULE_DEPEND(ixv, pci, 1, 1, 1);
161280182SjfvMODULE_DEPEND(ixv, ether, 1, 1, 1);
162295008Ssbruno#ifdef DEV_NETMAP
163295008SsbrunoMODULE_DEPEND(ix, netmap, 1, 1, 1);
164295008Ssbruno#endif /* DEV_NETMAP */
165283620Serj/* XXX depend on 'ix' ? */
166280182Sjfv
167280182Sjfv/*
168280182Sjfv** TUNEABLE PARAMETERS:
169280182Sjfv*/
170280182Sjfv
171295008Ssbruno/* Number of Queues - do not exceed MSIX vectors - 1 */
172295008Ssbrunostatic int ixv_num_queues = 1;
173295008SsbrunoTUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues);
174295008Ssbruno
175280182Sjfv/*
176280182Sjfv** AIM: Adaptive Interrupt Moderation
177280182Sjfv** which means that the interrupt rate
178280182Sjfv** is varied over time based on the
179280182Sjfv** traffic for that interrupt vector
180280182Sjfv*/
181280182Sjfvstatic int ixv_enable_aim = FALSE;
182280182SjfvTUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim);
183280182Sjfv
184280182Sjfv/* How many packets rxeof tries to clean at a time */
185280182Sjfvstatic int ixv_rx_process_limit = 256;
186280182SjfvTUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit);
187280182Sjfv
188280182Sjfv/* How many packets txeof tries to clean at a time */
189280182Sjfvstatic int ixv_tx_process_limit = 256;
190280182SjfvTUNABLE_INT("hw.ixv.tx_process_limit", &ixv_tx_process_limit);
191280182Sjfv
192280182Sjfv/* Flow control setting, default to full */
193280182Sjfvstatic int ixv_flow_control = ixgbe_fc_full;
194280182SjfvTUNABLE_INT("hw.ixv.flow_control", &ixv_flow_control);
195280182Sjfv
196280182Sjfv/*
197280182Sjfv * Header split: this causes the hardware to DMA
198280182Sjfv * the header into a seperate mbuf from the payload,
199280182Sjfv * it can be a performance win in some workloads, but
200280182Sjfv * in others it actually hurts, its off by default.
201280182Sjfv */
202280182Sjfvstatic int ixv_header_split = FALSE;
203280182SjfvTUNABLE_INT("hw.ixv.hdr_split", &ixv_header_split);
204280182Sjfv
205280182Sjfv/*
206280182Sjfv** Number of TX descriptors per ring,
207280182Sjfv** setting higher than RX as this seems
208280182Sjfv** the better performing choice.
209280182Sjfv*/
210280182Sjfvstatic int ixv_txd = DEFAULT_TXD;
211280182SjfvTUNABLE_INT("hw.ixv.txd", &ixv_txd);
212280182Sjfv
213280182Sjfv/* Number of RX descriptors per ring */
214280182Sjfvstatic int ixv_rxd = DEFAULT_RXD;
215280182SjfvTUNABLE_INT("hw.ixv.rxd", &ixv_rxd);
216280182Sjfv
217280182Sjfv/*
218280182Sjfv** Shadow VFTA table, this is needed because
219280182Sjfv** the real filter table gets cleared during
220280182Sjfv** a soft reset and we need to repopulate it.
221280182Sjfv*/
222280182Sjfvstatic u32 ixv_shadow_vfta[IXGBE_VFTA_SIZE];
223280182Sjfv
224280182Sjfv/*********************************************************************
225280182Sjfv *  Device identification routine
226280182Sjfv *
227280182Sjfv *  ixv_probe determines if the driver should be loaded on
228280182Sjfv *  adapter based on PCI vendor/device id of the adapter.
229280182Sjfv *
230280182Sjfv *  return BUS_PROBE_DEFAULT on success, positive on failure
231280182Sjfv *********************************************************************/
232280182Sjfv
233280182Sjfvstatic int
234280182Sjfvixv_probe(device_t dev)
235280182Sjfv{
236280182Sjfv	ixgbe_vendor_info_t *ent;
237280182Sjfv
238280182Sjfv	u16	pci_vendor_id = 0;
239280182Sjfv	u16	pci_device_id = 0;
240280182Sjfv	u16	pci_subvendor_id = 0;
241280182Sjfv	u16	pci_subdevice_id = 0;
242280182Sjfv	char	adapter_name[256];
243280182Sjfv
244280182Sjfv
245280182Sjfv	pci_vendor_id = pci_get_vendor(dev);
246280182Sjfv	if (pci_vendor_id != IXGBE_INTEL_VENDOR_ID)
247280182Sjfv		return (ENXIO);
248280182Sjfv
249280182Sjfv	pci_device_id = pci_get_device(dev);
250280182Sjfv	pci_subvendor_id = pci_get_subvendor(dev);
251280182Sjfv	pci_subdevice_id = pci_get_subdevice(dev);
252280182Sjfv
253280182Sjfv	ent = ixv_vendor_info_array;
254280182Sjfv	while (ent->vendor_id != 0) {
255280182Sjfv		if ((pci_vendor_id == ent->vendor_id) &&
256280182Sjfv		    (pci_device_id == ent->device_id) &&
257280182Sjfv
258280182Sjfv		    ((pci_subvendor_id == ent->subvendor_id) ||
259280182Sjfv		     (ent->subvendor_id == 0)) &&
260280182Sjfv
261280182Sjfv		    ((pci_subdevice_id == ent->subdevice_id) ||
262280182Sjfv		     (ent->subdevice_id == 0))) {
263280182Sjfv			sprintf(adapter_name, "%s, Version - %s",
264280182Sjfv				ixv_strings[ent->index],
265280182Sjfv				ixv_driver_version);
266280182Sjfv			device_set_desc_copy(dev, adapter_name);
267280182Sjfv			return (BUS_PROBE_DEFAULT);
268280182Sjfv		}
269280182Sjfv		ent++;
270280182Sjfv	}
271280182Sjfv	return (ENXIO);
272280182Sjfv}
273280182Sjfv
274280182Sjfv/*********************************************************************
275280182Sjfv *  Device initialization routine
276280182Sjfv *
277280182Sjfv *  The attach entry point is called when the driver is being loaded.
278280182Sjfv *  This routine identifies the type of hardware, allocates all resources
279280182Sjfv *  and initializes the hardware.
280280182Sjfv *
281280182Sjfv *  return 0 on success, positive on failure
282280182Sjfv *********************************************************************/
283280182Sjfv
284280182Sjfvstatic int
285280182Sjfvixv_attach(device_t dev)
286280182Sjfv{
287280182Sjfv	struct adapter *adapter;
288280182Sjfv	struct ixgbe_hw *hw;
289280182Sjfv	int             error = 0;
290280182Sjfv
291280182Sjfv	INIT_DEBUGOUT("ixv_attach: begin");
292280182Sjfv
293280182Sjfv	/* Allocate, clear, and link in our adapter structure */
294280182Sjfv	adapter = device_get_softc(dev);
295295524Ssbruno	adapter->dev = dev;
296280182Sjfv	hw = &adapter->hw;
297280182Sjfv
298295524Ssbruno#ifdef DEV_NETMAP
299295524Ssbruno	adapter->init_locked = ixv_init_locked;
300295524Ssbruno	adapter->stop_locked = ixv_stop;
301295524Ssbruno#endif
302295524Ssbruno
303280182Sjfv	/* Core Lock Init*/
304280182Sjfv	IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
305280182Sjfv
306280182Sjfv	/* SYSCTL APIs */
307280182Sjfv	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
308280182Sjfv			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
309280182Sjfv			OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW,
310280182Sjfv			adapter, 0, ixv_sysctl_debug, "I", "Debug Info");
311280182Sjfv
312280182Sjfv	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
313280182Sjfv			SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
314283620Serj			OID_AUTO, "enable_aim", CTLFLAG_RW,
315280182Sjfv			&ixv_enable_aim, 1, "Interrupt Moderation");
316280182Sjfv
317280182Sjfv	/* Set up the timer callout */
318280182Sjfv	callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
319280182Sjfv
320280182Sjfv	/* Determine hardware revision */
321280182Sjfv	ixv_identify_hardware(adapter);
322280182Sjfv
323280182Sjfv	/* Do base PCI setup - map BAR0 */
324280182Sjfv	if (ixv_allocate_pci_resources(adapter)) {
325295524Ssbruno		device_printf(dev, "ixv_allocate_pci_resources() failed!\n");
326280182Sjfv		error = ENXIO;
327280182Sjfv		goto err_out;
328280182Sjfv	}
329280182Sjfv
330294034Ssbruno	/* Sysctls for limiting the amount of work done in the taskqueues */
331294034Ssbruno	ixv_set_sysctl_value(adapter, "rx_processing_limit",
332294034Ssbruno	    "max number of rx packets to process",
333294034Ssbruno	    &adapter->rx_process_limit, ixv_rx_process_limit);
334294034Ssbruno
335294034Ssbruno	ixv_set_sysctl_value(adapter, "tx_processing_limit",
336294034Ssbruno	    "max number of tx packets to process",
337294034Ssbruno	    &adapter->tx_process_limit, ixv_tx_process_limit);
338294034Ssbruno
339295008Ssbruno	/* Sysctls for limiting the amount of work done in the taskqueues */
340295008Ssbruno	ixv_set_sysctl_value(adapter, "rx_processing_limit",
341295008Ssbruno	    "max number of rx packets to process",
342295008Ssbruno	    &adapter->rx_process_limit, ixv_rx_process_limit);
343295008Ssbruno
344295008Ssbruno	ixv_set_sysctl_value(adapter, "tx_processing_limit",
345295008Ssbruno	    "max number of tx packets to process",
346295008Ssbruno	    &adapter->tx_process_limit, ixv_tx_process_limit);
347295008Ssbruno
348280182Sjfv	/* Do descriptor calc and sanity checks */
349280182Sjfv	if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 ||
350280182Sjfv	    ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) {
351280182Sjfv		device_printf(dev, "TXD config issue, using default!\n");
352280182Sjfv		adapter->num_tx_desc = DEFAULT_TXD;
353280182Sjfv	} else
354280182Sjfv		adapter->num_tx_desc = ixv_txd;
355280182Sjfv
356280182Sjfv	if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 ||
357280182Sjfv	    ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) {
358280182Sjfv		device_printf(dev, "RXD config issue, using default!\n");
359280182Sjfv		adapter->num_rx_desc = DEFAULT_RXD;
360280182Sjfv	} else
361280182Sjfv		adapter->num_rx_desc = ixv_rxd;
362280182Sjfv
363280182Sjfv	/* Allocate our TX/RX Queues */
364280182Sjfv	if (ixgbe_allocate_queues(adapter)) {
365295524Ssbruno		device_printf(dev, "ixgbe_allocate_queues() failed!\n");
366280182Sjfv		error = ENOMEM;
367280182Sjfv		goto err_out;
368280182Sjfv	}
369280182Sjfv
370280182Sjfv	/*
371280182Sjfv	** Initialize the shared code: its
372280182Sjfv	** at this point the mac type is set.
373280182Sjfv	*/
374280182Sjfv	error = ixgbe_init_shared_code(hw);
375280182Sjfv	if (error) {
376295524Ssbruno		device_printf(dev, "ixgbe_init_shared_code() failed!\n");
377280182Sjfv		error = EIO;
378280182Sjfv		goto err_late;
379280182Sjfv	}
380280182Sjfv
381280182Sjfv	/* Setup the mailbox */
382280182Sjfv	ixgbe_init_mbx_params_vf(hw);
383280182Sjfv
384295524Ssbruno	/* Reset mbox api to 1.0 */
385295524Ssbruno	error = ixgbe_reset_hw(hw);
386295524Ssbruno	if (error == IXGBE_ERR_RESET_FAILED)
387295524Ssbruno		device_printf(dev, "ixgbe_reset_hw() failure: Reset Failed!\n");
388295524Ssbruno	else if (error)
389295524Ssbruno		device_printf(dev, "ixgbe_reset_hw() failed with error %d\n", error);
390295524Ssbruno	if (error) {
391295524Ssbruno		error = EIO;
392295524Ssbruno		goto err_late;
393295524Ssbruno	}
394280182Sjfv
395295524Ssbruno	/* Negotiate mailbox API version */
396295524Ssbruno	error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11);
397295524Ssbruno	if (error) {
398295524Ssbruno		device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error);
399295524Ssbruno		error = EIO;
400295524Ssbruno		goto err_late;
401295524Ssbruno	}
402295008Ssbruno
403280182Sjfv	error = ixgbe_init_hw(hw);
404280182Sjfv	if (error) {
405295524Ssbruno		device_printf(dev, "ixgbe_init_hw() failed!\n");
406280182Sjfv		error = EIO;
407280182Sjfv		goto err_late;
408280182Sjfv	}
409280182Sjfv
410280182Sjfv	error = ixv_allocate_msix(adapter);
411295524Ssbruno	if (error) {
412295524Ssbruno		device_printf(dev, "ixv_allocate_msix() failed!\n");
413280182Sjfv		goto err_late;
414295524Ssbruno	}
415280182Sjfv
416280182Sjfv	/* If no mac address was assigned, make a random one */
417280182Sjfv	if (!ixv_check_ether_addr(hw->mac.addr)) {
418280182Sjfv		u8 addr[ETHER_ADDR_LEN];
419280182Sjfv		arc4rand(&addr, sizeof(addr), 0);
420280182Sjfv		addr[0] &= 0xFE;
421280182Sjfv		addr[0] |= 0x02;
422280182Sjfv		bcopy(addr, hw->mac.addr, sizeof(addr));
423280182Sjfv	}
424280182Sjfv
425280182Sjfv	/* Setup OS specific network interface */
426280182Sjfv	ixv_setup_interface(dev, adapter);
427280182Sjfv
428280182Sjfv	/* Do the stats setup */
429280182Sjfv	ixv_save_stats(adapter);
430280182Sjfv	ixv_init_stats(adapter);
431280182Sjfv	ixv_add_stats_sysctls(adapter);
432280182Sjfv
433280182Sjfv	/* Register for VLAN events */
434280182Sjfv	adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
435280182Sjfv	    ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
436280182Sjfv	adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
437280182Sjfv	    ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
438280182Sjfv
439295008Ssbruno#ifdef DEV_NETMAP
440295008Ssbruno	ixgbe_netmap_attach(adapter);
441295008Ssbruno#endif /* DEV_NETMAP */
442280182Sjfv	INIT_DEBUGOUT("ixv_attach: end");
443280182Sjfv	return (0);
444280182Sjfv
445280182Sjfverr_late:
446280182Sjfv	ixgbe_free_transmit_structures(adapter);
447280182Sjfv	ixgbe_free_receive_structures(adapter);
448280182Sjfverr_out:
449280182Sjfv	ixv_free_pci_resources(adapter);
450280182Sjfv	return (error);
451280182Sjfv
452280182Sjfv}
453280182Sjfv
454280182Sjfv/*********************************************************************
455280182Sjfv *  Device removal routine
456280182Sjfv *
457280182Sjfv *  The detach entry point is called when the driver is being removed.
458280182Sjfv *  This routine stops the adapter and deallocates all the resources
459280182Sjfv *  that were allocated for driver operation.
460280182Sjfv *
461280182Sjfv *  return 0 on success, positive on failure
462280182Sjfv *********************************************************************/
463280182Sjfv
464280182Sjfvstatic int
465280182Sjfvixv_detach(device_t dev)
466280182Sjfv{
467280182Sjfv	struct adapter *adapter = device_get_softc(dev);
468280182Sjfv	struct ix_queue *que = adapter->queues;
469280182Sjfv
470280182Sjfv	INIT_DEBUGOUT("ixv_detach: begin");
471280182Sjfv
472280182Sjfv	/* Make sure VLANS are not using driver */
473280182Sjfv	if (adapter->ifp->if_vlantrunk != NULL) {
474295524Ssbruno		device_printf(dev, "Vlan in use, detach first\n");
475280182Sjfv		return (EBUSY);
476280182Sjfv	}
477280182Sjfv
478280182Sjfv	IXGBE_CORE_LOCK(adapter);
479280182Sjfv	ixv_stop(adapter);
480280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
481280182Sjfv
482280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, que++) {
483280182Sjfv		if (que->tq) {
484280182Sjfv			struct tx_ring  *txr = que->txr;
485280182Sjfv			taskqueue_drain(que->tq, &txr->txq_task);
486280182Sjfv			taskqueue_drain(que->tq, &que->que_task);
487280182Sjfv			taskqueue_free(que->tq);
488280182Sjfv		}
489280182Sjfv	}
490280182Sjfv
491280182Sjfv	/* Drain the Mailbox(link) queue */
492280182Sjfv	if (adapter->tq) {
493280182Sjfv		taskqueue_drain(adapter->tq, &adapter->link_task);
494280182Sjfv		taskqueue_free(adapter->tq);
495280182Sjfv	}
496280182Sjfv
497280182Sjfv	/* Unregister VLAN events */
498280182Sjfv	if (adapter->vlan_attach != NULL)
499280182Sjfv		EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
500280182Sjfv	if (adapter->vlan_detach != NULL)
501280182Sjfv		EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
502280182Sjfv
503280182Sjfv	ether_ifdetach(adapter->ifp);
504280182Sjfv	callout_drain(&adapter->timer);
505295008Ssbruno#ifdef DEV_NETMAP
506295008Ssbruno	netmap_detach(adapter->ifp);
507295008Ssbruno#endif /* DEV_NETMAP */
508280182Sjfv	ixv_free_pci_resources(adapter);
509280182Sjfv	bus_generic_detach(dev);
510280182Sjfv	if_free(adapter->ifp);
511280182Sjfv
512280182Sjfv	ixgbe_free_transmit_structures(adapter);
513280182Sjfv	ixgbe_free_receive_structures(adapter);
514280182Sjfv
515280182Sjfv	IXGBE_CORE_LOCK_DESTROY(adapter);
516280182Sjfv	return (0);
517280182Sjfv}
518280182Sjfv
519280182Sjfv/*********************************************************************
520280182Sjfv *
521280182Sjfv *  Shutdown entry point
522280182Sjfv *
523280182Sjfv **********************************************************************/
524280182Sjfvstatic int
525280182Sjfvixv_shutdown(device_t dev)
526280182Sjfv{
527280182Sjfv	struct adapter *adapter = device_get_softc(dev);
528280182Sjfv	IXGBE_CORE_LOCK(adapter);
529280182Sjfv	ixv_stop(adapter);
530280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
531280182Sjfv	return (0);
532280182Sjfv}
533280182Sjfv
534280182Sjfv
535280182Sjfv/*********************************************************************
536280182Sjfv *  Ioctl entry point
537280182Sjfv *
538280182Sjfv *  ixv_ioctl is called when the user wants to configure the
539280182Sjfv *  interface.
540280182Sjfv *
541280182Sjfv *  return 0 on success, positive on failure
542280182Sjfv **********************************************************************/
543280182Sjfv
544280182Sjfvstatic int
545280182Sjfvixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
546280182Sjfv{
547280182Sjfv	struct adapter	*adapter = ifp->if_softc;
548280182Sjfv	struct ifreq	*ifr = (struct ifreq *) data;
549280182Sjfv#if defined(INET) || defined(INET6)
550280182Sjfv	struct ifaddr	*ifa = (struct ifaddr *) data;
551280182Sjfv	bool		avoid_reset = FALSE;
552280182Sjfv#endif
553280182Sjfv	int             error = 0;
554280182Sjfv
555280182Sjfv	switch (command) {
556280182Sjfv
557280182Sjfv	case SIOCSIFADDR:
558280182Sjfv#ifdef INET
559280182Sjfv		if (ifa->ifa_addr->sa_family == AF_INET)
560280182Sjfv			avoid_reset = TRUE;
561280182Sjfv#endif
562280182Sjfv#ifdef INET6
563280182Sjfv		if (ifa->ifa_addr->sa_family == AF_INET6)
564280182Sjfv			avoid_reset = TRUE;
565280182Sjfv#endif
566280182Sjfv#if defined(INET) || defined(INET6)
567280182Sjfv		/*
568280182Sjfv		** Calling init results in link renegotiation,
569280182Sjfv		** so we avoid doing it when possible.
570280182Sjfv		*/
571280182Sjfv		if (avoid_reset) {
572280182Sjfv			ifp->if_flags |= IFF_UP;
573280182Sjfv			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
574280182Sjfv				ixv_init(adapter);
575280182Sjfv			if (!(ifp->if_flags & IFF_NOARP))
576280182Sjfv				arp_ifinit(ifp, ifa);
577280182Sjfv		} else
578280182Sjfv			error = ether_ioctl(ifp, command, data);
579280182Sjfv		break;
580280182Sjfv#endif
581280182Sjfv	case SIOCSIFMTU:
582280182Sjfv		IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
583295524Ssbruno		if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) {
584280182Sjfv			error = EINVAL;
585280182Sjfv		} else {
586280182Sjfv			IXGBE_CORE_LOCK(adapter);
587280182Sjfv			ifp->if_mtu = ifr->ifr_mtu;
588280182Sjfv			adapter->max_frame_size =
589295524Ssbruno				ifp->if_mtu + IXGBE_MTU_HDR;
590280182Sjfv			ixv_init_locked(adapter);
591280182Sjfv			IXGBE_CORE_UNLOCK(adapter);
592280182Sjfv		}
593280182Sjfv		break;
594280182Sjfv	case SIOCSIFFLAGS:
595280182Sjfv		IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
596280182Sjfv		IXGBE_CORE_LOCK(adapter);
597280182Sjfv		if (ifp->if_flags & IFF_UP) {
598280182Sjfv			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
599280182Sjfv				ixv_init_locked(adapter);
600280182Sjfv		} else
601280182Sjfv			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
602280182Sjfv				ixv_stop(adapter);
603280182Sjfv		adapter->if_flags = ifp->if_flags;
604280182Sjfv		IXGBE_CORE_UNLOCK(adapter);
605280182Sjfv		break;
606280182Sjfv	case SIOCADDMULTI:
607280182Sjfv	case SIOCDELMULTI:
608280182Sjfv		IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
609280182Sjfv		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
610280182Sjfv			IXGBE_CORE_LOCK(adapter);
611280182Sjfv			ixv_disable_intr(adapter);
612280182Sjfv			ixv_set_multi(adapter);
613280182Sjfv			ixv_enable_intr(adapter);
614280182Sjfv			IXGBE_CORE_UNLOCK(adapter);
615280182Sjfv		}
616280182Sjfv		break;
617280182Sjfv	case SIOCSIFMEDIA:
618280182Sjfv	case SIOCGIFMEDIA:
619280182Sjfv		IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
620280182Sjfv		error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
621280182Sjfv		break;
622280182Sjfv	case SIOCSIFCAP:
623280182Sjfv	{
624280182Sjfv		int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
625280182Sjfv		IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
626280182Sjfv		if (mask & IFCAP_HWCSUM)
627280182Sjfv			ifp->if_capenable ^= IFCAP_HWCSUM;
628280182Sjfv		if (mask & IFCAP_TSO4)
629280182Sjfv			ifp->if_capenable ^= IFCAP_TSO4;
630280182Sjfv		if (mask & IFCAP_LRO)
631280182Sjfv			ifp->if_capenable ^= IFCAP_LRO;
632280182Sjfv		if (mask & IFCAP_VLAN_HWTAGGING)
633280182Sjfv			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
634280182Sjfv		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
635280182Sjfv			IXGBE_CORE_LOCK(adapter);
636280182Sjfv			ixv_init_locked(adapter);
637280182Sjfv			IXGBE_CORE_UNLOCK(adapter);
638280182Sjfv		}
639280182Sjfv		VLAN_CAPABILITIES(ifp);
640280182Sjfv		break;
641280182Sjfv	}
642280182Sjfv
643280182Sjfv	default:
644280182Sjfv		IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command);
645280182Sjfv		error = ether_ioctl(ifp, command, data);
646280182Sjfv		break;
647280182Sjfv	}
648280182Sjfv
649280182Sjfv	return (error);
650280182Sjfv}
651280182Sjfv
652280182Sjfv/*********************************************************************
653280182Sjfv *  Init entry point
654280182Sjfv *
655280182Sjfv *  This routine is used in two ways. It is used by the stack as
656280182Sjfv *  init entry point in network interface structure. It is also used
657280182Sjfv *  by the driver as a hw/sw initialization routine to get to a
658280182Sjfv *  consistent state.
659280182Sjfv *
660280182Sjfv *  return 0 on success, positive on failure
661280182Sjfv **********************************************************************/
662280182Sjfv#define IXGBE_MHADD_MFS_SHIFT 16
663280182Sjfv
664280182Sjfvstatic void
665280182Sjfvixv_init_locked(struct adapter *adapter)
666280182Sjfv{
667280182Sjfv	struct ifnet	*ifp = adapter->ifp;
668280182Sjfv	device_t 	dev = adapter->dev;
669280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
670295524Ssbruno	int error = 0;
671280182Sjfv
672295524Ssbruno	INIT_DEBUGOUT("ixv_init_locked: begin");
673280182Sjfv	mtx_assert(&adapter->core_mtx, MA_OWNED);
674280182Sjfv	hw->adapter_stopped = FALSE;
675280182Sjfv	ixgbe_stop_adapter(hw);
676280182Sjfv        callout_stop(&adapter->timer);
677280182Sjfv
678280182Sjfv        /* reprogram the RAR[0] in case user changed it. */
679280182Sjfv        ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
680280182Sjfv
681280182Sjfv	/* Get the latest mac address, User can use a LAA */
682280182Sjfv	bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr,
683280182Sjfv	     IXGBE_ETH_LENGTH_OF_ADDRESS);
684280182Sjfv        ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
685280182Sjfv	hw->addr_ctrl.rar_used_count = 1;
686280182Sjfv
687280182Sjfv	/* Prepare transmit descriptors and buffers */
688280182Sjfv	if (ixgbe_setup_transmit_structures(adapter)) {
689295524Ssbruno		device_printf(dev, "Could not setup transmit structures\n");
690280182Sjfv		ixv_stop(adapter);
691280182Sjfv		return;
692280182Sjfv	}
693280182Sjfv
694295524Ssbruno	/* Reset VF and renegotiate mailbox API version */
695280182Sjfv	ixgbe_reset_hw(hw);
696295524Ssbruno	error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11);
697295524Ssbruno	if (error)
698295524Ssbruno		device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error);
699295524Ssbruno
700280182Sjfv	ixv_initialize_transmit_units(adapter);
701280182Sjfv
702280182Sjfv	/* Setup Multicast table */
703280182Sjfv	ixv_set_multi(adapter);
704280182Sjfv
705280182Sjfv	/*
706280182Sjfv	** Determine the correct mbuf pool
707280182Sjfv	** for doing jumbo/headersplit
708280182Sjfv	*/
709280182Sjfv	if (ifp->if_mtu > ETHERMTU)
710280182Sjfv		adapter->rx_mbuf_sz = MJUMPAGESIZE;
711280182Sjfv	else
712280182Sjfv		adapter->rx_mbuf_sz = MCLBYTES;
713280182Sjfv
714280182Sjfv	/* Prepare receive descriptors and buffers */
715280182Sjfv	if (ixgbe_setup_receive_structures(adapter)) {
716295524Ssbruno		device_printf(dev, "Could not setup receive structures\n");
717280182Sjfv		ixv_stop(adapter);
718280182Sjfv		return;
719280182Sjfv	}
720280182Sjfv
721280182Sjfv	/* Configure RX settings */
722280182Sjfv	ixv_initialize_receive_units(adapter);
723280182Sjfv
724280182Sjfv	/* Set the various hardware offload abilities */
725280182Sjfv	ifp->if_hwassist = 0;
726280182Sjfv	if (ifp->if_capenable & IFCAP_TSO4)
727280182Sjfv		ifp->if_hwassist |= CSUM_TSO;
728280182Sjfv	if (ifp->if_capenable & IFCAP_TXCSUM) {
729280182Sjfv		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
730280182Sjfv#if __FreeBSD_version >= 800000
731280182Sjfv		ifp->if_hwassist |= CSUM_SCTP;
732280182Sjfv#endif
733280182Sjfv	}
734280182Sjfv
735280182Sjfv	/* Set up VLAN offload and filter */
736280182Sjfv	ixv_setup_vlan_support(adapter);
737280182Sjfv
738280182Sjfv	/* Set up MSI/X routing */
739280182Sjfv	ixv_configure_ivars(adapter);
740280182Sjfv
741280182Sjfv	/* Set up auto-mask */
742280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE);
743280182Sjfv
744280182Sjfv        /* Set moderation on the Link interrupt */
745280182Sjfv        IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR);
746280182Sjfv
747280182Sjfv	/* Stats init */
748280182Sjfv	ixv_init_stats(adapter);
749280182Sjfv
750280182Sjfv	/* Config/Enable Link */
751280182Sjfv	ixv_config_link(adapter);
752280182Sjfv
753295524Ssbruno	/* Start watchdog */
754295524Ssbruno	callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
755295524Ssbruno
756280182Sjfv	/* And now turn on interrupts */
757280182Sjfv	ixv_enable_intr(adapter);
758280182Sjfv
759280182Sjfv	/* Now inform the stack we're ready */
760280182Sjfv	ifp->if_drv_flags |= IFF_DRV_RUNNING;
761280182Sjfv	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
762280182Sjfv
763280182Sjfv	return;
764280182Sjfv}
765280182Sjfv
766280182Sjfvstatic void
767280182Sjfvixv_init(void *arg)
768280182Sjfv{
769280182Sjfv	struct adapter *adapter = arg;
770280182Sjfv
771280182Sjfv	IXGBE_CORE_LOCK(adapter);
772280182Sjfv	ixv_init_locked(adapter);
773280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
774280182Sjfv	return;
775280182Sjfv}
776280182Sjfv
777280182Sjfv
778280182Sjfv/*
779280182Sjfv**
780280182Sjfv** MSIX Interrupt Handlers and Tasklets
781280182Sjfv**
782280182Sjfv*/
783280182Sjfv
784280182Sjfvstatic inline void
785280182Sjfvixv_enable_queue(struct adapter *adapter, u32 vector)
786280182Sjfv{
787280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
788280182Sjfv	u32	queue = 1 << vector;
789280182Sjfv	u32	mask;
790280182Sjfv
791280182Sjfv	mask = (IXGBE_EIMS_RTX_QUEUE & queue);
792280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
793280182Sjfv}
794280182Sjfv
795280182Sjfvstatic inline void
796280182Sjfvixv_disable_queue(struct adapter *adapter, u32 vector)
797280182Sjfv{
798280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
799280182Sjfv	u64	queue = (u64)(1 << vector);
800280182Sjfv	u32	mask;
801280182Sjfv
802280182Sjfv	mask = (IXGBE_EIMS_RTX_QUEUE & queue);
803280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
804280182Sjfv}
805280182Sjfv
806280182Sjfvstatic inline void
807280182Sjfvixv_rearm_queues(struct adapter *adapter, u64 queues)
808280182Sjfv{
809280182Sjfv	u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues);
810280182Sjfv	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask);
811280182Sjfv}
812280182Sjfv
813280182Sjfv
814280182Sjfvstatic void
815280182Sjfvixv_handle_que(void *context, int pending)
816280182Sjfv{
817280182Sjfv	struct ix_queue *que = context;
818280182Sjfv	struct adapter  *adapter = que->adapter;
819280182Sjfv	struct tx_ring	*txr = que->txr;
820280182Sjfv	struct ifnet    *ifp = adapter->ifp;
821280182Sjfv	bool		more;
822280182Sjfv
823280182Sjfv	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
824280182Sjfv		more = ixgbe_rxeof(que);
825280182Sjfv		IXGBE_TX_LOCK(txr);
826280182Sjfv		ixgbe_txeof(txr);
827280182Sjfv#if __FreeBSD_version >= 800000
828280182Sjfv		if (!drbr_empty(ifp, txr->br))
829280182Sjfv			ixgbe_mq_start_locked(ifp, txr);
830280182Sjfv#else
831280182Sjfv		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
832280182Sjfv			ixgbe_start_locked(txr, ifp);
833280182Sjfv#endif
834280182Sjfv		IXGBE_TX_UNLOCK(txr);
835280182Sjfv		if (more) {
836280182Sjfv			taskqueue_enqueue(que->tq, &que->que_task);
837280182Sjfv			return;
838280182Sjfv		}
839280182Sjfv	}
840280182Sjfv
841280182Sjfv	/* Reenable this interrupt */
842280182Sjfv	ixv_enable_queue(adapter, que->msix);
843280182Sjfv	return;
844280182Sjfv}
845280182Sjfv
846280182Sjfv/*********************************************************************
847280182Sjfv *
848280182Sjfv *  MSI Queue Interrupt Service routine
849280182Sjfv *
850280182Sjfv **********************************************************************/
851280182Sjfvvoid
852280182Sjfvixv_msix_que(void *arg)
853280182Sjfv{
854280182Sjfv	struct ix_queue	*que = arg;
855280182Sjfv	struct adapter  *adapter = que->adapter;
856280182Sjfv	struct ifnet    *ifp = adapter->ifp;
857280182Sjfv	struct tx_ring	*txr = que->txr;
858280182Sjfv	struct rx_ring	*rxr = que->rxr;
859280182Sjfv	bool		more;
860280182Sjfv	u32		newitr = 0;
861280182Sjfv
862280182Sjfv	ixv_disable_queue(adapter, que->msix);
863280182Sjfv	++que->irqs;
864280182Sjfv
865280182Sjfv	more = ixgbe_rxeof(que);
866280182Sjfv
867280182Sjfv	IXGBE_TX_LOCK(txr);
868280182Sjfv	ixgbe_txeof(txr);
869280182Sjfv	/*
870280182Sjfv	** Make certain that if the stack
871280182Sjfv	** has anything queued the task gets
872280182Sjfv	** scheduled to handle it.
873280182Sjfv	*/
874280182Sjfv#ifdef IXGBE_LEGACY_TX
875280182Sjfv	if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd))
876280182Sjfv		ixgbe_start_locked(txr, ifp);
877280182Sjfv#else
878280182Sjfv	if (!drbr_empty(adapter->ifp, txr->br))
879280182Sjfv		ixgbe_mq_start_locked(ifp, txr);
880280182Sjfv#endif
881280182Sjfv	IXGBE_TX_UNLOCK(txr);
882280182Sjfv
883280182Sjfv	/* Do AIM now? */
884280182Sjfv
885280182Sjfv	if (ixv_enable_aim == FALSE)
886280182Sjfv		goto no_calc;
887280182Sjfv	/*
888280182Sjfv	** Do Adaptive Interrupt Moderation:
889280182Sjfv        **  - Write out last calculated setting
890280182Sjfv	**  - Calculate based on average size over
891280182Sjfv	**    the last interval.
892280182Sjfv	*/
893280182Sjfv        if (que->eitr_setting)
894280182Sjfv                IXGBE_WRITE_REG(&adapter->hw,
895280182Sjfv                    IXGBE_VTEITR(que->msix),
896280182Sjfv		    que->eitr_setting);
897280182Sjfv
898280182Sjfv        que->eitr_setting = 0;
899280182Sjfv
900280182Sjfv        /* Idle, do nothing */
901280182Sjfv        if ((txr->bytes == 0) && (rxr->bytes == 0))
902280182Sjfv                goto no_calc;
903280182Sjfv
904280182Sjfv	if ((txr->bytes) && (txr->packets))
905280182Sjfv               	newitr = txr->bytes/txr->packets;
906280182Sjfv	if ((rxr->bytes) && (rxr->packets))
907280182Sjfv		newitr = max(newitr,
908280182Sjfv		    (rxr->bytes / rxr->packets));
909280182Sjfv	newitr += 24; /* account for hardware frame, crc */
910280182Sjfv
911280182Sjfv	/* set an upper boundary */
912280182Sjfv	newitr = min(newitr, 3000);
913280182Sjfv
914280182Sjfv	/* Be nice to the mid range */
915280182Sjfv	if ((newitr > 300) && (newitr < 1200))
916280182Sjfv		newitr = (newitr / 3);
917280182Sjfv	else
918280182Sjfv		newitr = (newitr / 2);
919280182Sjfv
920280182Sjfv	newitr |= newitr << 16;
921280182Sjfv
922280182Sjfv        /* save for next interrupt */
923280182Sjfv        que->eitr_setting = newitr;
924280182Sjfv
925280182Sjfv        /* Reset state */
926280182Sjfv        txr->bytes = 0;
927280182Sjfv        txr->packets = 0;
928280182Sjfv        rxr->bytes = 0;
929280182Sjfv        rxr->packets = 0;
930280182Sjfv
931280182Sjfvno_calc:
932280182Sjfv	if (more)
933280182Sjfv		taskqueue_enqueue(que->tq, &que->que_task);
934280182Sjfv	else /* Reenable this interrupt */
935280182Sjfv		ixv_enable_queue(adapter, que->msix);
936280182Sjfv	return;
937280182Sjfv}
938280182Sjfv
939280182Sjfvstatic void
940280182Sjfvixv_msix_mbx(void *arg)
941280182Sjfv{
942280182Sjfv	struct adapter	*adapter = arg;
943280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
944280182Sjfv	u32		reg;
945280182Sjfv
946283620Serj	++adapter->link_irq;
947280182Sjfv
948280182Sjfv	/* First get the cause */
949280182Sjfv	reg = IXGBE_READ_REG(hw, IXGBE_VTEICS);
950280182Sjfv	/* Clear interrupt with write */
951280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEICR, reg);
952280182Sjfv
953280182Sjfv	/* Link status change */
954280182Sjfv	if (reg & IXGBE_EICR_LSC)
955280182Sjfv		taskqueue_enqueue(adapter->tq, &adapter->link_task);
956280182Sjfv
957280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER);
958280182Sjfv	return;
959280182Sjfv}
960280182Sjfv
961280182Sjfv/*********************************************************************
962280182Sjfv *
963280182Sjfv *  Media Ioctl callback
964280182Sjfv *
965280182Sjfv *  This routine is called whenever the user queries the status of
966280182Sjfv *  the interface using ifconfig.
967280182Sjfv *
968280182Sjfv **********************************************************************/
969280182Sjfvstatic void
970280182Sjfvixv_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
971280182Sjfv{
972280182Sjfv	struct adapter *adapter = ifp->if_softc;
973280182Sjfv
974280182Sjfv	INIT_DEBUGOUT("ixv_media_status: begin");
975280182Sjfv	IXGBE_CORE_LOCK(adapter);
976280182Sjfv	ixv_update_link_status(adapter);
977280182Sjfv
978280182Sjfv	ifmr->ifm_status = IFM_AVALID;
979280182Sjfv	ifmr->ifm_active = IFM_ETHER;
980280182Sjfv
981280182Sjfv	if (!adapter->link_active) {
982280182Sjfv		IXGBE_CORE_UNLOCK(adapter);
983280182Sjfv		return;
984280182Sjfv	}
985280182Sjfv
986280182Sjfv	ifmr->ifm_status |= IFM_ACTIVE;
987280182Sjfv
988280182Sjfv	switch (adapter->link_speed) {
989280182Sjfv		case IXGBE_LINK_SPEED_1GB_FULL:
990280182Sjfv			ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
991280182Sjfv			break;
992280182Sjfv		case IXGBE_LINK_SPEED_10GB_FULL:
993280182Sjfv			ifmr->ifm_active |= IFM_FDX;
994280182Sjfv			break;
995280182Sjfv	}
996280182Sjfv
997280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
998280182Sjfv
999280182Sjfv	return;
1000280182Sjfv}
1001280182Sjfv
1002280182Sjfv/*********************************************************************
1003280182Sjfv *
1004280182Sjfv *  Media Ioctl callback
1005280182Sjfv *
1006280182Sjfv *  This routine is called when the user changes speed/duplex using
1007280182Sjfv *  media/mediopt option with ifconfig.
1008280182Sjfv *
1009280182Sjfv **********************************************************************/
1010280182Sjfvstatic int
1011280182Sjfvixv_media_change(struct ifnet * ifp)
1012280182Sjfv{
1013280182Sjfv	struct adapter *adapter = ifp->if_softc;
1014280182Sjfv	struct ifmedia *ifm = &adapter->media;
1015280182Sjfv
1016280182Sjfv	INIT_DEBUGOUT("ixv_media_change: begin");
1017280182Sjfv
1018280182Sjfv	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1019280182Sjfv		return (EINVAL);
1020280182Sjfv
1021280182Sjfv        switch (IFM_SUBTYPE(ifm->ifm_media)) {
1022280182Sjfv        case IFM_AUTO:
1023280182Sjfv                break;
1024280182Sjfv        default:
1025280182Sjfv                device_printf(adapter->dev, "Only auto media type\n");
1026280182Sjfv		return (EINVAL);
1027280182Sjfv        }
1028280182Sjfv
1029280182Sjfv	return (0);
1030280182Sjfv}
1031280182Sjfv
1032280182Sjfv
1033280182Sjfv/*********************************************************************
1034280182Sjfv *  Multicast Update
1035280182Sjfv *
1036280182Sjfv *  This routine is called whenever multicast address list is updated.
1037280182Sjfv *
1038280182Sjfv **********************************************************************/
1039280182Sjfv#define IXGBE_RAR_ENTRIES 16
1040280182Sjfv
1041280182Sjfvstatic void
1042280182Sjfvixv_set_multi(struct adapter *adapter)
1043280182Sjfv{
1044280182Sjfv	u8	mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
1045280182Sjfv	u8	*update_ptr;
1046280182Sjfv	struct	ifmultiaddr *ifma;
1047280182Sjfv	int	mcnt = 0;
1048280182Sjfv	struct ifnet   *ifp = adapter->ifp;
1049280182Sjfv
1050280182Sjfv	IOCTL_DEBUGOUT("ixv_set_multi: begin");
1051280182Sjfv
1052280182Sjfv#if __FreeBSD_version < 800000
1053280182Sjfv	IF_ADDR_LOCK(ifp);
1054280182Sjfv#else
1055280182Sjfv	if_maddr_rlock(ifp);
1056280182Sjfv#endif
1057280182Sjfv	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1058280182Sjfv		if (ifma->ifma_addr->sa_family != AF_LINK)
1059280182Sjfv			continue;
1060280182Sjfv		bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
1061280182Sjfv		    &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
1062280182Sjfv		    IXGBE_ETH_LENGTH_OF_ADDRESS);
1063280182Sjfv		mcnt++;
1064280182Sjfv	}
1065280182Sjfv#if __FreeBSD_version < 800000
1066280182Sjfv	IF_ADDR_UNLOCK(ifp);
1067280182Sjfv#else
1068280182Sjfv	if_maddr_runlock(ifp);
1069280182Sjfv#endif
1070280182Sjfv
1071280182Sjfv	update_ptr = mta;
1072280182Sjfv
1073280182Sjfv	ixgbe_update_mc_addr_list(&adapter->hw,
1074280182Sjfv	    update_ptr, mcnt, ixv_mc_array_itr, TRUE);
1075280182Sjfv
1076280182Sjfv	return;
1077280182Sjfv}
1078280182Sjfv
1079280182Sjfv/*
1080280182Sjfv * This is an iterator function now needed by the multicast
1081280182Sjfv * shared code. It simply feeds the shared code routine the
1082280182Sjfv * addresses in the array of ixv_set_multi() one by one.
1083280182Sjfv */
1084280182Sjfvstatic u8 *
1085280182Sjfvixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
1086280182Sjfv{
1087280182Sjfv	u8 *addr = *update_ptr;
1088280182Sjfv	u8 *newptr;
1089280182Sjfv	*vmdq = 0;
1090280182Sjfv
1091280182Sjfv	newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS;
1092280182Sjfv	*update_ptr = newptr;
1093280182Sjfv	return addr;
1094280182Sjfv}
1095280182Sjfv
1096280182Sjfv/*********************************************************************
1097280182Sjfv *  Timer routine
1098280182Sjfv *
1099280182Sjfv *  This routine checks for link status,updates statistics,
1100280182Sjfv *  and runs the watchdog check.
1101280182Sjfv *
1102280182Sjfv **********************************************************************/
1103280182Sjfv
1104280182Sjfvstatic void
1105280182Sjfvixv_local_timer(void *arg)
1106280182Sjfv{
1107280182Sjfv	struct adapter	*adapter = arg;
1108280182Sjfv	device_t	dev = adapter->dev;
1109280182Sjfv	struct ix_queue	*que = adapter->queues;
1110280182Sjfv	u64		queues = 0;
1111280182Sjfv	int		hung = 0;
1112280182Sjfv
1113280182Sjfv	mtx_assert(&adapter->core_mtx, MA_OWNED);
1114280182Sjfv
1115280182Sjfv	ixv_update_link_status(adapter);
1116280182Sjfv
1117280182Sjfv	/* Stats Update */
1118280182Sjfv	ixv_update_stats(adapter);
1119280182Sjfv
1120280182Sjfv	/*
1121280182Sjfv	** Check the TX queues status
1122280182Sjfv	**      - mark hung queues so we don't schedule on them
1123280182Sjfv	**      - watchdog only if all queues show hung
1124280182Sjfv	*/
1125280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, que++) {
1126280182Sjfv		/* Keep track of queues with work for soft irq */
1127280182Sjfv		if (que->txr->busy)
1128280182Sjfv			queues |= ((u64)1 << que->me);
1129280182Sjfv		/*
1130280182Sjfv		** Each time txeof runs without cleaning, but there
1131280182Sjfv		** are uncleaned descriptors it increments busy. If
1132280182Sjfv		** we get to the MAX we declare it hung.
1133280182Sjfv		*/
1134280182Sjfv		if (que->busy == IXGBE_QUEUE_HUNG) {
1135280182Sjfv			++hung;
1136280182Sjfv			/* Mark the queue as inactive */
1137280182Sjfv			adapter->active_queues &= ~((u64)1 << que->me);
1138280182Sjfv			continue;
1139280182Sjfv		} else {
1140280182Sjfv			/* Check if we've come back from hung */
1141280182Sjfv			if ((adapter->active_queues & ((u64)1 << que->me)) == 0)
1142280182Sjfv                                adapter->active_queues |= ((u64)1 << que->me);
1143280182Sjfv		}
1144280182Sjfv		if (que->busy >= IXGBE_MAX_TX_BUSY) {
1145280182Sjfv			device_printf(dev,"Warning queue %d "
1146280182Sjfv			    "appears to be hung!\n", i);
1147280182Sjfv			que->txr->busy = IXGBE_QUEUE_HUNG;
1148280182Sjfv			++hung;
1149280182Sjfv		}
1150280182Sjfv
1151280182Sjfv	}
1152280182Sjfv
1153280182Sjfv	/* Only truely watchdog if all queues show hung */
1154280182Sjfv	if (hung == adapter->num_queues)
1155280182Sjfv		goto watchdog;
1156280182Sjfv	else if (queues != 0) { /* Force an IRQ on queues with work */
1157280182Sjfv		ixv_rearm_queues(adapter, queues);
1158280182Sjfv	}
1159280182Sjfv
1160280182Sjfv	callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
1161280182Sjfv	return;
1162280182Sjfv
1163280182Sjfvwatchdog:
1164280182Sjfv	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
1165280182Sjfv	adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1166280182Sjfv	adapter->watchdog_events++;
1167280182Sjfv	ixv_init_locked(adapter);
1168280182Sjfv}
1169280182Sjfv
1170280182Sjfv/*
1171280182Sjfv** Note: this routine updates the OS on the link state
1172280182Sjfv**	the real check of the hardware only happens with
1173280182Sjfv**	a link interrupt.
1174280182Sjfv*/
1175280182Sjfvstatic void
1176280182Sjfvixv_update_link_status(struct adapter *adapter)
1177280182Sjfv{
1178280182Sjfv	struct ifnet	*ifp = adapter->ifp;
1179280182Sjfv	device_t dev = adapter->dev;
1180280182Sjfv
1181280182Sjfv	if (adapter->link_up){
1182280182Sjfv		if (adapter->link_active == FALSE) {
1183280182Sjfv			if (bootverbose)
1184280182Sjfv				device_printf(dev,"Link is up %d Gbps %s \n",
1185280182Sjfv				    ((adapter->link_speed == 128)? 10:1),
1186280182Sjfv				    "Full Duplex");
1187280182Sjfv			adapter->link_active = TRUE;
1188280182Sjfv			if_link_state_change(ifp, LINK_STATE_UP);
1189280182Sjfv		}
1190280182Sjfv	} else { /* Link down */
1191280182Sjfv		if (adapter->link_active == TRUE) {
1192280182Sjfv			if (bootverbose)
1193280182Sjfv				device_printf(dev,"Link is Down\n");
1194280182Sjfv			if_link_state_change(ifp, LINK_STATE_DOWN);
1195280182Sjfv			adapter->link_active = FALSE;
1196280182Sjfv		}
1197280182Sjfv	}
1198280182Sjfv
1199280182Sjfv	return;
1200280182Sjfv}
1201280182Sjfv
1202280182Sjfv
1203280182Sjfv/*********************************************************************
1204280182Sjfv *
1205280182Sjfv *  This routine disables all traffic on the adapter by issuing a
1206280182Sjfv *  global reset on the MAC and deallocates TX/RX buffers.
1207280182Sjfv *
1208280182Sjfv **********************************************************************/
1209280182Sjfv
1210280182Sjfvstatic void
1211280182Sjfvixv_stop(void *arg)
1212280182Sjfv{
1213280182Sjfv	struct ifnet   *ifp;
1214280182Sjfv	struct adapter *adapter = arg;
1215280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1216280182Sjfv	ifp = adapter->ifp;
1217280182Sjfv
1218280182Sjfv	mtx_assert(&adapter->core_mtx, MA_OWNED);
1219280182Sjfv
1220280182Sjfv	INIT_DEBUGOUT("ixv_stop: begin\n");
1221280182Sjfv	ixv_disable_intr(adapter);
1222280182Sjfv
1223280182Sjfv	/* Tell the stack that the interface is no longer active */
1224280182Sjfv	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1225280182Sjfv
1226280182Sjfv	ixgbe_reset_hw(hw);
1227280182Sjfv	adapter->hw.adapter_stopped = FALSE;
1228280182Sjfv	ixgbe_stop_adapter(hw);
1229280182Sjfv	callout_stop(&adapter->timer);
1230280182Sjfv
1231280182Sjfv	/* reprogram the RAR[0] in case user changed it. */
1232280182Sjfv	ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1233280182Sjfv
1234280182Sjfv	return;
1235280182Sjfv}
1236280182Sjfv
1237280182Sjfv
1238280182Sjfv/*********************************************************************
1239280182Sjfv *
1240280182Sjfv *  Determine hardware revision.
1241280182Sjfv *
1242280182Sjfv **********************************************************************/
1243280182Sjfvstatic void
1244280182Sjfvixv_identify_hardware(struct adapter *adapter)
1245280182Sjfv{
1246280182Sjfv	device_t        dev = adapter->dev;
1247280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1248280182Sjfv
1249280182Sjfv	/*
1250280182Sjfv	** Make sure BUSMASTER is set, on a VM under
1251280182Sjfv	** KVM it may not be and will break things.
1252280182Sjfv	*/
1253280182Sjfv	pci_enable_busmaster(dev);
1254280182Sjfv
1255280182Sjfv	/* Save off the information about this board */
1256280182Sjfv	hw->vendor_id = pci_get_vendor(dev);
1257280182Sjfv	hw->device_id = pci_get_device(dev);
1258280182Sjfv	hw->revision_id = pci_read_config(dev, PCIR_REVID, 1);
1259280182Sjfv	hw->subsystem_vendor_id =
1260280182Sjfv	    pci_read_config(dev, PCIR_SUBVEND_0, 2);
1261280182Sjfv	hw->subsystem_device_id =
1262280182Sjfv	    pci_read_config(dev, PCIR_SUBDEV_0, 2);
1263280182Sjfv
1264280182Sjfv	/* We need this to determine device-specific things */
1265280182Sjfv	ixgbe_set_mac_type(hw);
1266280182Sjfv
1267280182Sjfv	/* Set the right number of segments */
1268280182Sjfv	adapter->num_segs = IXGBE_82599_SCATTER;
1269280182Sjfv
1270280182Sjfv	return;
1271280182Sjfv}
1272280182Sjfv
1273280182Sjfv/*********************************************************************
1274280182Sjfv *
1275280182Sjfv *  Setup MSIX Interrupt resources and handlers
1276280182Sjfv *
1277280182Sjfv **********************************************************************/
1278280182Sjfvstatic int
1279280182Sjfvixv_allocate_msix(struct adapter *adapter)
1280280182Sjfv{
1281280182Sjfv	device_t	dev = adapter->dev;
1282280182Sjfv	struct 		ix_queue *que = adapter->queues;
1283280182Sjfv	struct		tx_ring *txr = adapter->tx_rings;
1284280182Sjfv	int 		error, rid, vector = 0;
1285280182Sjfv
1286280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
1287280182Sjfv		rid = vector + 1;
1288280182Sjfv		que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
1289280182Sjfv		    RF_SHAREABLE | RF_ACTIVE);
1290280182Sjfv		if (que->res == NULL) {
1291280182Sjfv			device_printf(dev,"Unable to allocate"
1292280182Sjfv		    	    " bus resource: que interrupt [%d]\n", vector);
1293280182Sjfv			return (ENXIO);
1294280182Sjfv		}
1295280182Sjfv		/* Set the handler function */
1296280182Sjfv		error = bus_setup_intr(dev, que->res,
1297280182Sjfv		    INTR_TYPE_NET | INTR_MPSAFE, NULL,
1298280182Sjfv		    ixv_msix_que, que, &que->tag);
1299280182Sjfv		if (error) {
1300280182Sjfv			que->res = NULL;
1301280182Sjfv			device_printf(dev, "Failed to register QUE handler");
1302280182Sjfv			return (error);
1303280182Sjfv		}
1304280182Sjfv#if __FreeBSD_version >= 800504
1305280182Sjfv		bus_describe_intr(dev, que->res, que->tag, "que %d", i);
1306280182Sjfv#endif
1307280182Sjfv		que->msix = vector;
1308280182Sjfv        	adapter->active_queues |= (u64)(1 << que->msix);
1309280182Sjfv		/*
1310280182Sjfv		** Bind the msix vector, and thus the
1311280182Sjfv		** ring to the corresponding cpu.
1312280182Sjfv		*/
1313280182Sjfv		if (adapter->num_queues > 1)
1314280182Sjfv			bus_bind_intr(dev, que->res, i);
1315280182Sjfv		TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
1316280182Sjfv		TASK_INIT(&que->que_task, 0, ixv_handle_que, que);
1317280182Sjfv		que->tq = taskqueue_create_fast("ixv_que", M_NOWAIT,
1318280182Sjfv		    taskqueue_thread_enqueue, &que->tq);
1319280182Sjfv		taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que",
1320280182Sjfv		    device_get_nameunit(adapter->dev));
1321280182Sjfv	}
1322280182Sjfv
1323280182Sjfv	/* and Mailbox */
1324280182Sjfv	rid = vector + 1;
1325280182Sjfv	adapter->res = bus_alloc_resource_any(dev,
1326280182Sjfv    	    SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
1327280182Sjfv	if (!adapter->res) {
1328280182Sjfv		device_printf(dev,"Unable to allocate"
1329280182Sjfv    	    " bus resource: MBX interrupt [%d]\n", rid);
1330280182Sjfv		return (ENXIO);
1331280182Sjfv	}
1332280182Sjfv	/* Set the mbx handler function */
1333280182Sjfv	error = bus_setup_intr(dev, adapter->res,
1334280182Sjfv	    INTR_TYPE_NET | INTR_MPSAFE, NULL,
1335280182Sjfv	    ixv_msix_mbx, adapter, &adapter->tag);
1336280182Sjfv	if (error) {
1337280182Sjfv		adapter->res = NULL;
1338280182Sjfv		device_printf(dev, "Failed to register LINK handler");
1339280182Sjfv		return (error);
1340280182Sjfv	}
1341280182Sjfv#if __FreeBSD_version >= 800504
1342280182Sjfv	bus_describe_intr(dev, adapter->res, adapter->tag, "mbx");
1343280182Sjfv#endif
1344280182Sjfv	adapter->vector = vector;
1345280182Sjfv	/* Tasklets for Mailbox */
1346280182Sjfv	TASK_INIT(&adapter->link_task, 0, ixv_handle_mbx, adapter);
1347280182Sjfv	adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT,
1348280182Sjfv	    taskqueue_thread_enqueue, &adapter->tq);
1349280182Sjfv	taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq",
1350280182Sjfv	    device_get_nameunit(adapter->dev));
1351280182Sjfv	/*
1352280182Sjfv	** Due to a broken design QEMU will fail to properly
1353280182Sjfv	** enable the guest for MSIX unless the vectors in
1354280182Sjfv	** the table are all set up, so we must rewrite the
1355280182Sjfv	** ENABLE in the MSIX control register again at this
1356280182Sjfv	** point to cause it to successfully initialize us.
1357280182Sjfv	*/
1358280182Sjfv	if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
1359280182Sjfv		int msix_ctrl;
1360280182Sjfv		pci_find_cap(dev, PCIY_MSIX, &rid);
1361280182Sjfv		rid += PCIR_MSIX_CTRL;
1362280182Sjfv		msix_ctrl = pci_read_config(dev, rid, 2);
1363280182Sjfv		msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
1364280182Sjfv		pci_write_config(dev, rid, msix_ctrl, 2);
1365280182Sjfv	}
1366280182Sjfv
1367280182Sjfv	return (0);
1368280182Sjfv}
1369280182Sjfv
1370280182Sjfv/*
1371280182Sjfv * Setup MSIX resources, note that the VF
1372280182Sjfv * device MUST use MSIX, there is no fallback.
1373280182Sjfv */
1374280182Sjfvstatic int
1375280182Sjfvixv_setup_msix(struct adapter *adapter)
1376280182Sjfv{
1377280182Sjfv	device_t dev = adapter->dev;
1378295008Ssbruno	int rid, want, msgs;
1379280182Sjfv
1380280182Sjfv
1381295008Ssbruno	/* Must have at least 2 MSIX vectors */
1382295008Ssbruno	msgs = pci_msix_count(dev);
1383295008Ssbruno	if (msgs < 2)
1384295008Ssbruno		goto out;
1385280182Sjfv	rid = PCIR_BAR(3);
1386280182Sjfv	adapter->msix_mem = bus_alloc_resource_any(dev,
1387280182Sjfv	    SYS_RES_MEMORY, &rid, RF_ACTIVE);
1388280182Sjfv       	if (adapter->msix_mem == NULL) {
1389280182Sjfv		device_printf(adapter->dev,
1390280182Sjfv		    "Unable to map MSIX table \n");
1391280182Sjfv		goto out;
1392280182Sjfv	}
1393280182Sjfv
1394280182Sjfv	/*
1395295008Ssbruno	** Want vectors for the queues,
1396280182Sjfv	** plus an additional for mailbox.
1397280182Sjfv	*/
1398295008Ssbruno	want = adapter->num_queues + 1;
1399295008Ssbruno	if (want > msgs) {
1400295008Ssbruno		want = msgs;
1401295008Ssbruno		adapter->num_queues = msgs - 1;
1402295008Ssbruno	} else
1403295008Ssbruno		msgs = want;
1404295008Ssbruno	if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
1405280182Sjfv               	device_printf(adapter->dev,
1406280182Sjfv		    "Using MSIX interrupts with %d vectors\n", want);
1407280182Sjfv		return (want);
1408280182Sjfv	}
1409280182Sjfv	/* Release in case alloc was insufficient */
1410280182Sjfv	pci_release_msi(dev);
1411280182Sjfvout:
1412280182Sjfv       	if (adapter->msix_mem != NULL) {
1413280182Sjfv		bus_release_resource(dev, SYS_RES_MEMORY,
1414280182Sjfv		    rid, adapter->msix_mem);
1415280182Sjfv		adapter->msix_mem = NULL;
1416280182Sjfv	}
1417280182Sjfv	device_printf(adapter->dev,"MSIX config error\n");
1418280182Sjfv	return (ENXIO);
1419280182Sjfv}
1420280182Sjfv
1421280182Sjfv
1422280182Sjfvstatic int
1423280182Sjfvixv_allocate_pci_resources(struct adapter *adapter)
1424280182Sjfv{
1425280182Sjfv	int             rid;
1426280182Sjfv	device_t        dev = adapter->dev;
1427280182Sjfv
1428280182Sjfv	rid = PCIR_BAR(0);
1429280182Sjfv	adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1430280182Sjfv	    &rid, RF_ACTIVE);
1431280182Sjfv
1432280182Sjfv	if (!(adapter->pci_mem)) {
1433295524Ssbruno		device_printf(dev, "Unable to allocate bus resource: memory\n");
1434280182Sjfv		return (ENXIO);
1435280182Sjfv	}
1436280182Sjfv
1437280182Sjfv	adapter->osdep.mem_bus_space_tag =
1438280182Sjfv		rman_get_bustag(adapter->pci_mem);
1439280182Sjfv	adapter->osdep.mem_bus_space_handle =
1440280182Sjfv		rman_get_bushandle(adapter->pci_mem);
1441295524Ssbruno	adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
1442280182Sjfv
1443295008Ssbruno	/* Pick up the tuneable queues */
1444295008Ssbruno	adapter->num_queues = ixv_num_queues;
1445295524Ssbruno	adapter->hw.back = adapter;
1446295008Ssbruno
1447280182Sjfv	/*
1448280182Sjfv	** Now setup MSI/X, should
1449280182Sjfv	** return us the number of
1450280182Sjfv	** configured vectors.
1451280182Sjfv	*/
1452280182Sjfv	adapter->msix = ixv_setup_msix(adapter);
1453280182Sjfv	if (adapter->msix == ENXIO)
1454280182Sjfv		return (ENXIO);
1455280182Sjfv	else
1456280182Sjfv		return (0);
1457280182Sjfv}
1458280182Sjfv
1459280182Sjfvstatic void
1460280182Sjfvixv_free_pci_resources(struct adapter * adapter)
1461280182Sjfv{
1462280182Sjfv	struct 		ix_queue *que = adapter->queues;
1463280182Sjfv	device_t	dev = adapter->dev;
1464280182Sjfv	int		rid, memrid;
1465280182Sjfv
1466280182Sjfv	memrid = PCIR_BAR(MSIX_82598_BAR);
1467280182Sjfv
1468280182Sjfv	/*
1469280182Sjfv	** There is a slight possibility of a failure mode
1470280182Sjfv	** in attach that will result in entering this function
1471280182Sjfv	** before interrupt resources have been initialized, and
1472280182Sjfv	** in that case we do not want to execute the loops below
1473280182Sjfv	** We can detect this reliably by the state of the adapter
1474280182Sjfv	** res pointer.
1475280182Sjfv	*/
1476280182Sjfv	if (adapter->res == NULL)
1477280182Sjfv		goto mem;
1478280182Sjfv
1479280182Sjfv	/*
1480280182Sjfv	**  Release all msix queue resources:
1481280182Sjfv	*/
1482280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, que++) {
1483280182Sjfv		rid = que->msix + 1;
1484280182Sjfv		if (que->tag != NULL) {
1485280182Sjfv			bus_teardown_intr(dev, que->res, que->tag);
1486280182Sjfv			que->tag = NULL;
1487280182Sjfv		}
1488280182Sjfv		if (que->res != NULL)
1489280182Sjfv			bus_release_resource(dev, SYS_RES_IRQ, rid, que->res);
1490280182Sjfv	}
1491280182Sjfv
1492280182Sjfv
1493280182Sjfv	/* Clean the Legacy or Link interrupt last */
1494280182Sjfv	if (adapter->vector) /* we are doing MSIX */
1495280182Sjfv		rid = adapter->vector + 1;
1496280182Sjfv	else
1497280182Sjfv		(adapter->msix != 0) ? (rid = 1):(rid = 0);
1498280182Sjfv
1499280182Sjfv	if (adapter->tag != NULL) {
1500280182Sjfv		bus_teardown_intr(dev, adapter->res, adapter->tag);
1501280182Sjfv		adapter->tag = NULL;
1502280182Sjfv	}
1503280182Sjfv	if (adapter->res != NULL)
1504280182Sjfv		bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res);
1505280182Sjfv
1506280182Sjfvmem:
1507280182Sjfv	if (adapter->msix)
1508280182Sjfv		pci_release_msi(dev);
1509280182Sjfv
1510280182Sjfv	if (adapter->msix_mem != NULL)
1511280182Sjfv		bus_release_resource(dev, SYS_RES_MEMORY,
1512280182Sjfv		    memrid, adapter->msix_mem);
1513280182Sjfv
1514280182Sjfv	if (adapter->pci_mem != NULL)
1515280182Sjfv		bus_release_resource(dev, SYS_RES_MEMORY,
1516280182Sjfv		    PCIR_BAR(0), adapter->pci_mem);
1517280182Sjfv
1518280182Sjfv	return;
1519280182Sjfv}
1520280182Sjfv
1521280182Sjfv/*********************************************************************
1522280182Sjfv *
1523280182Sjfv *  Setup networking device structure and register an interface.
1524280182Sjfv *
1525280182Sjfv **********************************************************************/
1526280182Sjfvstatic void
1527280182Sjfvixv_setup_interface(device_t dev, struct adapter *adapter)
1528280182Sjfv{
1529280182Sjfv	struct ifnet   *ifp;
1530280182Sjfv
1531280182Sjfv	INIT_DEBUGOUT("ixv_setup_interface: begin");
1532280182Sjfv
1533280182Sjfv	ifp = adapter->ifp = if_alloc(IFT_ETHER);
1534280182Sjfv	if (ifp == NULL)
1535280182Sjfv		panic("%s: can not if_alloc()\n", device_get_nameunit(dev));
1536280182Sjfv	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1537280182Sjfv	ifp->if_baudrate = 1000000000;
1538280182Sjfv	ifp->if_init = ixv_init;
1539280182Sjfv	ifp->if_softc = adapter;
1540280182Sjfv	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1541280182Sjfv	ifp->if_ioctl = ixv_ioctl;
1542280182Sjfv#if __FreeBSD_version >= 800000
1543280182Sjfv	ifp->if_transmit = ixgbe_mq_start;
1544280182Sjfv	ifp->if_qflush = ixgbe_qflush;
1545280182Sjfv#else
1546280182Sjfv	ifp->if_start = ixgbe_start;
1547280182Sjfv#endif
1548280182Sjfv	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2;
1549280182Sjfv
1550280182Sjfv	ether_ifattach(ifp, adapter->hw.mac.addr);
1551280182Sjfv
1552280182Sjfv	adapter->max_frame_size =
1553295524Ssbruno	    ifp->if_mtu + IXGBE_MTU_HDR_VLAN;
1554280182Sjfv
1555280182Sjfv	/*
1556280182Sjfv	 * Tell the upper layer(s) we support long frames.
1557280182Sjfv	 */
1558280182Sjfv	ifp->if_hdrlen = sizeof(struct ether_vlan_header);
1559280182Sjfv
1560280182Sjfv	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
1561280182Sjfv	ifp->if_capabilities |= IFCAP_JUMBO_MTU;
1562280182Sjfv	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING
1563280182Sjfv			     |  IFCAP_VLAN_HWTSO
1564280182Sjfv			     |  IFCAP_VLAN_MTU;
1565280182Sjfv	ifp->if_capabilities |= IFCAP_LRO;
1566280182Sjfv	ifp->if_capenable = ifp->if_capabilities;
1567280182Sjfv
1568280182Sjfv	/*
1569280182Sjfv	 * Specify the media types supported by this adapter and register
1570280182Sjfv	 * callbacks to update media and link information
1571280182Sjfv	 */
1572280182Sjfv	ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change,
1573280182Sjfv		     ixv_media_status);
1574280182Sjfv	ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
1575280182Sjfv	ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
1576280182Sjfv
1577280182Sjfv	return;
1578280182Sjfv}
1579280182Sjfv
1580280182Sjfvstatic void
1581280182Sjfvixv_config_link(struct adapter *adapter)
1582280182Sjfv{
1583280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1584295524Ssbruno	u32	autoneg;
1585280182Sjfv
1586280182Sjfv	if (hw->mac.ops.check_link)
1587295524Ssbruno		hw->mac.ops.check_link(hw, &autoneg,
1588280182Sjfv		    &adapter->link_up, FALSE);
1589280182Sjfv}
1590280182Sjfv
1591280182Sjfv
1592280182Sjfv/*********************************************************************
1593280182Sjfv *
1594280182Sjfv *  Enable transmit unit.
1595280182Sjfv *
1596280182Sjfv **********************************************************************/
1597280182Sjfvstatic void
1598280182Sjfvixv_initialize_transmit_units(struct adapter *adapter)
1599280182Sjfv{
1600280182Sjfv	struct tx_ring	*txr = adapter->tx_rings;
1601280182Sjfv	struct ixgbe_hw	*hw = &adapter->hw;
1602280182Sjfv
1603280182Sjfv
1604280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, txr++) {
1605280182Sjfv		u64	tdba = txr->txdma.dma_paddr;
1606280182Sjfv		u32	txctrl, txdctl;
1607280182Sjfv
1608280182Sjfv		/* Set WTHRESH to 8, burst writeback */
1609280182Sjfv		txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
1610280182Sjfv		txdctl |= (8 << 16);
1611280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl);
1612280182Sjfv
1613280182Sjfv		/* Set the HW Tx Head and Tail indices */
1614280182Sjfv	    	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0);
1615280182Sjfv	    	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0);
1616280182Sjfv
1617280182Sjfv		/* Set Tx Tail register */
1618280182Sjfv		txr->tail = IXGBE_VFTDT(i);
1619280182Sjfv
1620280182Sjfv		/* Set Ring parameters */
1621280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(i),
1622280182Sjfv		       (tdba & 0x00000000ffffffffULL));
1623280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(i), (tdba >> 32));
1624280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(i),
1625280182Sjfv		    adapter->num_tx_desc *
1626280182Sjfv		    sizeof(struct ixgbe_legacy_tx_desc));
1627280182Sjfv		txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(i));
1628280182Sjfv		txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
1629280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(i), txctrl);
1630280182Sjfv
1631280182Sjfv		/* Now enable */
1632280182Sjfv		txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i));
1633280182Sjfv		txdctl |= IXGBE_TXDCTL_ENABLE;
1634280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl);
1635280182Sjfv	}
1636280182Sjfv
1637280182Sjfv	return;
1638280182Sjfv}
1639280182Sjfv
1640280182Sjfv
1641280182Sjfv/*********************************************************************
1642280182Sjfv *
1643280182Sjfv *  Setup receive registers and features.
1644280182Sjfv *
1645280182Sjfv **********************************************************************/
1646280182Sjfv#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
1647280182Sjfv
1648280182Sjfvstatic void
1649280182Sjfvixv_initialize_receive_units(struct adapter *adapter)
1650280182Sjfv{
1651280182Sjfv	struct	rx_ring	*rxr = adapter->rx_rings;
1652280182Sjfv	struct ixgbe_hw	*hw = &adapter->hw;
1653295008Ssbruno	struct ifnet	*ifp = adapter->ifp;
1654295008Ssbruno	u32		bufsz, rxcsum, psrtype;
1655280182Sjfv
1656295008Ssbruno	if (ifp->if_mtu > ETHERMTU)
1657280182Sjfv		bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1658295008Ssbruno	else
1659280182Sjfv		bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
1660280182Sjfv
1661295008Ssbruno	psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR |
1662295008Ssbruno	    IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR |
1663295008Ssbruno	    IXGBE_PSRTYPE_L2HDR;
1664295008Ssbruno
1665295008Ssbruno	IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
1666295008Ssbruno
1667295524Ssbruno	/* Tell PF our max_frame size */
1668295524Ssbruno	ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size);
1669295008Ssbruno
1670280182Sjfv	for (int i = 0; i < adapter->num_queues; i++, rxr++) {
1671280182Sjfv		u64 rdba = rxr->rxdma.dma_paddr;
1672280182Sjfv		u32 reg, rxdctl;
1673280182Sjfv
1674295008Ssbruno		/* Disable the queue */
1675295008Ssbruno		rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
1676295524Ssbruno		rxdctl &= ~IXGBE_RXDCTL_ENABLE;
1677295008Ssbruno		IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl);
1678295008Ssbruno		for (int j = 0; j < 10; j++) {
1679295008Ssbruno			if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) &
1680295008Ssbruno			    IXGBE_RXDCTL_ENABLE)
1681295008Ssbruno				msec_delay(1);
1682295008Ssbruno			else
1683295008Ssbruno				break;
1684295008Ssbruno		}
1685295008Ssbruno		wmb();
1686280182Sjfv		/* Setup the Base and Length of the Rx Descriptor Ring */
1687280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(i),
1688280182Sjfv		    (rdba & 0x00000000ffffffffULL));
1689280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i),
1690280182Sjfv		    (rdba >> 32));
1691280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(i),
1692280182Sjfv		    adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
1693280182Sjfv
1694295008Ssbruno		/* Reset the ring indices */
1695295008Ssbruno		IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0);
1696295008Ssbruno		IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0);
1697295008Ssbruno
1698280182Sjfv		/* Set up the SRRCTL register */
1699280182Sjfv		reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i));
1700280182Sjfv		reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
1701280182Sjfv		reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
1702280182Sjfv		reg |= bufsz;
1703280182Sjfv		reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
1704280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg);
1705280182Sjfv
1706295524Ssbruno		/* Capture  Rx Tail register */
1707280182Sjfv		rxr->tail = IXGBE_VFRDT(rxr->me);
1708280182Sjfv
1709280182Sjfv		/* Do the queue enabling last */
1710295524Ssbruno		rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME;
1711280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl);
1712280182Sjfv		for (int k = 0; k < 10; k++) {
1713280182Sjfv			if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) &
1714280182Sjfv			    IXGBE_RXDCTL_ENABLE)
1715280182Sjfv				break;
1716280182Sjfv			else
1717280182Sjfv				msec_delay(1);
1718280182Sjfv		}
1719280182Sjfv		wmb();
1720295008Ssbruno
1721295008Ssbruno		/* Set the Tail Pointer */
1722295008Ssbruno#ifdef DEV_NETMAP
1723295008Ssbruno		/*
1724295008Ssbruno		 * In netmap mode, we must preserve the buffers made
1725295008Ssbruno		 * available to userspace before the if_init()
1726295008Ssbruno		 * (this is true by default on the TX side, because
1727295008Ssbruno		 * init makes all buffers available to userspace).
1728295008Ssbruno		 *
1729295008Ssbruno		 * netmap_reset() and the device specific routines
1730295008Ssbruno		 * (e.g. ixgbe_setup_receive_rings()) map these
1731295008Ssbruno		 * buffers at the end of the NIC ring, so here we
1732295008Ssbruno		 * must set the RDT (tail) register to make sure
1733295008Ssbruno		 * they are not overwritten.
1734295008Ssbruno		 *
1735295008Ssbruno		 * In this driver the NIC ring starts at RDH = 0,
1736295008Ssbruno		 * RDT points to the last slot available for reception (?),
1737295008Ssbruno		 * so RDT = num_rx_desc - 1 means the whole ring is available.
1738295008Ssbruno		 */
1739295008Ssbruno		if (ifp->if_capenable & IFCAP_NETMAP) {
1740295008Ssbruno			struct netmap_adapter *na = NA(adapter->ifp);
1741295008Ssbruno			struct netmap_kring *kring = &na->rx_rings[i];
1742295008Ssbruno			int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
1743295008Ssbruno
1744295008Ssbruno			IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t);
1745295008Ssbruno		} else
1746295008Ssbruno#endif /* DEV_NETMAP */
1747295008Ssbruno			IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
1748295008Ssbruno			    adapter->num_rx_desc - 1);
1749280182Sjfv	}
1750280182Sjfv
1751280182Sjfv	rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
1752280182Sjfv
1753280182Sjfv	if (ifp->if_capenable & IFCAP_RXCSUM)
1754280182Sjfv		rxcsum |= IXGBE_RXCSUM_PCSD;
1755280182Sjfv
1756280182Sjfv	if (!(rxcsum & IXGBE_RXCSUM_PCSD))
1757280182Sjfv		rxcsum |= IXGBE_RXCSUM_IPPCSE;
1758280182Sjfv
1759280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
1760280182Sjfv
1761280182Sjfv	return;
1762280182Sjfv}
1763280182Sjfv
1764280182Sjfvstatic void
1765280182Sjfvixv_setup_vlan_support(struct adapter *adapter)
1766280182Sjfv{
1767280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1768280182Sjfv	u32		ctrl, vid, vfta, retry;
1769295524Ssbruno	struct rx_ring	*rxr;
1770280182Sjfv
1771280182Sjfv	/*
1772280182Sjfv	** We get here thru init_locked, meaning
1773280182Sjfv	** a soft reset, this has already cleared
1774280182Sjfv	** the VFTA and other state, so if there
1775280182Sjfv	** have been no vlan's registered do nothing.
1776280182Sjfv	*/
1777280182Sjfv	if (adapter->num_vlans == 0)
1778280182Sjfv		return;
1779280182Sjfv
1780280182Sjfv	/* Enable the queues */
1781280182Sjfv	for (int i = 0; i < adapter->num_queues; i++) {
1782280182Sjfv		ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
1783280182Sjfv		ctrl |= IXGBE_RXDCTL_VME;
1784280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl);
1785295524Ssbruno		/*
1786295524Ssbruno		 * Let Rx path know that it needs to store VLAN tag
1787295524Ssbruno		 * as part of extra mbuf info.
1788295524Ssbruno		 */
1789295524Ssbruno		rxr = &adapter->rx_rings[i];
1790295524Ssbruno		rxr->vtag_strip = TRUE;
1791280182Sjfv	}
1792280182Sjfv
1793280182Sjfv	/*
1794280182Sjfv	** A soft reset zero's out the VFTA, so
1795280182Sjfv	** we need to repopulate it now.
1796280182Sjfv	*/
1797280182Sjfv	for (int i = 0; i < IXGBE_VFTA_SIZE; i++) {
1798280182Sjfv		if (ixv_shadow_vfta[i] == 0)
1799280182Sjfv			continue;
1800280182Sjfv		vfta = ixv_shadow_vfta[i];
1801280182Sjfv		/*
1802280182Sjfv		** Reconstruct the vlan id's
1803280182Sjfv		** based on the bits set in each
1804280182Sjfv		** of the array ints.
1805280182Sjfv		*/
1806295524Ssbruno		for (int j = 0; j < 32; j++) {
1807280182Sjfv			retry = 0;
1808280182Sjfv			if ((vfta & (1 << j)) == 0)
1809280182Sjfv				continue;
1810280182Sjfv			vid = (i * 32) + j;
1811280182Sjfv			/* Call the shared code mailbox routine */
1812280182Sjfv			while (ixgbe_set_vfta(hw, vid, 0, TRUE)) {
1813280182Sjfv				if (++retry > 5)
1814280182Sjfv					break;
1815280182Sjfv			}
1816280182Sjfv		}
1817280182Sjfv	}
1818280182Sjfv}
1819280182Sjfv
1820280182Sjfv/*
1821280182Sjfv** This routine is run via an vlan config EVENT,
1822280182Sjfv** it enables us to use the HW Filter table since
1823280182Sjfv** we can get the vlan id. This just creates the
1824280182Sjfv** entry in the soft version of the VFTA, init will
1825280182Sjfv** repopulate the real table.
1826280182Sjfv*/
1827280182Sjfvstatic void
1828280182Sjfvixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
1829280182Sjfv{
1830280182Sjfv	struct adapter	*adapter = ifp->if_softc;
1831280182Sjfv	u16		index, bit;
1832280182Sjfv
1833295524Ssbruno	if (ifp->if_softc != arg) /* Not our event */
1834280182Sjfv		return;
1835280182Sjfv
1836295524Ssbruno	if ((vtag == 0) || (vtag > 4095)) /* Invalid */
1837280182Sjfv		return;
1838280182Sjfv
1839280182Sjfv	IXGBE_CORE_LOCK(adapter);
1840280182Sjfv	index = (vtag >> 5) & 0x7F;
1841280182Sjfv	bit = vtag & 0x1F;
1842280182Sjfv	ixv_shadow_vfta[index] |= (1 << bit);
1843280182Sjfv	++adapter->num_vlans;
1844280182Sjfv	/* Re-init to load the changes */
1845280182Sjfv	ixv_init_locked(adapter);
1846280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
1847280182Sjfv}
1848280182Sjfv
1849280182Sjfv/*
1850280182Sjfv** This routine is run via an vlan
1851280182Sjfv** unconfig EVENT, remove our entry
1852280182Sjfv** in the soft vfta.
1853280182Sjfv*/
1854280182Sjfvstatic void
1855280182Sjfvixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
1856280182Sjfv{
1857280182Sjfv	struct adapter	*adapter = ifp->if_softc;
1858280182Sjfv	u16		index, bit;
1859280182Sjfv
1860280182Sjfv	if (ifp->if_softc !=  arg)
1861280182Sjfv		return;
1862280182Sjfv
1863280182Sjfv	if ((vtag == 0) || (vtag > 4095))	/* Invalid */
1864280182Sjfv		return;
1865280182Sjfv
1866280182Sjfv	IXGBE_CORE_LOCK(adapter);
1867280182Sjfv	index = (vtag >> 5) & 0x7F;
1868280182Sjfv	bit = vtag & 0x1F;
1869280182Sjfv	ixv_shadow_vfta[index] &= ~(1 << bit);
1870280182Sjfv	--adapter->num_vlans;
1871280182Sjfv	/* Re-init to load the changes */
1872280182Sjfv	ixv_init_locked(adapter);
1873280182Sjfv	IXGBE_CORE_UNLOCK(adapter);
1874280182Sjfv}
1875280182Sjfv
1876280182Sjfvstatic void
1877280182Sjfvixv_enable_intr(struct adapter *adapter)
1878280182Sjfv{
1879280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1880280182Sjfv	struct ix_queue *que = adapter->queues;
1881280182Sjfv	u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
1882280182Sjfv
1883280182Sjfv
1884280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
1885280182Sjfv
1886280182Sjfv	mask = IXGBE_EIMS_ENABLE_MASK;
1887280182Sjfv	mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
1888280182Sjfv	IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask);
1889280182Sjfv
1890280182Sjfv        for (int i = 0; i < adapter->num_queues; i++, que++)
1891280182Sjfv		ixv_enable_queue(adapter, que->msix);
1892280182Sjfv
1893280182Sjfv	IXGBE_WRITE_FLUSH(hw);
1894280182Sjfv
1895280182Sjfv	return;
1896280182Sjfv}
1897280182Sjfv
1898280182Sjfvstatic void
1899280182Sjfvixv_disable_intr(struct adapter *adapter)
1900280182Sjfv{
1901280182Sjfv	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0);
1902280182Sjfv	IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, ~0);
1903280182Sjfv	IXGBE_WRITE_FLUSH(&adapter->hw);
1904280182Sjfv	return;
1905280182Sjfv}
1906280182Sjfv
1907280182Sjfv/*
1908280182Sjfv** Setup the correct IVAR register for a particular MSIX interrupt
1909280182Sjfv**  - entry is the register array entry
1910280182Sjfv**  - vector is the MSIX vector for this queue
1911280182Sjfv**  - type is RX/TX/MISC
1912280182Sjfv*/
1913280182Sjfvstatic void
1914280182Sjfvixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
1915280182Sjfv{
1916280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1917280182Sjfv	u32 ivar, index;
1918280182Sjfv
1919280182Sjfv	vector |= IXGBE_IVAR_ALLOC_VAL;
1920280182Sjfv
1921280182Sjfv	if (type == -1) { /* MISC IVAR */
1922280182Sjfv		ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC);
1923280182Sjfv		ivar &= ~0xFF;
1924280182Sjfv		ivar |= vector;
1925280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar);
1926280182Sjfv	} else {	/* RX/TX IVARS */
1927280182Sjfv		index = (16 * (entry & 1)) + (8 * type);
1928280182Sjfv		ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1));
1929280182Sjfv		ivar &= ~(0xFF << index);
1930280182Sjfv		ivar |= (vector << index);
1931280182Sjfv		IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar);
1932280182Sjfv	}
1933280182Sjfv}
1934280182Sjfv
1935280182Sjfvstatic void
1936280182Sjfvixv_configure_ivars(struct adapter *adapter)
1937280182Sjfv{
1938280182Sjfv	struct  ix_queue *que = adapter->queues;
1939280182Sjfv
1940280182Sjfv        for (int i = 0; i < adapter->num_queues; i++, que++) {
1941280182Sjfv		/* First the RX queue entry */
1942280182Sjfv                ixv_set_ivar(adapter, i, que->msix, 0);
1943280182Sjfv		/* ... and the TX */
1944280182Sjfv		ixv_set_ivar(adapter, i, que->msix, 1);
1945280182Sjfv		/* Set an initial value in EITR */
1946280182Sjfv                IXGBE_WRITE_REG(&adapter->hw,
1947280182Sjfv                    IXGBE_VTEITR(que->msix), IXV_EITR_DEFAULT);
1948280182Sjfv	}
1949280182Sjfv
1950280182Sjfv	/* For the mailbox interrupt */
1951280182Sjfv        ixv_set_ivar(adapter, 1, adapter->vector, -1);
1952280182Sjfv}
1953280182Sjfv
1954280182Sjfv
1955280182Sjfv/*
1956280182Sjfv** Tasklet handler for MSIX MBX interrupts
1957280182Sjfv**  - do outside interrupt since it might sleep
1958280182Sjfv*/
1959280182Sjfvstatic void
1960280182Sjfvixv_handle_mbx(void *context, int pending)
1961280182Sjfv{
1962280182Sjfv	struct adapter  *adapter = context;
1963280182Sjfv
1964280182Sjfv	ixgbe_check_link(&adapter->hw,
1965280182Sjfv	    &adapter->link_speed, &adapter->link_up, 0);
1966280182Sjfv	ixv_update_link_status(adapter);
1967280182Sjfv}
1968280182Sjfv
1969280182Sjfv/*
1970280182Sjfv** The VF stats registers never have a truely virgin
1971280182Sjfv** starting point, so this routine tries to make an
1972280182Sjfv** artificial one, marking ground zero on attach as
1973280182Sjfv** it were.
1974280182Sjfv*/
1975280182Sjfvstatic void
1976280182Sjfvixv_save_stats(struct adapter *adapter)
1977280182Sjfv{
1978280182Sjfv	if (adapter->stats.vf.vfgprc || adapter->stats.vf.vfgptc) {
1979280182Sjfv		adapter->stats.vf.saved_reset_vfgprc +=
1980280182Sjfv		    adapter->stats.vf.vfgprc - adapter->stats.vf.base_vfgprc;
1981280182Sjfv		adapter->stats.vf.saved_reset_vfgptc +=
1982280182Sjfv		    adapter->stats.vf.vfgptc - adapter->stats.vf.base_vfgptc;
1983280182Sjfv		adapter->stats.vf.saved_reset_vfgorc +=
1984280182Sjfv		    adapter->stats.vf.vfgorc - adapter->stats.vf.base_vfgorc;
1985280182Sjfv		adapter->stats.vf.saved_reset_vfgotc +=
1986280182Sjfv		    adapter->stats.vf.vfgotc - adapter->stats.vf.base_vfgotc;
1987280182Sjfv		adapter->stats.vf.saved_reset_vfmprc +=
1988280182Sjfv		    adapter->stats.vf.vfmprc - adapter->stats.vf.base_vfmprc;
1989280182Sjfv	}
1990280182Sjfv}
1991280182Sjfv
1992280182Sjfvstatic void
1993280182Sjfvixv_init_stats(struct adapter *adapter)
1994280182Sjfv{
1995280182Sjfv	struct ixgbe_hw *hw = &adapter->hw;
1996280182Sjfv
1997280182Sjfv	adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC);
1998280182Sjfv	adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB);
1999280182Sjfv	adapter->stats.vf.last_vfgorc |=
2000280182Sjfv	    (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32);
2001280182Sjfv
2002280182Sjfv	adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC);
2003280182Sjfv	adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB);
2004280182Sjfv	adapter->stats.vf.last_vfgotc |=
2005280182Sjfv	    (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32);
2006280182Sjfv
2007280182Sjfv	adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC);
2008280182Sjfv
2009280182Sjfv	adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc;
2010280182Sjfv	adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc;
2011280182Sjfv	adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc;
2012280182Sjfv	adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc;
2013280182Sjfv	adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc;
2014280182Sjfv}
2015280182Sjfv
2016280182Sjfv#define UPDATE_STAT_32(reg, last, count)		\
2017280182Sjfv{							\
2018280182Sjfv	u32 current = IXGBE_READ_REG(hw, reg);		\
2019280182Sjfv	if (current < last)				\
2020280182Sjfv		count += 0x100000000LL;			\
2021280182Sjfv	last = current;					\
2022280182Sjfv	count &= 0xFFFFFFFF00000000LL;			\
2023280182Sjfv	count |= current;				\
2024280182Sjfv}
2025280182Sjfv
2026280182Sjfv#define UPDATE_STAT_36(lsb, msb, last, count) 		\
2027280182Sjfv{							\
2028280182Sjfv	u64 cur_lsb = IXGBE_READ_REG(hw, lsb);		\
2029280182Sjfv	u64 cur_msb = IXGBE_READ_REG(hw, msb);		\
2030280182Sjfv	u64 current = ((cur_msb << 32) | cur_lsb);	\
2031280182Sjfv	if (current < last)				\
2032280182Sjfv		count += 0x1000000000LL;		\
2033280182Sjfv	last = current;					\
2034280182Sjfv	count &= 0xFFFFFFF000000000LL;			\
2035280182Sjfv	count |= current;				\
2036280182Sjfv}
2037280182Sjfv
2038280182Sjfv/*
2039280182Sjfv** ixv_update_stats - Update the board statistics counters.
2040280182Sjfv*/
2041280182Sjfvvoid
2042280182Sjfvixv_update_stats(struct adapter *adapter)
2043280182Sjfv{
2044280182Sjfv        struct ixgbe_hw *hw = &adapter->hw;
2045280182Sjfv
2046280182Sjfv        UPDATE_STAT_32(IXGBE_VFGPRC, adapter->stats.vf.last_vfgprc,
2047280182Sjfv	    adapter->stats.vf.vfgprc);
2048280182Sjfv        UPDATE_STAT_32(IXGBE_VFGPTC, adapter->stats.vf.last_vfgptc,
2049280182Sjfv	    adapter->stats.vf.vfgptc);
2050280182Sjfv        UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB,
2051280182Sjfv	    adapter->stats.vf.last_vfgorc, adapter->stats.vf.vfgorc);
2052280182Sjfv        UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB,
2053280182Sjfv	    adapter->stats.vf.last_vfgotc, adapter->stats.vf.vfgotc);
2054280182Sjfv        UPDATE_STAT_32(IXGBE_VFMPRC, adapter->stats.vf.last_vfmprc,
2055280182Sjfv	    adapter->stats.vf.vfmprc);
2056280182Sjfv}
2057280182Sjfv
2058280182Sjfv/*
2059280182Sjfv * Add statistic sysctls for the VF.
2060280182Sjfv */
2061280182Sjfvstatic void
2062280182Sjfvixv_add_stats_sysctls(struct adapter *adapter)
2063280182Sjfv{
2064280182Sjfv	device_t dev = adapter->dev;
2065280182Sjfv	struct ix_queue *que = &adapter->queues[0];
2066280182Sjfv	struct tx_ring *txr = que->txr;
2067280182Sjfv	struct rx_ring *rxr = que->rxr;
2068280182Sjfv
2069280182Sjfv	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
2070280182Sjfv	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
2071280182Sjfv	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
2072280182Sjfv	struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
2073280182Sjfv
2074280182Sjfv	struct sysctl_oid *stat_node, *queue_node;
2075280182Sjfv	struct sysctl_oid_list *stat_list, *queue_list;
2076280182Sjfv
2077280182Sjfv	/* Driver Statistics */
2078283620Serj	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",
2079280182Sjfv			CTLFLAG_RD, &adapter->dropped_pkts,
2080280182Sjfv			"Driver dropped packets");
2081283620Serj	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed",
2082280182Sjfv			CTLFLAG_RD, &adapter->mbuf_defrag_failed,
2083280182Sjfv			"m_defrag() failed");
2084283620Serj	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events",
2085280182Sjfv			CTLFLAG_RD, &adapter->watchdog_events,
2086280182Sjfv			"Watchdog timeouts");
2087280182Sjfv
2088280182Sjfv	stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac",
2089280182Sjfv				    CTLFLAG_RD, NULL,
2090280182Sjfv				    "VF Statistics (read from HW registers)");
2091280182Sjfv	stat_list = SYSCTL_CHILDREN(stat_node);
2092280182Sjfv
2093280182Sjfv	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd",
2094280182Sjfv			CTLFLAG_RD, &stats->vfgprc,
2095280182Sjfv			"Good Packets Received");
2096280182Sjfv	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd",
2097280182Sjfv			CTLFLAG_RD, &stats->vfgorc,
2098280182Sjfv			"Good Octets Received");
2099280182Sjfv	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd",
2100280182Sjfv			CTLFLAG_RD, &stats->vfmprc,
2101280182Sjfv			"Multicast Packets Received");
2102280182Sjfv	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
2103280182Sjfv			CTLFLAG_RD, &stats->vfgptc,
2104280182Sjfv			"Good Packets Transmitted");
2105280182Sjfv	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd",
2106280182Sjfv			CTLFLAG_RD, &stats->vfgotc,
2107280182Sjfv			"Good Octets Transmitted");
2108280182Sjfv
2109280182Sjfv	queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "que",
2110280182Sjfv				    CTLFLAG_RD, NULL,
2111280182Sjfv				    "Queue Statistics (collected by SW)");
2112280182Sjfv	queue_list = SYSCTL_CHILDREN(queue_node);
2113280182Sjfv
2114280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs",
2115280182Sjfv			CTLFLAG_RD, &(que->irqs),
2116280182Sjfv			"IRQs on queue");
2117280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_irqs",
2118280182Sjfv			CTLFLAG_RD, &(rxr->rx_irq),
2119280182Sjfv			"RX irqs on queue");
2120280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets",
2121280182Sjfv			CTLFLAG_RD, &(rxr->rx_packets),
2122280182Sjfv			"RX packets");
2123280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes",
2124280182Sjfv			CTLFLAG_RD, &(rxr->rx_bytes),
2125280182Sjfv			"RX bytes");
2126280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded",
2127280182Sjfv			CTLFLAG_RD, &(rxr->rx_discarded),
2128280182Sjfv			"Discarded RX packets");
2129280182Sjfv
2130280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
2131280182Sjfv			CTLFLAG_RD, &(txr->total_packets),
2132280182Sjfv			"TX Packets");
2133283620Serj	SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "tx_bytes",
2134283620Serj			CTLFLAG_RD, &(txr->bytes), 0,
2135280182Sjfv			"TX Bytes");
2136280182Sjfv	SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc",
2137280182Sjfv			CTLFLAG_RD, &(txr->no_desc_avail),
2138280182Sjfv			"# of times not enough descriptors were available during TX");
2139280182Sjfv}
2140280182Sjfv
2141294034Ssbrunostatic void
2142294034Ssbrunoixv_set_sysctl_value(struct adapter *adapter, const char *name,
2143294034Ssbruno	const char *description, int *limit, int value)
2144294034Ssbruno{
2145294034Ssbruno	*limit = value;
2146294034Ssbruno	SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
2147294034Ssbruno	    SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
2148294034Ssbruno	    OID_AUTO, name, CTLFLAG_RW, limit, value, description);
2149294034Ssbruno}
2150294034Ssbruno
2151280182Sjfv/**********************************************************************
2152280182Sjfv *
2153280182Sjfv *  This routine is called only when em_display_debug_stats is enabled.
2154280182Sjfv *  This routine provides a way to take a look at important statistics
2155280182Sjfv *  maintained by the driver and hardware.
2156280182Sjfv *
2157280182Sjfv **********************************************************************/
2158280182Sjfvstatic void
2159280182Sjfvixv_print_debug_info(struct adapter *adapter)
2160280182Sjfv{
2161280182Sjfv        device_t dev = adapter->dev;
2162280182Sjfv        struct ixgbe_hw         *hw = &adapter->hw;
2163280182Sjfv        struct ix_queue         *que = adapter->queues;
2164280182Sjfv        struct rx_ring          *rxr;
2165280182Sjfv        struct tx_ring          *txr;
2166280182Sjfv        struct lro_ctrl         *lro;
2167280182Sjfv
2168280182Sjfv        device_printf(dev,"Error Byte Count = %u \n",
2169280182Sjfv            IXGBE_READ_REG(hw, IXGBE_ERRBC));
2170280182Sjfv
2171280182Sjfv        for (int i = 0; i < adapter->num_queues; i++, que++) {
2172280182Sjfv                txr = que->txr;
2173280182Sjfv                rxr = que->rxr;
2174280182Sjfv                lro = &rxr->lro;
2175280182Sjfv                device_printf(dev,"QUE(%d) IRQs Handled: %lu\n",
2176280182Sjfv                    que->msix, (long)que->irqs);
2177280182Sjfv                device_printf(dev,"RX(%d) Packets Received: %lld\n",
2178280182Sjfv                    rxr->me, (long long)rxr->rx_packets);
2179280182Sjfv                device_printf(dev,"RX(%d) Bytes Received: %lu\n",
2180280182Sjfv                    rxr->me, (long)rxr->rx_bytes);
2181280182Sjfv                device_printf(dev,"RX(%d) LRO Queued= %d\n",
2182280182Sjfv                    rxr->me, lro->lro_queued);
2183280182Sjfv                device_printf(dev,"RX(%d) LRO Flushed= %d\n",
2184280182Sjfv                    rxr->me, lro->lro_flushed);
2185280182Sjfv                device_printf(dev,"TX(%d) Packets Sent: %lu\n",
2186280182Sjfv                    txr->me, (long)txr->total_packets);
2187280182Sjfv                device_printf(dev,"TX(%d) NO Desc Avail: %lu\n",
2188280182Sjfv                    txr->me, (long)txr->no_desc_avail);
2189280182Sjfv        }
2190280182Sjfv
2191280182Sjfv        device_printf(dev,"MBX IRQ Handled: %lu\n",
2192283620Serj            (long)adapter->link_irq);
2193280182Sjfv        return;
2194280182Sjfv}
2195280182Sjfv
2196280182Sjfvstatic int
2197280182Sjfvixv_sysctl_debug(SYSCTL_HANDLER_ARGS)
2198280182Sjfv{
2199280182Sjfv	int error, result;
2200280182Sjfv	struct adapter *adapter;
2201280182Sjfv
2202280182Sjfv	result = -1;
2203280182Sjfv	error = sysctl_handle_int(oidp, &result, 0, req);
2204280182Sjfv
2205280182Sjfv	if (error || !req->newptr)
2206280182Sjfv		return (error);
2207280182Sjfv
2208280182Sjfv	if (result == 1) {
2209280182Sjfv		adapter = (struct adapter *) arg1;
2210280182Sjfv		ixv_print_debug_info(adapter);
2211280182Sjfv	}
2212280182Sjfv	return error;
2213280182Sjfv}
2214280182Sjfv
2215