xref: /src/sys/dev/aq/aq_main.c (revision 96156003ec0c70de88a448d48d8e9bd37913589f)
1 /*
2  * aQuantia Corporation Network Driver
3  * Copyright (C) 2019 aQuantia Corporation. All rights reserved
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *   (1) Redistributions of source code must retain the above
10  *   copyright notice, this list of conditions and the following
11  *   disclaimer.
12  *
13  *   (2) Redistributions in binary form must reproduce the above
14  *   copyright notice, this list of conditions and the following
15  *   disclaimer in the documentation and/or other materials provided
16  *   with the distribution.
17  *
18  *   (3)The name of the author may not be used to endorse or promote
19  *   products derived from this software without specific prior
20  *   written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 
38 #include "opt_inet.h"
39 #include "opt_inet6.h"
40 #include "opt_rss.h"
41 
42 #include <sys/param.h>
43 #include <sys/bitstring.h>
44 #include <sys/bus.h>
45 #include <sys/endian.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/module.h>
49 #include <sys/priv.h>
50 #include <sys/rman.h>
51 #include <sys/sbuf.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/sysctl.h>
55 
56 #include <machine/bus.h>
57 #include <machine/resource.h>
58 
59 #include <dev/pci/pcireg.h>
60 #include <dev/pci/pcivar.h>
61 
62 #include <net/ethernet.h>
63 #include <net/if.h>
64 #include <net/if_dl.h>
65 #include <net/if_media.h>
66 #include <net/if_var.h>
67 #include <net/iflib.h>
68 #include <net/rss_config.h>
69 
70 #include "ifdi_if.h"
71 
72 #include "aq_device.h"
73 #include "aq_fw.h"
74 #include "aq_hw.h"
75 #include "aq_hw_llh.h"
76 #include "aq_ring.h"
77 #include "aq_dbg.h"
78 
79 
80 #define	AQ_XXX_UNIMPLEMENTED_FUNCTION	do {				\
81 	printf("atlantic: unimplemented function: %s@%s:%d\n", __func__, 	\
82 	    __FILE__, __LINE__);					\
83 } while (0)
84 
85 MALLOC_DEFINE(M_AQ, "aq", "Aquantia");
86 
87 char aq_driver_version[] = AQ_VER;
88 
89 #define AQUANTIA_VENDOR_ID 0x1D6A
90 
91 #define AQ_DEVICE_ID_0001	0x0001
92 #define AQ_DEVICE_ID_D100	0xD100
93 #define AQ_DEVICE_ID_D107	0xD107
94 #define AQ_DEVICE_ID_D108	0xD108
95 #define AQ_DEVICE_ID_D109	0xD109
96 
97 #define AQ_DEVICE_ID_AQC100	0x00B1
98 #define AQ_DEVICE_ID_AQC107	0x07B1
99 #define AQ_DEVICE_ID_AQC108	0x08B1
100 #define AQ_DEVICE_ID_AQC109	0x09B1
101 #define AQ_DEVICE_ID_AQC111	0x11B1
102 #define AQ_DEVICE_ID_AQC112	0x12B1
103 
104 #define AQ_DEVICE_ID_AQC100S	0x80B1
105 #define AQ_DEVICE_ID_AQC107S	0x87B1
106 #define AQ_DEVICE_ID_AQC108S	0x88B1
107 #define AQ_DEVICE_ID_AQC109S	0x89B1
108 #define AQ_DEVICE_ID_AQC111S	0x91B1
109 #define AQ_DEVICE_ID_AQC112S	0x92B1
110 
111 static pci_vendor_info_t aq_vendor_info_array[] = {
112 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_0001,
113 	    "Aquantia AQtion 10Gbit Network Adapter"),
114 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D107,
115 	    "Aquantia AQtion 10Gbit Network Adapter"),
116 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D108,
117 	    "Aquantia AQtion 5Gbit Network Adapter"),
118 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D109,
119 	    "Aquantia AQtion 2.5Gbit Network Adapter"),
120 
121 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC107,
122 	    "Aquantia AQtion 10Gbit Network Adapter"),
123 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC108,
124 	    "Aquantia AQtion 5Gbit Network Adapter"),
125 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC109,
126 	    "Aquantia AQtion 2.5Gbit Network Adapter"),
127 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC100,
128 	    "Aquantia AQtion 10Gbit Network Adapter"),
129 
130 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC107S,
131 	    "Aquantia AQtion 10Gbit Network Adapter"),
132 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC108S,
133 	    "Aquantia AQtion 5Gbit Network Adapter"),
134 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC109S,
135 	    "Aquantia AQtion 2.5Gbit Network Adapter"),
136 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC100S,
137 	    "Aquantia AQtion 10Gbit Network Adapter"),
138 
139 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC111,
140 	    "Aquantia AQtion 5Gbit Network Adapter"),
141 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC112,
142 	    "Aquantia AQtion 2.5Gbit Network Adapter"),
143 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC111S,
144 	    "Aquantia AQtion 5Gbit Network Adapter"),
145 	PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC112S,
146 	    "Aquantia AQtion 2.5Gbit Network Adapter"),
147 
148 	PVID_END
149 };
150 
151 
152 /* Device setup, teardown, etc */
153 static void *aq_register(device_t dev);
154 static int aq_if_attach_pre(if_ctx_t ctx);
155 static int aq_if_attach_post(if_ctx_t ctx);
156 static int aq_if_detach(if_ctx_t ctx);
157 static int aq_if_shutdown(if_ctx_t ctx);
158 static int aq_if_suspend(if_ctx_t ctx);
159 static int aq_if_resume(if_ctx_t ctx);
160 
161 /* Soft queue setup and teardown */
162 static int aq_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
163 		    uint64_t *paddrs, int ntxqs, int ntxqsets);
164 static int aq_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
165 		    uint64_t *paddrs, int nrxqs, int nrxqsets);
166 static void aq_if_queues_free(if_ctx_t ctx);
167 
168 /* Device configuration */
169 static void aq_if_init(if_ctx_t ctx);
170 static void aq_if_stop(if_ctx_t ctx);
171 static void aq_if_multi_set(if_ctx_t ctx);
172 static int aq_if_mtu_set(if_ctx_t ctx, uint32_t mtu);
173 static void aq_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr);
174 static int aq_if_media_change(if_ctx_t ctx);
175 static int aq_if_promisc_set(if_ctx_t ctx, int flags);
176 static uint64_t aq_if_get_counter(if_ctx_t ctx, ift_counter cnt);
177 static void aq_if_timer(if_ctx_t ctx, uint16_t qid);
178 static int aq_hw_capabilities(struct aq_dev *softc);
179 static void aq_add_stats_sysctls(struct aq_dev *softc);
180 
181 /* Interrupt enable / disable */
182 static void	aq_if_enable_intr(if_ctx_t ctx);
183 static void	aq_if_disable_intr(if_ctx_t ctx);
184 static int	aq_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid);
185 static int	aq_if_msix_intr_assign(if_ctx_t ctx, int msix);
186 
187 /* VLAN support */
188 static bool aq_is_vlan_promisc_required(struct aq_dev *softc);
189 static void aq_update_vlan_filters(struct aq_dev *softc);
190 static void aq_if_vlan_register(if_ctx_t ctx, uint16_t vtag);
191 static void aq_if_vlan_unregister(if_ctx_t ctx, uint16_t vtag);
192 
193 /* Informational/diagnostic */
194 static void	aq_if_led_func(if_ctx_t ctx, int onoff);
195 
196 static device_method_t aq_methods[] = {
197 	DEVMETHOD(device_register, aq_register),
198 	DEVMETHOD(device_probe, iflib_device_probe),
199 	DEVMETHOD(device_attach, iflib_device_attach),
200 	DEVMETHOD(device_detach, iflib_device_detach),
201 	DEVMETHOD(device_shutdown, iflib_device_shutdown),
202 	DEVMETHOD(device_suspend, iflib_device_suspend),
203 	DEVMETHOD(device_resume, iflib_device_resume),
204 
205 	DEVMETHOD_END
206 };
207 
208 static driver_t aq_driver = {
209 	"aq", aq_methods, sizeof(struct aq_dev),
210 };
211 
212 #if __FreeBSD_version >= 1400058
213 DRIVER_MODULE(atlantic, pci, aq_driver, 0, 0);
214 #else
215 static devclass_t aq_devclass;
216 DRIVER_MODULE(atlantic, pci, aq_driver, aq_devclass, 0, 0);
217 #endif
218 
219 MODULE_DEPEND(atlantic, pci, 1, 1, 1);
220 MODULE_DEPEND(atlantic, ether, 1, 1, 1);
221 MODULE_DEPEND(atlantic, iflib, 1, 1, 1);
222 
223 IFLIB_PNP_INFO(pci, atlantic, aq_vendor_info_array);
224 
225 static device_method_t aq_if_methods[] = {
226 	/* Device setup, teardown, etc */
227 	DEVMETHOD(ifdi_attach_pre, aq_if_attach_pre),
228 	DEVMETHOD(ifdi_attach_post, aq_if_attach_post),
229 	DEVMETHOD(ifdi_detach, aq_if_detach),
230 
231 	DEVMETHOD(ifdi_shutdown, aq_if_shutdown),
232 	DEVMETHOD(ifdi_suspend, aq_if_suspend),
233 	DEVMETHOD(ifdi_resume, aq_if_resume),
234 
235 	/* Soft queue setup and teardown */
236 	DEVMETHOD(ifdi_tx_queues_alloc, aq_if_tx_queues_alloc),
237 	DEVMETHOD(ifdi_rx_queues_alloc, aq_if_rx_queues_alloc),
238 	DEVMETHOD(ifdi_queues_free, aq_if_queues_free),
239 
240 	/* Device configuration */
241 	DEVMETHOD(ifdi_init, aq_if_init),
242 	DEVMETHOD(ifdi_stop, aq_if_stop),
243 	DEVMETHOD(ifdi_multi_set, aq_if_multi_set),
244 	DEVMETHOD(ifdi_mtu_set, aq_if_mtu_set),
245 	DEVMETHOD(ifdi_media_status, aq_if_media_status),
246 	DEVMETHOD(ifdi_media_change, aq_if_media_change),
247 	DEVMETHOD(ifdi_promisc_set, aq_if_promisc_set),
248 	DEVMETHOD(ifdi_get_counter, aq_if_get_counter),
249 	DEVMETHOD(ifdi_update_admin_status, aq_if_update_admin_status),
250 	DEVMETHOD(ifdi_timer, aq_if_timer),
251 
252 	/* Interrupt enable / disable */
253 	DEVMETHOD(ifdi_intr_enable, aq_if_enable_intr),
254 	DEVMETHOD(ifdi_intr_disable, aq_if_disable_intr),
255 	DEVMETHOD(ifdi_rx_queue_intr_enable, aq_if_rx_queue_intr_enable),
256 	DEVMETHOD(ifdi_tx_queue_intr_enable, aq_if_rx_queue_intr_enable),
257 	DEVMETHOD(ifdi_msix_intr_assign, aq_if_msix_intr_assign),
258 
259 	/* VLAN support */
260 	DEVMETHOD(ifdi_vlan_register, aq_if_vlan_register),
261 	DEVMETHOD(ifdi_vlan_unregister, aq_if_vlan_unregister),
262 
263 	/* Informational/diagnostic */
264 	DEVMETHOD(ifdi_led_func, aq_if_led_func),
265 
266 	DEVMETHOD_END
267 };
268 
269 static driver_t aq_if_driver = {
270 	"aq_if", aq_if_methods, sizeof(struct aq_dev)
271 };
272 
273 static struct if_shared_ctx aq_sctx_init = {
274 	.isc_magic = IFLIB_MAGIC,
275 	.isc_q_align = PAGE_SIZE,
276 	.isc_tx_maxsize = HW_ATL_B0_TSO_SIZE,
277 	.isc_tx_maxsegsize = HW_ATL_B0_MTU_JUMBO,
278 #if __FreeBSD__ >= 12
279 	.isc_tso_maxsize = HW_ATL_B0_TSO_SIZE,
280 	.isc_tso_maxsegsize = HW_ATL_B0_MTU_JUMBO,
281 #endif
282 	.isc_rx_maxsize = HW_ATL_B0_MTU_JUMBO,
283 	.isc_rx_nsegments = 16,
284 	.isc_rx_maxsegsize = PAGE_SIZE,
285 	.isc_nfl = 1,
286 	.isc_nrxqs = 1,
287 	.isc_ntxqs = 1,
288 	.isc_admin_intrcnt = 1,
289 	.isc_vendor_info = aq_vendor_info_array,
290 	.isc_driver_version = aq_driver_version,
291 	.isc_driver = &aq_if_driver,
292 	.isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP |
293 	    IFLIB_NEED_ZERO_CSUM,
294 
295 	.isc_nrxd_min = {HW_ATL_B0_MIN_RXD},
296 	.isc_ntxd_min = {HW_ATL_B0_MIN_TXD},
297 	.isc_nrxd_max = {HW_ATL_B0_MAX_RXD},
298 	.isc_ntxd_max = {HW_ATL_B0_MAX_TXD},
299 	.isc_nrxd_default = {PAGE_SIZE / sizeof(aq_txc_desc_t) * 4},
300 	.isc_ntxd_default = {PAGE_SIZE / sizeof(aq_txc_desc_t) * 4},
301 };
302 
303 /*
304  * TUNEABLE PARAMETERS:
305  */
306 
307 static SYSCTL_NODE(_hw, OID_AUTO, aq, CTLFLAG_RD, 0, "Atlantic driver parameters");
308 /* UDP Receive-Side Scaling */
309 static int aq_enable_rss_udp = 1;
310 SYSCTL_INT(_hw_aq, OID_AUTO, enable_rss_udp, CTLFLAG_RDTUN, &aq_enable_rss_udp,
311      0, "Enable Receive-Side Scaling (RSS) for UDP");
312 
313 
314 /*
315  * Device Methods
316  */
317 static void *
aq_register(device_t dev)318 aq_register(device_t dev)
319 {
320 	return (&aq_sctx_init);
321 }
322 
323 static int
aq_if_attach_pre(if_ctx_t ctx)324 aq_if_attach_pre(if_ctx_t ctx)
325 {
326 	struct aq_dev *softc;
327 	struct aq_hw *hw;
328 	if_softc_ctx_t scctx;
329 	int rc;
330 
331 	AQ_DBG_ENTER();
332 	softc = iflib_get_softc(ctx);
333 	rc = 0;
334 
335 	softc->ctx = ctx;
336 	softc->dev = iflib_get_dev(ctx);
337 	softc->media = iflib_get_media(ctx);
338 	softc->scctx = iflib_get_softc_ctx(ctx);
339 	softc->sctx = iflib_get_sctx(ctx);
340 	scctx = softc->scctx;
341 
342 	softc->mmio_rid = PCIR_BAR(0);
343 	softc->mmio_res = bus_alloc_resource_any(softc->dev, SYS_RES_MEMORY,
344 	    &softc->mmio_rid, RF_ACTIVE|RF_SHAREABLE);
345 	if (softc->mmio_res == NULL) {
346 		device_printf(softc->dev,
347 		    "failed to allocate MMIO resources\n");
348 		rc = ENXIO;
349 		goto fail;
350 	}
351 
352 	softc->mmio_tag = rman_get_bustag(softc->mmio_res);
353 	softc->mmio_handle = rman_get_bushandle(softc->mmio_res);
354 	softc->mmio_size = rman_get_size(softc->mmio_res);
355 	softc->hw.hw_addr = (uint8_t*) softc->mmio_handle;
356 	hw = &softc->hw;
357 	hw->link_rate = aq_fw_speed_auto;
358 	hw->itr = -1;
359 	hw->fc.fc_rx = 1;
360 	hw->fc.fc_tx = 1;
361 	softc->linkup = 0U;
362 
363 	/* Look up ops and caps. */
364 	rc = aq_hw_mpi_create(hw);
365 	if (rc < 0) {
366 		AQ_DBG_ERROR(" %s: aq_hw_mpi_create fail err=%d", __func__, rc);
367 		goto fail;
368 	}
369 
370 	if (hw->fast_start_enabled) {
371 		if (hw->fw_ops && hw->fw_ops->reset)
372 			hw->fw_ops->reset(hw);
373 	} else
374 		aq_hw_reset(&softc->hw);
375 	aq_hw_capabilities(softc);
376 
377 	if (aq_hw_get_mac_permanent(hw, hw->mac_addr) < 0) {
378 		AQ_DBG_ERROR("Unable to get mac addr from hw");
379 		goto fail;
380 	};
381 
382 	softc->admin_ticks = 0;
383 
384 	iflib_set_mac(ctx, hw->mac_addr);
385 #if __FreeBSD__ < 13
386 	/* since FreeBSD13 deadlock due to calling iflib_led_func() under CTX_LOCK() */
387 	iflib_led_create(ctx);
388 #endif
389 	scctx->isc_tx_csum_flags = CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_TSO;
390 #if __FreeBSD__ >= 12
391 	scctx->isc_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_HWCSUM |
392 	    IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWFILTER | IFCAP_VLAN_MTU |
393 	    IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
394 	scctx->isc_capenable = scctx->isc_capabilities;
395 #else
396 	if_t ifp;
397 	ifp = iflib_get_ifp(ctx);
398 	if_setcapenable(ifp,  IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_HWCSUM |
399 	    IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_VLAN_HWFILTER | IFCAP_VLAN_MTU |
400 	    IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM;
401 #endif
402 	scctx->isc_tx_nsegments = 31,
403 	scctx->isc_tx_tso_segments_max = 31;
404 	scctx->isc_tx_tso_size_max =
405 	    HW_ATL_B0_TSO_SIZE - sizeof(struct ether_vlan_header);
406 	scctx->isc_tx_tso_segsize_max = HW_ATL_B0_MTU_JUMBO;
407 	scctx->isc_min_frame_size = 52;
408 	scctx->isc_txrx = &aq_txrx;
409 
410 	scctx->isc_txqsizes[0] = sizeof(aq_tx_desc_t) * scctx->isc_ntxd[0];
411 	scctx->isc_rxqsizes[0] = sizeof(aq_rx_desc_t) * scctx->isc_nrxd[0];
412 
413 	scctx->isc_ntxqsets_max = HW_ATL_B0_RINGS_MAX;
414 	scctx->isc_nrxqsets_max = HW_ATL_B0_RINGS_MAX;
415 
416 	/* iflib will map and release this bar */
417 	scctx->isc_msix_bar = pci_msix_table_bar(softc->dev);
418 
419 	softc->vlan_tags  = bit_alloc(4096, M_AQ, M_NOWAIT);
420 
421 	AQ_DBG_EXIT(rc);
422 	return (rc);
423 
424 fail:
425 	if (softc->mmio_res != NULL)
426 		bus_release_resource(softc->dev, SYS_RES_MEMORY,
427 		    softc->mmio_rid, softc->mmio_res);
428 
429 	AQ_DBG_EXIT(rc);
430 	return (ENXIO);
431 }
432 
433 
434 static int
435 aq_if_attach_post(if_ctx_t ctx)
436 {
437 	struct aq_dev *softc;
438 	int rc;
439 
440 	AQ_DBG_ENTER();
441 
442 	softc = iflib_get_softc(ctx);
443 	rc = 0;
444 
445 	aq_update_hw_stats(softc);
446 
447 	aq_initmedia(softc);
448 
449 
450 	switch (softc->scctx->isc_intr) {
451 	case IFLIB_INTR_LEGACY:
452 		rc = EOPNOTSUPP;
453 		goto exit;
454 	goto exit;
455 		break;
456 	case IFLIB_INTR_MSI:
457 		break;
458 	case IFLIB_INTR_MSIX:
459 		break;
460 	default:
461 		device_printf(softc->dev, "unknown interrupt mode\n");
462 		rc = EOPNOTSUPP;
463 		goto exit;
464 	}
465 
466 	aq_add_stats_sysctls(softc);
467 	/* RSS */
468 	arc4rand(softc->rss_key, HW_ATL_RSS_HASHKEY_SIZE, 0);
469 	for (int i = ARRAY_SIZE(softc->rss_table); i--;){
470 		softc->rss_table[i] = i & (softc->rx_rings_count - 1);
471 	}
472 exit:
473 	AQ_DBG_EXIT(rc);
474 	return (rc);
475 }
476 
477 
478 static int
479 aq_if_detach(if_ctx_t ctx)
480 {
481 	struct aq_dev *softc;
482 	int i;
483 
484 	AQ_DBG_ENTER();
485 	softc = iflib_get_softc(ctx);
486 
487 	aq_hw_deinit(&softc->hw);
488 
489 	for (i = 0; i < softc->scctx->isc_nrxqsets; i++)
490 		iflib_irq_free(ctx, &softc->rx_rings[i]->irq);
491 	iflib_irq_free(ctx, &softc->irq);
492 
493 
494 	if (softc->mmio_res != NULL)
495 		bus_release_resource(softc->dev, SYS_RES_MEMORY,
496 		    softc->mmio_rid, softc->mmio_res);
497 
498 	free(softc->vlan_tags, M_AQ);
499 
500 	AQ_DBG_EXIT(0);
501 	return (0);
502 }
503 
504 static int
505 aq_if_shutdown(if_ctx_t ctx)
506 {
507 
508 	AQ_DBG_ENTER();
509 
510 	AQ_XXX_UNIMPLEMENTED_FUNCTION;
511 
512 	AQ_DBG_EXIT(0);
513 	return (0);
514 }
515 
516 static int
517 aq_if_suspend(if_ctx_t ctx)
518 {
519 	AQ_DBG_ENTER();
520 
521 	AQ_XXX_UNIMPLEMENTED_FUNCTION;
522 
523 	AQ_DBG_EXIT(0);
524 	return (0);
525 }
526 
527 static int
528 aq_if_resume(if_ctx_t ctx)
529 {
530 	AQ_DBG_ENTER();
531 
532 	AQ_XXX_UNIMPLEMENTED_FUNCTION;
533 
534 	AQ_DBG_EXIT(0);
535 	return (0);
536 }
537 
538 /* Soft queue setup and teardown */
539 static int
540 aq_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs,
541     int ntxqs, int ntxqsets)
542 {
543 	struct aq_dev *softc;
544 	struct aq_ring *ring;
545 	int rc = 0, i;
546 
547 	AQ_DBG_ENTERA("ntxqs=%d, ntxqsets=%d", ntxqs, ntxqsets);
548 	softc = iflib_get_softc(ctx);
549 	AQ_DBG_PRINT("tx descriptors  number %d", softc->scctx->isc_ntxd[0]);
550 
551 	for (i = 0; i < ntxqsets; i++) {
552 		ring = softc->tx_rings[i] = malloc(sizeof(struct aq_ring),
553 						   M_AQ, M_NOWAIT | M_ZERO);
554 		if (!ring){
555 			rc = ENOMEM;
556 			device_printf(softc->dev, "atlantic: tx_ring malloc fail\n");
557 			goto fail;
558 		}
559 		ring->tx_descs = (aq_tx_desc_t*)vaddrs[i];
560 		ring->tx_size = softc->scctx->isc_ntxd[0];
561 		ring->tx_descs_phys = paddrs[i];
562 		ring->tx_head = ring->tx_tail = 0;
563 		ring->index = i;
564 		ring->dev = softc;
565 
566 		softc->tx_rings_count++;
567 	}
568 
569 	AQ_DBG_EXIT(rc);
570 	return (rc);
571 
572 fail:
573 	aq_if_queues_free(ctx);
574 	AQ_DBG_EXIT(rc);
575 	return (rc);
576 }
577 
578 static int
579 aq_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs,
580     int nrxqs, int nrxqsets)
581 {
582 	struct aq_dev *softc;
583 	struct aq_ring *ring;
584 	int rc = 0, i;
585 
586 	AQ_DBG_ENTERA("nrxqs=%d, nrxqsets=%d", nrxqs, nrxqsets);
587 	softc = iflib_get_softc(ctx);
588 
589 	for (i = 0; i < nrxqsets; i++) {
590 		ring = softc->rx_rings[i] = malloc(sizeof(struct aq_ring),
591 						   M_AQ, M_NOWAIT | M_ZERO);
592 		if (!ring){
593 			rc = ENOMEM;
594 			device_printf(softc->dev,
595 			    "atlantic: rx_ring malloc fail\n");
596 			goto fail;
597 		}
598 
599 		ring->rx_descs = (aq_rx_desc_t*)vaddrs[i];
600 		ring->rx_descs_phys = paddrs[i];
601 		ring->rx_size = softc->scctx->isc_nrxd[0];
602 		ring->index = i;
603 		ring->dev = softc;
604 
605 		switch (MCLBYTES) {
606 			case    (4 * 1024):
607 			case    (8 * 1024):
608 			case    (16 * 1024):
609 				ring->rx_max_frame_size = MCLBYTES;
610 				break;
611 			default:
612 				ring->rx_max_frame_size = 2048;
613 				break;
614 		}
615 
616 		softc->rx_rings_count++;
617 	}
618 
619 	AQ_DBG_EXIT(rc);
620 	return (rc);
621 
622 fail:
623 	aq_if_queues_free(ctx);
624 	AQ_DBG_EXIT(rc);
625 	return (rc);
626 }
627 
628 static void
629 aq_if_queues_free(if_ctx_t ctx)
630 {
631 	struct aq_dev *softc;
632 	int i;
633 
634 	AQ_DBG_ENTER();
635 	softc = iflib_get_softc(ctx);
636 
637 	for (i = 0; i < softc->tx_rings_count; i++) {
638 		if (softc->tx_rings[i]) {
639 			free(softc->tx_rings[i], M_AQ);
640 			softc->tx_rings[i] = NULL;
641 		}
642 	}
643 	softc->tx_rings_count = 0;
644 	for (i = 0; i < softc->rx_rings_count; i++) {
645 		if (softc->rx_rings[i]){
646 			free(softc->rx_rings[i], M_AQ);
647 			softc->rx_rings[i] = NULL;
648 		}
649 	}
650 	softc->rx_rings_count = 0;
651 
652 	AQ_DBG_EXIT(0);
653 	return;
654 }
655 
656 /* Device configuration */
657 static void
658 aq_if_init(if_ctx_t ctx)
659 {
660 	struct aq_dev *softc;
661 	struct aq_hw *hw;
662 	struct ifmediareq ifmr;
663 	int i, err;
664 
665 	AQ_DBG_ENTER();
666 	softc = iflib_get_softc(ctx);
667 	hw = &softc->hw;
668 
669 	err = aq_hw_init(&softc->hw, softc->hw.mac_addr, softc->msix,
670 	    softc->scctx->isc_intr == IFLIB_INTR_MSIX);
671 	if (err != EOK) {
672 		device_printf(softc->dev, "atlantic: aq_hw_init: %d", err);
673 	}
674 
675 	aq_if_media_status(ctx, &ifmr);
676 
677 	aq_update_vlan_filters(softc);
678 
679 	for (i = 0; i < softc->tx_rings_count; i++) {
680 		struct aq_ring *ring = softc->tx_rings[i];
681 		err = aq_ring_tx_init(&softc->hw, ring);
682 		if (err) {
683 			device_printf(softc->dev,
684 			    "atlantic: aq_ring_tx_init: %d", err);
685 		}
686 		err = aq_ring_tx_start(hw, ring);
687 		if (err != EOK) {
688 			device_printf(softc->dev,
689 			    "atlantic: aq_ring_tx_start: %d", err);
690 		}
691 	}
692 	for (i = 0; i < softc->rx_rings_count; i++) {
693 		struct aq_ring *ring = softc->rx_rings[i];
694 		err = aq_ring_rx_init(&softc->hw, ring);
695 		if (err) {
696 			device_printf(softc->dev,
697 			    "atlantic: aq_ring_rx_init: %d", err);
698 		}
699 		err = aq_ring_rx_start(hw, ring);
700 		if (err != EOK) {
701 			device_printf(softc->dev,
702 			    "atlantic: aq_ring_rx_start: %d", err);
703 		}
704 		aq_if_rx_queue_intr_enable(ctx, i);
705 	}
706 
707 	aq_hw_start(hw);
708 	aq_if_enable_intr(ctx);
709 	aq_hw_rss_hash_set(&softc->hw, softc->rss_key);
710 	aq_hw_rss_set(&softc->hw, softc->rss_table);
711 	aq_hw_udp_rss_enable(hw, aq_enable_rss_udp);
712 	aq_hw_set_link_speed(hw, hw->link_rate);
713 
714 	AQ_DBG_EXIT(0);
715 }
716 
717 
718 static void
719 aq_if_stop(if_ctx_t ctx)
720 {
721 	struct aq_dev *softc;
722 	struct aq_hw *hw;
723 	int i;
724 
725 	AQ_DBG_ENTER();
726 
727 	softc = iflib_get_softc(ctx);
728 	hw = &softc->hw;
729 
730 	/* disable interrupt */
731 	aq_if_disable_intr(ctx);
732 
733 	for (i = 0; i < softc->tx_rings_count; i++) {
734 		aq_ring_tx_stop(hw, softc->tx_rings[i]);
735 		softc->tx_rings[i]->tx_head = 0;
736 		softc->tx_rings[i]->tx_tail = 0;
737 	}
738 	for (i = 0; i < softc->rx_rings_count; i++) {
739 		aq_ring_rx_stop(hw, softc->rx_rings[i]);
740 	}
741 
742 	aq_hw_reset(&softc->hw);
743 	memset(&softc->last_stats, 0, sizeof(softc->last_stats));
744 	softc->linkup = false;
745 	aq_if_update_admin_status(ctx);
746 	AQ_DBG_EXIT(0);
747 }
748 
749 static uint64_t
750 aq_if_get_counter(if_ctx_t ctx, ift_counter cnt)
751 {
752 	struct aq_dev *softc = iflib_get_softc(ctx);
753 	if_t ifp = iflib_get_ifp(ctx);
754 
755 	switch (cnt) {
756 	case IFCOUNTER_IERRORS:
757 		return (softc->curr_stats.erpr);
758 	case IFCOUNTER_IQDROPS:
759 		return (softc->curr_stats.dpc);
760 	case IFCOUNTER_OERRORS:
761 		return (softc->curr_stats.erpt);
762 	default:
763 		return (if_get_counter_default(ifp, cnt));
764 	}
765 }
766 
767 #if __FreeBSD_version >= 1300054
768 static u_int
769 aq_mc_filter_apply(void *arg, struct sockaddr_dl *dl, u_int count)
770 {
771 	struct aq_dev *softc = arg;
772 	struct aq_hw *hw = &softc->hw;
773 	uint8_t *mac_addr = NULL;
774 
775 	if (count == AQ_HW_MAC_MAX)
776 		return (0);
777 
778 	mac_addr = LLADDR(dl);
779 	aq_hw_mac_addr_set(hw, mac_addr, count + 1);
780 
781 	aq_log_detail("set %d mc address %6D", count + 1, mac_addr, ":");
782 	return (1);
783 }
784 #else
785 static int
786 aq_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int count)
787 {
788 	struct aq_dev *softc = arg;
789 	struct aq_hw *hw = &softc->hw;
790 	uint8_t *mac_addr = NULL;
791 
792 	if (ifma->ifma_addr->sa_family != AF_LINK)
793 		return (0);
794 	if (count == AQ_HW_MAC_MAX)
795 		return (0);
796 
797 	mac_addr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
798 	aq_hw_mac_addr_set(hw, mac_addr, count + 1);
799 
800 	aq_log_detail("set %d mc address %6D", count + 1, mac_addr, ":");
801 	return (1);
802 }
803 #endif
804 
805 static bool
806 aq_is_mc_promisc_required(struct aq_dev *softc)
807 {
808 	return (softc->mcnt >= AQ_HW_MAC_MAX);
809 }
810 
811 static void
812 aq_if_multi_set(if_ctx_t ctx)
813 {
814 	struct aq_dev *softc = iflib_get_softc(ctx);
815 	if_t ifp = iflib_get_ifp(ctx);
816 	struct aq_hw  *hw = &softc->hw;
817 	AQ_DBG_ENTER();
818 #if __FreeBSD_version >= 1300054
819 	softc->mcnt = if_llmaddr_count(iflib_get_ifp(ctx));
820 #else
821 	softc->mcnt = if_multiaddr_count(iflib_get_ifp(ctx), AQ_HW_MAC_MAX);
822 #endif
823 	if (softc->mcnt >= AQ_HW_MAC_MAX) {
824 		aq_hw_set_promisc(hw, !!(if_getflags(ifp) & IFF_PROMISC),
825 		    aq_is_vlan_promisc_required(softc),
826 		    !!(if_getflags(ifp) & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc));
827 	} else {
828 #if __FreeBSD_version >= 1300054
829 		if_foreach_llmaddr(iflib_get_ifp(ctx), &aq_mc_filter_apply, softc);
830 #else
831 		if_multi_apply(iflib_get_ifp(ctx), aq_mc_filter_apply, softc);
832 #endif
833 	}
834 	AQ_DBG_EXIT(0);
835 }
836 
837 static int
838 aq_if_mtu_set(if_ctx_t ctx, uint32_t mtu)
839 {
840 	int err = 0;
841 	AQ_DBG_ENTER();
842 
843 	AQ_DBG_EXIT(err);
844 	return (err);
845 }
846 
847 static void
848 aq_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr)
849 {
850 	if_t ifp;
851 
852 	AQ_DBG_ENTER();
853 
854 	ifp = iflib_get_ifp(ctx);
855 
856 	aq_mediastatus(ifp, ifmr);
857 
858 	AQ_DBG_EXIT(0);
859 }
860 
861 static int
862 aq_if_media_change(if_ctx_t ctx)
863 {
864 	struct aq_dev *softc = iflib_get_softc(ctx);
865 	if_t ifp = iflib_get_ifp(ctx);
866 	int rc = 0;
867 
868 	AQ_DBG_ENTER();
869 
870 	/* Not allowd in UP state, since causes unsync of rings */
871 	if ((if_getflags(ifp) & IFF_UP)){
872 		rc = EPERM;
873 		goto exit;
874 	}
875 
876 	ifp = iflib_get_ifp(softc->ctx);
877 
878 	rc = aq_mediachange(ifp);
879 
880 exit:
881 	AQ_DBG_EXIT(rc);
882 	return (rc);
883 }
884 
885 static int
886 aq_if_promisc_set(if_ctx_t ctx, int flags)
887 {
888 	struct aq_dev *softc;
889 
890 	AQ_DBG_ENTER();
891 
892 	softc = iflib_get_softc(ctx);
893 
894 	aq_hw_set_promisc(&softc->hw, !!(flags & IFF_PROMISC),
895 	    aq_is_vlan_promisc_required(softc),
896 	    !!(flags & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc));
897 
898 	AQ_DBG_EXIT(0);
899 	return (0);
900 }
901 
902 static void
903 aq_if_timer(if_ctx_t ctx, uint16_t qid)
904 {
905 	struct aq_dev *softc;
906 	uint64_t ticks_now;
907 
908 //	AQ_DBG_ENTER();
909 
910 	softc = iflib_get_softc(ctx);
911 	ticks_now = ticks;
912 
913 	/* Schedule aqc_if_update_admin_status() once per sec */
914 	if (ticks_now - softc->admin_ticks >= hz) {
915 		softc->admin_ticks = ticks_now;
916 		iflib_admin_intr_deferred(ctx);
917 	}
918 
919 //	AQ_DBG_EXIT(0);
920 	return;
921 
922 }
923 
924 /* Interrupt enable / disable */
925 static void
926 aq_if_enable_intr(if_ctx_t ctx)
927 {
928 	struct aq_dev *softc = iflib_get_softc(ctx);
929 	struct aq_hw  *hw = &softc->hw;
930 
931 	AQ_DBG_ENTER();
932 
933 	/* Enable interrupts */
934 	itr_irq_msk_setlsw_set(hw, BIT(softc->msix + 1) - 1);
935 
936 	AQ_DBG_EXIT(0);
937 }
938 
939 static void
940 aq_if_disable_intr(if_ctx_t ctx)
941 {
942 	struct aq_dev *softc = iflib_get_softc(ctx);
943 	struct aq_hw  *hw = &softc->hw;
944 
945 	AQ_DBG_ENTER();
946 
947 	/* Disable interrupts */
948 	itr_irq_msk_clearlsw_set(hw, BIT(softc->msix + 1) - 1);
949 
950 	AQ_DBG_EXIT(0);
951 }
952 
953 static int
954 aq_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid)
955 {
956 	struct aq_dev *softc = iflib_get_softc(ctx);
957 	struct aq_hw  *hw = &softc->hw;
958 
959 	AQ_DBG_ENTER();
960 
961 	itr_irq_msk_setlsw_set(hw, BIT(softc->rx_rings[rxqid]->msix));
962 
963 	AQ_DBG_EXIT(0);
964 	return (0);
965 }
966 
967 static int
968 aq_if_msix_intr_assign(if_ctx_t ctx, int msix)
969 {
970 	struct aq_dev *softc;
971 	int i, vector = 0, rc;
972 	char irq_name[16];
973 	int rx_vectors;
974 
975 	AQ_DBG_ENTER();
976 	softc = iflib_get_softc(ctx);
977 
978 	for (i = 0; i < softc->rx_rings_count; i++, vector++) {
979 		snprintf(irq_name, sizeof(irq_name), "rxq%d", i);
980 		rc = iflib_irq_alloc_generic(ctx, &softc->rx_rings[i]->irq,
981 		    vector + 1, IFLIB_INTR_RX, aq_isr_rx, softc->rx_rings[i],
982 			softc->rx_rings[i]->index, irq_name);
983 		device_printf(softc->dev, "Assign IRQ %u to rx ring %u\n",
984 					  vector, softc->rx_rings[i]->index);
985 
986 		if (rc) {
987 			device_printf(softc->dev, "failed to set up RX handler\n");
988 			i--;
989 			goto fail;
990 		}
991 
992 		softc->rx_rings[i]->msix = vector;
993 	}
994 
995 	rx_vectors = vector;
996 
997 	for (i = 0; i < softc->tx_rings_count; i++, vector++) {
998 		snprintf(irq_name, sizeof(irq_name), "txq%d", i);
999 		iflib_softirq_alloc_generic(ctx, &softc->rx_rings[i]->irq,
1000 		    IFLIB_INTR_TX, softc->tx_rings[i], i, irq_name);
1001 
1002 		softc->tx_rings[i]->msix = (vector % softc->rx_rings_count);
1003 		device_printf(softc->dev, "Assign IRQ %u to tx ring %u\n",
1004 		    softc->tx_rings[i]->msix, softc->tx_rings[i]->index);
1005 	}
1006 
1007 	rc = iflib_irq_alloc_generic(ctx, &softc->irq, rx_vectors + 1,
1008 	    IFLIB_INTR_ADMIN, aq_linkstat_isr, softc, 0, "aq");
1009 	softc->msix = rx_vectors;
1010 	device_printf(softc->dev, "Assign IRQ %u to admin proc \n",
1011 	    rx_vectors);
1012 	if (rc) {
1013 		device_printf(iflib_get_dev(ctx),
1014 		    "Failed to register admin handler");
1015 		i = softc->rx_rings_count;
1016 		goto fail;
1017 	}
1018 	AQ_DBG_EXIT(0);
1019 	return (0);
1020 
1021 fail:
1022 	for (; i >= 0; i--)
1023 		iflib_irq_free(ctx, &softc->rx_rings[i]->irq);
1024 	AQ_DBG_EXIT(rc);
1025 	return (rc);
1026 }
1027 
1028 static bool
1029 aq_is_vlan_promisc_required(struct aq_dev *softc)
1030 {
1031 	int vlan_tag_count;
1032 
1033 	bit_count(softc->vlan_tags, 0, 4096, &vlan_tag_count);
1034 
1035 	if (vlan_tag_count <= AQ_HW_VLAN_MAX_FILTERS)
1036 		return (false);
1037 	else
1038 		return (true);
1039 
1040 }
1041 
1042 static void
1043 aq_update_vlan_filters(struct aq_dev *softc)
1044 {
1045 	struct aq_rx_filter_vlan aq_vlans[AQ_HW_VLAN_MAX_FILTERS];
1046 	struct aq_hw  *hw = &softc->hw;
1047 	int bit_pos = 0;
1048 	int vlan_tag = -1;
1049 	int i;
1050 
1051 	hw_atl_b0_hw_vlan_promisc_set(hw, true);
1052 	for (i = 0; i < AQ_HW_VLAN_MAX_FILTERS; i++) {
1053 		bit_ffs_at(softc->vlan_tags, bit_pos, 4096, &vlan_tag);
1054 		if (vlan_tag != -1) {
1055 			aq_vlans[i].enable = true;
1056 			aq_vlans[i].location = i;
1057 			aq_vlans[i].queue = 0xFF;
1058 			aq_vlans[i].vlan_id = vlan_tag;
1059 			bit_pos = vlan_tag;
1060 		} else {
1061 			aq_vlans[i].enable = false;
1062 		}
1063 	}
1064 
1065 	hw_atl_b0_hw_vlan_set(hw, aq_vlans);
1066 	hw_atl_b0_hw_vlan_promisc_set(hw, aq_is_vlan_promisc_required(softc));
1067 }
1068 
1069 /* VLAN support */
1070 static void
1071 aq_if_vlan_register(if_ctx_t ctx, uint16_t vtag)
1072 {
1073 	struct aq_dev *softc = iflib_get_softc(ctx);
1074 
1075 	AQ_DBG_ENTERA("%d", vtag);
1076 
1077 	bit_set(softc->vlan_tags, vtag);
1078 
1079 	aq_update_vlan_filters(softc);
1080 
1081 	AQ_DBG_EXIT(0);
1082 }
1083 
1084 static void
1085 aq_if_vlan_unregister(if_ctx_t ctx, uint16_t vtag)
1086 {
1087 	struct aq_dev *softc = iflib_get_softc(ctx);
1088 
1089 	AQ_DBG_ENTERA("%d", vtag);
1090 
1091 	bit_clear(softc->vlan_tags, vtag);
1092 
1093 	aq_update_vlan_filters(softc);
1094 
1095 	AQ_DBG_EXIT(0);
1096 }
1097 
1098 static void
1099 aq_if_led_func(if_ctx_t ctx, int onoff)
1100 {
1101 	struct aq_dev *softc = iflib_get_softc(ctx);
1102 	struct aq_hw  *hw = &softc->hw;
1103 
1104 	AQ_DBG_ENTERA("%d", onoff);
1105 	if (hw->fw_ops && hw->fw_ops->led_control)
1106 		hw->fw_ops->led_control(hw, onoff);
1107 
1108 	AQ_DBG_EXIT(0);
1109 }
1110 
1111 static int
1112 aq_hw_capabilities(struct aq_dev *softc)
1113 {
1114 
1115 	if (pci_get_vendor(softc->dev) != AQUANTIA_VENDOR_ID)
1116 		return (ENXIO);
1117 
1118 	switch (pci_get_device(softc->dev)) {
1119 	case AQ_DEVICE_ID_D100:
1120 	case AQ_DEVICE_ID_AQC100:
1121 	case AQ_DEVICE_ID_AQC100S:
1122 		softc->media_type = AQ_MEDIA_TYPE_FIBRE;
1123 		softc->link_speeds = AQ_LINK_ALL & ~AQ_LINK_10G;
1124 		break;
1125 
1126 	case AQ_DEVICE_ID_0001:
1127 	case AQ_DEVICE_ID_D107:
1128 	case AQ_DEVICE_ID_AQC107:
1129 	case AQ_DEVICE_ID_AQC107S:
1130 		softc->media_type = AQ_MEDIA_TYPE_TP;
1131 		softc->link_speeds = AQ_LINK_ALL;
1132 		break;
1133 
1134 	case AQ_DEVICE_ID_D108:
1135 	case AQ_DEVICE_ID_AQC108:
1136 	case AQ_DEVICE_ID_AQC108S:
1137 	case AQ_DEVICE_ID_AQC111:
1138 	case AQ_DEVICE_ID_AQC111S:
1139 		softc->media_type = AQ_MEDIA_TYPE_TP;
1140 		softc->link_speeds = AQ_LINK_ALL & ~AQ_LINK_10G;
1141 		break;
1142 
1143 	case AQ_DEVICE_ID_D109:
1144 	case AQ_DEVICE_ID_AQC109:
1145 	case AQ_DEVICE_ID_AQC109S:
1146 	case AQ_DEVICE_ID_AQC112:
1147 	case AQ_DEVICE_ID_AQC112S:
1148 		softc->media_type = AQ_MEDIA_TYPE_TP;
1149 		softc->link_speeds = AQ_LINK_ALL & ~(AQ_LINK_10G | AQ_LINK_5G);
1150 		break;
1151 
1152 	default:
1153 		return (ENXIO);
1154 	}
1155 
1156 	return (0);
1157 }
1158 
1159 static int
1160 aq_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS)
1161 {
1162 	struct aq_dev  *softc = (struct aq_dev *)arg1;
1163 	device_t        dev = softc->dev;
1164 	struct sbuf     *buf;
1165 	int             error = 0;
1166 
1167 	buf = sbuf_new_for_sysctl(NULL, NULL, 256, req);
1168 	if (!buf) {
1169 		device_printf(dev, "Could not allocate sbuf for output.\n");
1170 		return (ENOMEM);
1171 	}
1172 
1173 	/* Print out the redirection table */
1174 	sbuf_cat(buf, "\nRSS Indirection table:\n");
1175 	for (int i = 0; i < HW_ATL_RSS_INDIRECTION_TABLE_MAX; i++) {
1176 		sbuf_printf(buf, "%d ", softc->rss_table[i]);
1177 		if ((i+1) % 10 == 0)
1178 			sbuf_printf(buf, "\n");
1179 	}
1180 
1181 	sbuf_cat(buf, "\nRSS Key:\n");
1182 	for (int i = 0; i < HW_ATL_RSS_HASHKEY_SIZE; i++) {
1183 		sbuf_printf(buf, "0x%02x ", softc->rss_key[i]);
1184 	}
1185 	sbuf_printf(buf, "\n");
1186 
1187 	error = sbuf_finish(buf);
1188 	if (error)
1189 		device_printf(dev, "Error finishing sbuf: %d\n", error);
1190 
1191 	sbuf_delete(buf);
1192 
1193 	return (0);
1194 }
1195 
1196 static int
1197 aq_sysctl_print_tx_head(SYSCTL_HANDLER_ARGS)
1198 {
1199 	struct aq_ring  *ring = arg1;
1200 	int             error = 0;
1201 	unsigned int   val;
1202 
1203 	if (!ring)
1204 		return (0);
1205 
1206 	val = tdm_tx_desc_head_ptr_get(&ring->dev->hw, ring->index);
1207 
1208 	error = sysctl_handle_int(oidp, &val, 0, req);
1209 	if (error || !req->newptr)
1210 		return (error);
1211 
1212 	return (0);
1213 }
1214 
1215 static int
1216 aq_sysctl_print_tx_tail(SYSCTL_HANDLER_ARGS)
1217 {
1218 	struct aq_ring  *ring = arg1;
1219 	int             error = 0;
1220 	unsigned int   val;
1221 
1222 	if (!ring)
1223 		return (0);
1224 
1225 	val = reg_tx_dma_desc_tail_ptr_get(&ring->dev->hw, ring->index);
1226 
1227 	error = sysctl_handle_int(oidp, &val, 0, req);
1228 	if (error || !req->newptr)
1229 		return (error);
1230 
1231 	return (0);
1232 }
1233 
1234 static int
1235 aq_sysctl_print_rx_head(SYSCTL_HANDLER_ARGS)
1236 {
1237 	struct aq_ring  *ring = arg1;
1238 	int             error = 0;
1239 	unsigned int   val;
1240 
1241 	if (!ring)
1242 		return (0);
1243 
1244 	val = rdm_rx_desc_head_ptr_get(&ring->dev->hw, ring->index);
1245 
1246 	error = sysctl_handle_int(oidp, &val, 0, req);
1247 	if (error || !req->newptr)
1248 		return (error);
1249 
1250 	return (0);
1251 }
1252 
1253 static int
1254 aq_sysctl_print_rx_tail(SYSCTL_HANDLER_ARGS)
1255 {
1256 	struct aq_ring  *ring = arg1;
1257 	int             error = 0;
1258 	unsigned int   val;
1259 
1260 	if (!ring)
1261 		return (0);
1262 
1263 	val = reg_rx_dma_desc_tail_ptr_get(&ring->dev->hw, ring->index);
1264 
1265 	error = sysctl_handle_int(oidp, &val, 0, req);
1266 	if (error || !req->newptr)
1267 		return (error);
1268 
1269 	return (0);
1270 }
1271 
1272 static void
1273 aq_add_stats_sysctls(struct aq_dev *softc)
1274 {
1275 	device_t                dev = softc->dev;
1276 	struct sysctl_ctx_list  *ctx = device_get_sysctl_ctx(dev);
1277 	struct sysctl_oid       *tree = device_get_sysctl_tree(dev);
1278 	struct sysctl_oid_list  *child = SYSCTL_CHILDREN(tree);
1279 	struct aq_stats_s *stats = &softc->curr_stats;
1280 	struct sysctl_oid       *stat_node, *queue_node;
1281 	struct sysctl_oid_list  *stat_list, *queue_list;
1282 
1283 #define QUEUE_NAME_LEN 32
1284 	char                    namebuf[QUEUE_NAME_LEN];
1285 	/* RSS configuration */
1286 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "print_rss_config",
1287 	    CTLTYPE_STRING | CTLFLAG_RD, softc, 0,
1288 	    aq_sysctl_print_rss_config, "A", "Prints RSS Configuration");
1289 
1290 	/* Driver Statistics */
1291 	for (int i = 0; i < softc->tx_rings_count; i++) {
1292 		struct aq_ring *ring = softc->tx_rings[i];
1293 		snprintf(namebuf, QUEUE_NAME_LEN, "tx_queue%d", i);
1294 		queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
1295 		    CTLFLAG_RD, NULL, "Queue Name");
1296 		queue_list = SYSCTL_CHILDREN(queue_node);
1297 
1298 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_pkts",
1299 		    CTLFLAG_RD, &(ring->stats.tx_pkts), "TX Packets");
1300 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_bytes",
1301 		    CTLFLAG_RD, &(ring->stats.tx_bytes), "TX Octets");
1302 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_drops",
1303 		    CTLFLAG_RD, &(ring->stats.tx_drops), "TX Drops");
1304 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_queue_full",
1305 		    CTLFLAG_RD, &(ring->stats.tx_queue_full), "TX Queue Full");
1306 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "tx_head",
1307 		    CTLTYPE_UINT | CTLFLAG_RD, ring, 0,
1308 		    aq_sysctl_print_tx_head, "IU", "ring head pointer");
1309 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "tx_tail",
1310 		    CTLTYPE_UINT | CTLFLAG_RD, ring, 0,
1311 		aq_sysctl_print_tx_tail, "IU", "ring tail pointer");
1312 	}
1313 
1314 	for (int i = 0; i < softc->rx_rings_count; i++) {
1315 		struct aq_ring *ring = softc->rx_rings[i];
1316 		snprintf(namebuf, QUEUE_NAME_LEN, "rx_queue%d", i);
1317 		queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
1318 		    CTLFLAG_RD, NULL, "Queue Name");
1319 		queue_list = SYSCTL_CHILDREN(queue_node);
1320 
1321 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_pkts",
1322 		    CTLFLAG_RD, &(ring->stats.rx_pkts), "RX Packets");
1323 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes",
1324 		    CTLFLAG_RD, &(ring->stats.rx_bytes), "TX Octets");
1325 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "jumbo_pkts",
1326 		    CTLFLAG_RD, &(ring->stats.jumbo_pkts), "Jumbo Packets");
1327 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_err",
1328 		    CTLFLAG_RD, &(ring->stats.rx_err), "RX Errors");
1329 		SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irq",
1330 		    CTLFLAG_RD, &(ring->stats.irq), "RX interrupts");
1331 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rx_head",
1332 		    CTLTYPE_UINT | CTLFLAG_RD, ring, 0,
1333 		aq_sysctl_print_rx_head, "IU", "ring head pointer");
1334 		SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rx_tail",
1335 		    CTLTYPE_UINT | CTLFLAG_RD, ring, 0,
1336 		aq_sysctl_print_rx_tail, "IU", " ring tail pointer");
1337 	}
1338 
1339 	stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac",
1340 	    CTLFLAG_RD, NULL, "Statistics (read from HW registers)");
1341 	stat_list = SYSCTL_CHILDREN(stat_node);
1342 
1343 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd",
1344 	    CTLFLAG_RD, &stats->prc, "Good Packets Received");
1345 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_pkts_rcvd",
1346 	    CTLFLAG_RD, &stats->uprc, "Unicast Packets Received");
1347 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd",
1348 	    CTLFLAG_RD, &stats->mprc, "Multicast Packets Received");
1349 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_rcvd",
1350 	    CTLFLAG_RD, &stats->bprc, "Broadcast Packets Received");
1351 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rsc_pkts_rcvd",
1352 	    CTLFLAG_RD, &stats->cprc, "Coalesced Packets Received");
1353 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "err_pkts_rcvd",
1354 	    CTLFLAG_RD, &stats->erpr, "Errors of Packet Receive");
1355 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "drop_pkts_dma",
1356 	    CTLFLAG_RD, &stats->dpc, "Dropped Packets in DMA");
1357 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd",
1358 	    CTLFLAG_RD, &stats->brc, "Good Octets Received");
1359 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_octets_rcvd",
1360 	    CTLFLAG_RD, &stats->ubrc, "Unicast Octets Received");
1361 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_octets_rcvd",
1362 	    CTLFLAG_RD, &stats->mbrc, "Multicast Octets Received");
1363 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_octets_rcvd",
1364 	    CTLFLAG_RD, &stats->bbrc, "Broadcast Octets Received");
1365 
1366 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
1367 	    CTLFLAG_RD, &stats->ptc, "Good Packets Transmitted");
1368 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_pkts_txd",
1369 	    CTLFLAG_RD, &stats->uptc, "Unicast Packets Transmitted");
1370 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
1371 	    CTLFLAG_RD, &stats->mptc, "Multicast Packets Transmitted");
1372 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
1373 	    CTLFLAG_RD, &stats->bptc, "Broadcast Packets Transmitted");
1374 
1375 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "err_pkts_txd",
1376 	    CTLFLAG_RD, &stats->erpt, "Errors of Packet Transmit");
1377 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd",
1378 	    CTLFLAG_RD, &stats->btc, "Good Octets Transmitted");
1379 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_octets_txd",
1380 	    CTLFLAG_RD, &stats->ubtc, "Unicast Octets Transmitted");
1381 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_octets_txd",
1382 	    CTLFLAG_RD, &stats->mbtc, "Multicast Octets Transmitted");
1383 	SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_octets_txd",
1384 	    CTLFLAG_RD, &stats->bbtc, "Broadcast Octets Transmitted");
1385 }
1386