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