Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/aq/aq_main.c
96295 views
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 *
318
aq_register(device_t dev)
319
{
320
return (&aq_sctx_init);
321
}
322
323
static int
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
1387