Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/axgbe/xgbe-sysctl.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2020 Advanced Micro Devices, Inc.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*
27
* Contact Information :
28
* Rajesh Kumar <[email protected]>
29
* Arpan Palit <[email protected]>
30
*/
31
32
#include <sys/param.h>
33
#include <sys/sysctl.h>
34
#include <sys/sbuf.h>
35
36
#include "xgbe.h"
37
#include "xgbe-common.h"
38
39
#define SYSCTL_BUF_LEN 64
40
41
typedef enum{
42
/* Coalesce flag */
43
rx_coalesce_usecs = 1,
44
rx_max_coalesced_frames,
45
rx_coalesce_usecs_irq,
46
rx_max_coalesced_frames_irq,
47
tx_coalesce_usecs,
48
tx_max_coalesced_frames,
49
tx_coalesce_usecs_irq,
50
tx_max_coalesced_frames_irq,
51
stats_block_coalesce_usecs,
52
use_adaptive_rx_coalesce,
53
use_adaptive_tx_coalesce,
54
pkt_rate_low,
55
rx_coalesce_usecs_low,
56
rx_max_coalesced_frames_low,
57
tx_coalesce_usecs_low,
58
tx_max_coalesced_frames_low,
59
pkt_rate_high,
60
rx_coalesce_usecs_high,
61
rx_max_coalesced_frames_high,
62
tx_coalesce_usecs_high,
63
tx_max_coalesced_frames_high,
64
rate_sample_interval,
65
66
/* Pasue flag */
67
autoneg,
68
tx_pause,
69
rx_pause,
70
71
/* link settings */
72
speed,
73
duplex,
74
75
/* Ring settings */
76
rx_pending,
77
rx_mini_pending,
78
rx_jumbo_pending,
79
tx_pending,
80
81
/* Channels settings */
82
rx_count,
83
tx_count,
84
other_count,
85
combined_count,
86
} sysctl_variable_t;
87
88
typedef enum {
89
SYSL_NONE,
90
SYSL_BOOL,
91
SYSL_S32,
92
SYSL_U8,
93
SYSL_U16,
94
SYSL_U32,
95
SYSL_U64,
96
SYSL_BE16,
97
SYSL_IP4,
98
SYSL_STR,
99
SYSL_FLAG,
100
SYSL_MAC,
101
} sysctl_type_t;
102
103
struct sysctl_info {
104
uint8_t name[32];
105
sysctl_type_t type;
106
sysctl_variable_t flag;
107
uint8_t support[16];
108
};
109
110
struct sysctl_op {
111
/* Coalesce options */
112
unsigned int rx_coalesce_usecs;
113
unsigned int rx_max_coalesced_frames;
114
unsigned int rx_coalesce_usecs_irq;
115
unsigned int rx_max_coalesced_frames_irq;
116
unsigned int tx_coalesce_usecs;
117
unsigned int tx_max_coalesced_frames;
118
unsigned int tx_coalesce_usecs_irq;
119
unsigned int tx_max_coalesced_frames_irq;
120
unsigned int stats_block_coalesce_usecs;
121
unsigned int use_adaptive_rx_coalesce;
122
unsigned int use_adaptive_tx_coalesce;
123
unsigned int pkt_rate_low;
124
unsigned int rx_coalesce_usecs_low;
125
unsigned int rx_max_coalesced_frames_low;
126
unsigned int tx_coalesce_usecs_low;
127
unsigned int tx_max_coalesced_frames_low;
128
unsigned int pkt_rate_high;
129
unsigned int rx_coalesce_usecs_high;
130
unsigned int rx_max_coalesced_frames_high;
131
unsigned int tx_coalesce_usecs_high;
132
unsigned int tx_max_coalesced_frames_high;
133
unsigned int rate_sample_interval;
134
135
/* Pasue options */
136
unsigned int autoneg;
137
unsigned int tx_pause;
138
unsigned int rx_pause;
139
140
/* Link settings options */
141
unsigned int speed;
142
unsigned int duplex;
143
144
/* Ring param options */
145
unsigned int rx_max_pending;
146
unsigned int rx_mini_max_pending;
147
unsigned int rx_jumbo_max_pending;
148
unsigned int tx_max_pending;
149
unsigned int rx_pending;
150
unsigned int rx_mini_pending;
151
unsigned int rx_jumbo_pending;
152
unsigned int tx_pending;
153
154
/* Channels options */
155
unsigned int max_rx;
156
unsigned int max_tx;
157
unsigned int max_other;
158
unsigned int max_combined;
159
unsigned int rx_count;
160
unsigned int tx_count;
161
unsigned int other_count;
162
unsigned int combined_count;
163
} sys_op;
164
165
#define GSTRING_LEN 32
166
167
struct xgbe_stats {
168
char stat_string[GSTRING_LEN];
169
int stat_size;
170
int stat_offset;
171
};
172
173
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
174
175
#define XGMAC_MMC_STAT(_string, _var) \
176
{ _string, \
177
FIELD_SIZEOF(struct xgbe_mmc_stats, _var), \
178
offsetof(struct xgbe_prv_data, mmc_stats._var), \
179
}
180
181
#define XGMAC_EXT_STAT(_string, _var) \
182
{ _string, \
183
FIELD_SIZEOF(struct xgbe_ext_stats, _var), \
184
offsetof(struct xgbe_prv_data, ext_stats._var), \
185
}
186
static const struct xgbe_stats xgbe_gstring_stats[] = {
187
XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
188
XGMAC_MMC_STAT("tx_packets", txframecount_gb),
189
XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
190
XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
191
XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
192
XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
193
XGMAC_EXT_STAT("tx_vxlan_packets", tx_vxlan_packets),
194
XGMAC_EXT_STAT("tx_tso_packets", tx_tso_packets),
195
XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
196
XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
197
XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
198
XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
199
XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
200
XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
201
XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
202
XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
203
204
XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
205
XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
206
XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
207
XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
208
XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
209
XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
210
XGMAC_EXT_STAT("rx_vxlan_packets", rx_vxlan_packets),
211
XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
212
XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
213
XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
214
XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
215
XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
216
XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
217
XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
218
XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
219
XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
220
XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
221
XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
222
XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
223
XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
224
XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
225
XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
226
XGMAC_EXT_STAT("rx_csum_errors", rx_csum_errors),
227
XGMAC_EXT_STAT("rx_vxlan_csum_errors", rx_vxlan_csum_errors),
228
XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
229
XGMAC_EXT_STAT("rx_split_header_packets", rx_split_header_packets),
230
XGMAC_EXT_STAT("rx_buffer_unavailable", rx_buffer_unavailable),
231
};
232
233
#define XGBE_STATS_COUNT ARRAY_SIZE(xgbe_gstring_stats)
234
235
char** alloc_sysctl_buffer(void);
236
void get_val(char *buf, char **op, char **val, int *n_op);
237
void fill_data(struct sysctl_op *sys_op, int flag, unsigned int value);
238
239
static int
240
exit_bad_op(void)
241
{
242
243
printf("SYSCTL: bad command line option (s)\n");
244
return(-EINVAL);
245
}
246
247
static inline int
248
get_ubuf(struct sysctl_req *req, char *ubuf)
249
{
250
int rc;
251
252
printf("%s: len:0x%li idx:0x%li\n", __func__, req->newlen,
253
req->newidx);
254
if (req->newlen >= SYSCTL_BUF_LEN)
255
return (-EINVAL);
256
257
rc = SYSCTL_IN(req, ubuf, req->newlen);
258
if (rc)
259
return (rc);
260
ubuf[req->newlen] = '\0';
261
262
return (0);
263
}
264
265
char**
266
alloc_sysctl_buffer(void)
267
{
268
char **buffer;
269
int i;
270
271
buffer = malloc(sizeof(char *)*32, M_AXGBE, M_WAITOK | M_ZERO);
272
for(i = 0; i < 32; i++)
273
buffer[i] = malloc(sizeof(char)*32, M_AXGBE, M_WAITOK | M_ZERO);
274
275
return (buffer);
276
}
277
278
void
279
get_val(char *buf, char **op, char **val, int *n_op)
280
{
281
int blen = strlen(buf);
282
int count = 0;
283
int i, j;
284
285
*n_op = 0;
286
for (i = 0; i < blen; i++) {
287
count++;
288
/* Get sysctl command option */
289
for (j = 0; buf[i] != ' '; j++) {
290
if (i >= blen)
291
break;
292
op[*n_op][j] = buf[i++];
293
}
294
op[*n_op][j+1] = '\0';
295
if (i >= strlen(buf))
296
goto out;
297
298
/* Get sysctl value*/
299
i++;
300
for (j = 0; buf[i] != ' '; j++) {
301
if (i >= blen)
302
break;
303
val[*n_op][j] = buf[i++];
304
}
305
val[*n_op][j+1] = '\0';
306
if (i >= strlen(buf))
307
goto out;
308
309
*n_op = count;
310
}
311
312
out:
313
*n_op = count;
314
}
315
316
void
317
fill_data(struct sysctl_op *sys_op, int flag, unsigned int value)
318
{
319
320
switch(flag) {
321
case 1:
322
sys_op->rx_coalesce_usecs = value;
323
break;
324
case 2:
325
sys_op->rx_max_coalesced_frames = value;
326
break;
327
case 3:
328
sys_op->rx_coalesce_usecs_irq = value;
329
break;
330
case 4:
331
sys_op->rx_max_coalesced_frames_irq = value;
332
break;
333
case 5:
334
sys_op->tx_coalesce_usecs = value;
335
break;
336
case 6:
337
sys_op->tx_max_coalesced_frames = value;
338
break;
339
case 7:
340
sys_op->tx_coalesce_usecs_irq = value;
341
break;
342
case 8:
343
sys_op->tx_max_coalesced_frames_irq = value;
344
break;
345
case 9:
346
sys_op->stats_block_coalesce_usecs = value;
347
break;
348
case 10:
349
sys_op->use_adaptive_rx_coalesce = value;
350
break;
351
case 11:
352
sys_op->use_adaptive_tx_coalesce = value;
353
break;
354
case 12:
355
sys_op->pkt_rate_low = value;
356
break;
357
case 13:
358
sys_op->rx_coalesce_usecs_low = value;
359
break;
360
case 14:
361
sys_op->rx_max_coalesced_frames_low = value;
362
break;
363
case 15:
364
sys_op->tx_coalesce_usecs_low = value;
365
break;
366
case 16:
367
sys_op->tx_max_coalesced_frames_low = value;
368
break;
369
case 17:
370
sys_op->pkt_rate_high = value;
371
break;
372
case 18:
373
sys_op->rx_coalesce_usecs_high = value;
374
break;
375
case 19:
376
sys_op->rx_max_coalesced_frames_high = value;
377
break;
378
case 20:
379
sys_op->tx_coalesce_usecs_high = value;
380
break;
381
case 21:
382
sys_op->tx_max_coalesced_frames_high = value;
383
break;
384
case 22:
385
sys_op->rate_sample_interval = value;
386
break;
387
case 23:
388
sys_op->autoneg = value;
389
break;
390
case 24:
391
sys_op->rx_pause = value;
392
break;
393
case 25:
394
sys_op->tx_pause = value;
395
break;
396
case 26:
397
sys_op->speed = value;
398
break;
399
case 27:
400
sys_op->duplex = value;
401
break;
402
case 28:
403
sys_op->rx_pending = value;
404
break;
405
case 29:
406
sys_op->rx_mini_pending = value;
407
break;
408
case 30:
409
sys_op->rx_jumbo_pending = value;
410
break;
411
case 31:
412
sys_op->tx_pending = value;
413
break;
414
default:
415
printf("Option error\n");
416
}
417
}
418
419
static int
420
parse_generic_sysctl(struct xgbe_prv_data *pdata, char *buf,
421
struct sysctl_info *info, unsigned int n_info)
422
{
423
struct sysctl_op *sys_op = pdata->sys_op;
424
unsigned int value;
425
char **op, **val;
426
int n_op = 0;
427
int rc = 0;
428
int i, idx;
429
430
op = alloc_sysctl_buffer();
431
val = alloc_sysctl_buffer();
432
get_val(buf, op, val, &n_op);
433
434
for (i = 0; i < n_op; i++) {
435
for (idx = 0; idx < n_info; idx++) {
436
if (strcmp(info[idx].name, op[i]) == 0) {
437
if (strcmp(info[idx].support,
438
"not-supported") == 0){
439
axgbe_printf(1, "ignoring not-supported "
440
"option \"%s\"\n", info[idx].name);
441
break;
442
}
443
switch(info[idx].type) {
444
case SYSL_BOOL: {
445
if (!strcmp(val[i], "on"))
446
fill_data(sys_op,
447
info[idx].flag, 1);
448
else if (!strcmp(val[i], "off"))
449
fill_data(sys_op,
450
info[idx].flag, 0);
451
else
452
rc = exit_bad_op();
453
break;
454
}
455
case SYSL_S32:
456
sscanf(val[i], "%u", &value);
457
fill_data(sys_op, info[idx].flag, value);
458
break;
459
case SYSL_U8:
460
if (!strcmp(val[i], "half"))
461
fill_data(sys_op,
462
info[idx].flag, DUPLEX_HALF);
463
else if (!strcmp(val[i], "full"))
464
fill_data(sys_op,
465
info[idx].flag, DUPLEX_FULL);
466
else
467
exit_bad_op();
468
default:
469
rc = exit_bad_op();
470
}
471
}
472
}
473
}
474
475
for(i = 0; i < 32; i++)
476
free(op[i], M_AXGBE);
477
free(op, M_AXGBE);
478
479
for(i = 0; i < 32; i++)
480
free(val[i], M_AXGBE);
481
free(val, M_AXGBE);
482
return (rc);
483
}
484
485
486
static int
487
sysctl_xgmac_reg_addr_handler(SYSCTL_HANDLER_ARGS)
488
{
489
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
490
ssize_t buf_size = 64;
491
char buf[buf_size];
492
struct sbuf *sb;
493
unsigned int reg;
494
int rc = 0;
495
496
if (req->newptr == NULL) {
497
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
498
if (sb == NULL) {
499
rc = ENOMEM;
500
return (rc);
501
}
502
503
axgbe_printf(2, "READ: %s: sysctl_xgmac_reg: 0x%x\n", __func__,
504
pdata->sysctl_xgmac_reg);
505
sbuf_printf(sb, "\nXGMAC reg_addr: 0x%x\n",
506
pdata->sysctl_xgmac_reg);
507
rc = sbuf_finish(sb);
508
sbuf_delete(sb);
509
return (rc);
510
}
511
512
rc = get_ubuf(req, buf);
513
if (rc == 0) {
514
sscanf(buf, "%x", &reg);
515
axgbe_printf(2, "WRITE: %s: reg: 0x%x\n", __func__, reg);
516
pdata->sysctl_xgmac_reg = reg;
517
}
518
519
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
520
return (rc);
521
}
522
523
static int
524
sysctl_get_drv_info_handler(SYSCTL_HANDLER_ARGS)
525
{
526
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
527
struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
528
ssize_t buf_size = 64;
529
struct sbuf *sb;
530
int rc = 0;
531
532
if (req->newptr == NULL) {
533
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
534
if (sb == NULL) {
535
rc = ENOMEM;
536
return (rc);
537
}
538
539
sbuf_printf(sb, "\ndriver: %s", XGBE_DRV_NAME);
540
sbuf_printf(sb, "\nversion: %s", XGBE_DRV_VERSION);
541
sbuf_printf(sb, "\nfirmware-version: %d.%d.%d",
542
XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
543
XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
544
XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
545
sbuf_printf(sb, "\nbus-info: %04d:%02d:%02d",
546
pdata->pcie_bus, pdata->pcie_device, pdata->pcie_func);
547
548
rc = sbuf_finish(sb);
549
sbuf_delete(sb);
550
return (rc);
551
}
552
553
return (-EINVAL);
554
}
555
556
static int
557
sysctl_get_link_info_handler(SYSCTL_HANDLER_ARGS)
558
{
559
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
560
ssize_t buf_size = 64;
561
struct sbuf *sb;
562
int rc = 0;
563
564
if (req->newptr == NULL) {
565
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
566
if (sb == NULL) {
567
rc = ENOMEM;
568
return (rc);
569
}
570
571
sbuf_printf(sb, "\nLink is %s", pdata->phy.link ? "Up" : "Down");
572
rc = sbuf_finish(sb);
573
sbuf_delete(sb);
574
return (0);
575
}
576
577
return (-EINVAL);
578
}
579
580
#define COALESCE_SYSCTL_INFO(__coalop) \
581
{ \
582
{ "adaptive-rx", SYSL_BOOL, use_adaptive_rx_coalesce, "not-supported" }, \
583
{ "adaptive-tx", SYSL_BOOL, use_adaptive_tx_coalesce, "not-supported" }, \
584
{ "sample-interval", SYSL_S32, rate_sample_interval, "not-supported" }, \
585
{ "stats-block-usecs", SYSL_S32, stats_block_coalesce_usecs, "not-supported" }, \
586
{ "pkt-rate-low", SYSL_S32, pkt_rate_low, "not-supported" }, \
587
{ "pkt-rate-high", SYSL_S32, pkt_rate_high, "not-supported" }, \
588
{ "rx-usecs", SYSL_S32, rx_coalesce_usecs, "supported" }, \
589
{ "rx-frames", SYSL_S32, rx_max_coalesced_frames, "supported" }, \
590
{ "rx-usecs-irq", SYSL_S32, rx_coalesce_usecs_irq, "not-supported" }, \
591
{ "rx-frames-irq", SYSL_S32, rx_max_coalesced_frames_irq, "not-supported" }, \
592
{ "tx-usecs", SYSL_S32, tx_coalesce_usecs, "not-supported" }, \
593
{ "tx-frames", SYSL_S32, tx_max_coalesced_frames, "supported" }, \
594
{ "tx-usecs-irq", SYSL_S32, tx_coalesce_usecs_irq, "not-supported" }, \
595
{ "tx-frames-irq", SYSL_S32, tx_max_coalesced_frames_irq, "not-supported" }, \
596
{ "rx-usecs-low", SYSL_S32, rx_coalesce_usecs_low, "not-supported" }, \
597
{ "rx-frames-low", SYSL_S32, rx_max_coalesced_frames_low, "not-supported"}, \
598
{ "tx-usecs-low", SYSL_S32, tx_coalesce_usecs_low, "not-supported" }, \
599
{ "tx-frames-low", SYSL_S32, tx_max_coalesced_frames_low, "not-supported" }, \
600
{ "rx-usecs-high", SYSL_S32, rx_coalesce_usecs_high, "not-supported" }, \
601
{ "rx-frames-high", SYSL_S32, rx_max_coalesced_frames_high, "not-supported" }, \
602
{ "tx-usecs-high", SYSL_S32, tx_coalesce_usecs_high, "not-supported" }, \
603
{ "tx-frames-high", SYSL_S32, tx_max_coalesced_frames_high, "not-supported" }, \
604
}
605
606
static int
607
sysctl_coalesce_handler(SYSCTL_HANDLER_ARGS)
608
{
609
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
610
struct xgbe_hw_if *hw_if = &pdata->hw_if;
611
struct sysctl_op *sys_op = pdata->sys_op;
612
struct sysctl_info sysctl_coalesce[] = COALESCE_SYSCTL_INFO(coalop);
613
unsigned int rx_frames, rx_riwt, rx_usecs;
614
unsigned int tx_frames;
615
ssize_t buf_size = 64;
616
char buf[buf_size];
617
struct sbuf *sb;
618
int rc = 0;
619
620
if (req->newptr == NULL) {
621
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
622
if (sb == NULL) {
623
rc = ENOMEM;
624
return (rc);
625
}
626
sys_op->rx_coalesce_usecs = pdata->rx_usecs;
627
sys_op->rx_max_coalesced_frames = pdata->rx_frames;
628
sys_op->tx_max_coalesced_frames = pdata->tx_frames;
629
630
sbuf_printf(sb, "\nAdaptive RX: %s TX: %s\n",
631
sys_op->use_adaptive_rx_coalesce ? "on" : "off",
632
sys_op->use_adaptive_tx_coalesce ? "on" : "off");
633
634
sbuf_printf(sb, "stats-block-usecs: %u\n"
635
"sample-interval: %u\n"
636
"pkt-rate-low: %u\n"
637
"pkt-rate-high: %u\n"
638
"\n"
639
"rx-usecs: %u\n"
640
"rx-frames: %u\n"
641
"rx-usecs-irq: %u\n"
642
"rx-frames-irq: %u\n"
643
"\n"
644
"tx-usecs: %u\n"
645
"tx-frames: %u\n"
646
"tx-usecs-irq: %u\n"
647
"tx-frames-irq: %u\n"
648
"\n"
649
"rx-usecs-low: %u\n"
650
"rx-frames-low: %u\n"
651
"tx-usecs-low: %u\n"
652
"tx-frames-low: %u\n"
653
"\n"
654
"rx-usecs-high: %u\n"
655
"rx-frames-high: %u\n"
656
"tx-usecs-high: %u\n"
657
"tx-frames-high: %u\n",
658
sys_op->stats_block_coalesce_usecs,
659
sys_op->rate_sample_interval,
660
sys_op->pkt_rate_low,
661
sys_op->pkt_rate_high,
662
663
sys_op->rx_coalesce_usecs,
664
sys_op->rx_max_coalesced_frames,
665
sys_op->rx_coalesce_usecs_irq,
666
sys_op->rx_max_coalesced_frames_irq,
667
668
sys_op->tx_coalesce_usecs,
669
sys_op->tx_max_coalesced_frames,
670
sys_op->tx_coalesce_usecs_irq,
671
sys_op->tx_max_coalesced_frames_irq,
672
673
sys_op->rx_coalesce_usecs_low,
674
sys_op->rx_max_coalesced_frames_low,
675
sys_op->tx_coalesce_usecs_low,
676
sys_op->tx_max_coalesced_frames_low,
677
678
sys_op->rx_coalesce_usecs_high,
679
sys_op->rx_max_coalesced_frames_high,
680
sys_op->tx_coalesce_usecs_high,
681
sys_op->tx_max_coalesced_frames_high);
682
683
rc = sbuf_finish(sb);
684
sbuf_delete(sb);
685
return (0);
686
}
687
688
rc = get_ubuf(req, buf);
689
if (rc == 0) {
690
parse_generic_sysctl(pdata, buf, sysctl_coalesce,
691
ARRAY_SIZE(sysctl_coalesce));
692
693
rx_riwt = hw_if->usec_to_riwt(pdata, sys_op->rx_coalesce_usecs);
694
rx_usecs = sys_op->rx_coalesce_usecs;
695
rx_frames = sys_op->rx_max_coalesced_frames;
696
697
/* Use smallest possible value if conversion resulted in zero */
698
if (rx_usecs && !rx_riwt)
699
rx_riwt = 1;
700
701
/* Check the bounds of values for Rx */
702
if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
703
axgbe_printf(2, "rx-usec is limited to %d usecs\n",
704
hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT));
705
return (-EINVAL);
706
}
707
if (rx_frames > pdata->rx_desc_count) {
708
axgbe_printf(2, "rx-frames is limited to %d frames\n",
709
pdata->rx_desc_count);
710
return (-EINVAL);
711
}
712
713
tx_frames = sys_op->tx_max_coalesced_frames;
714
715
/* Check the bounds of values for Tx */
716
if (tx_frames > pdata->tx_desc_count) {
717
axgbe_printf(2, "tx-frames is limited to %d frames\n",
718
pdata->tx_desc_count);
719
return (-EINVAL);
720
}
721
722
pdata->rx_riwt = rx_riwt;
723
pdata->rx_usecs = rx_usecs;
724
pdata->rx_frames = rx_frames;
725
hw_if->config_rx_coalesce(pdata);
726
727
pdata->tx_frames = tx_frames;
728
hw_if->config_tx_coalesce(pdata);
729
}
730
731
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
732
733
return (rc);
734
}
735
736
static int
737
sysctl_pauseparam_handler(SYSCTL_HANDLER_ARGS)
738
{
739
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
740
struct sysctl_op *sys_op = pdata->sys_op;
741
struct sysctl_info sysctl_pauseparam[] = {
742
{ "autoneg", SYSL_BOOL, autoneg, "supported" },
743
{ "rx", SYSL_BOOL, rx_pause, "supported" },
744
{ "tx", SYSL_BOOL, tx_pause, "supported" },
745
};
746
ssize_t buf_size = 512;
747
char buf[buf_size];
748
struct sbuf *sb;
749
int rc = 0;
750
751
if (req->newptr == NULL) {
752
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
753
if (sb == NULL) {
754
rc = ENOMEM;
755
return (rc);
756
}
757
sys_op->autoneg = pdata->phy.pause_autoneg;
758
sys_op->tx_pause = pdata->phy.tx_pause;
759
sys_op->rx_pause = pdata->phy.rx_pause;
760
761
sbuf_printf(sb,
762
"\nAutonegotiate: %s\n"
763
"RX: %s\n"
764
"TX: %s\n",
765
sys_op->autoneg ? "on" : "off",
766
sys_op->rx_pause ? "on" : "off",
767
sys_op->tx_pause ? "on" : "off");
768
769
if (pdata->phy.lp_advertising) {
770
int an_rx = 0, an_tx = 0;
771
772
if (pdata->phy.advertising & pdata->phy.lp_advertising &
773
ADVERTISED_Pause) {
774
an_tx = 1;
775
an_rx = 1;
776
} else if (pdata->phy.advertising &
777
pdata->phy.lp_advertising & ADVERTISED_Asym_Pause) {
778
if (pdata->phy.advertising & ADVERTISED_Pause)
779
an_rx = 1;
780
else if (pdata->phy.lp_advertising &
781
ADVERTISED_Pause)
782
an_tx = 1;
783
}
784
sbuf_printf(sb,
785
"\n->\nRX negotiated: %s\n"
786
"TX negotiated: %s\n",
787
an_rx ? "on" : "off",
788
an_tx ? "on" : "off");
789
}
790
rc = sbuf_finish(sb);
791
sbuf_delete(sb);
792
return (0);
793
}
794
795
rc = get_ubuf(req, buf);
796
if (rc == 0) {
797
parse_generic_sysctl(pdata, buf, sysctl_pauseparam,
798
ARRAY_SIZE(sysctl_pauseparam));
799
800
if (sys_op->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) {
801
axgbe_error("autoneg disabled, pause autoneg not available\n");
802
return (-EINVAL);
803
}
804
805
pdata->phy.pause_autoneg = sys_op->autoneg;
806
pdata->phy.tx_pause = sys_op->tx_pause;
807
pdata->phy.rx_pause = sys_op->rx_pause;
808
809
XGBE_CLR_ADV(&pdata->phy, Pause);
810
XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
811
812
if (sys_op->rx_pause) {
813
XGBE_SET_ADV(&pdata->phy, Pause);
814
XGBE_SET_ADV(&pdata->phy, Asym_Pause);
815
}
816
817
if (sys_op->tx_pause) {
818
/* Equivalent to XOR of Asym_Pause */
819
if (XGBE_ADV(&pdata->phy, Asym_Pause))
820
XGBE_CLR_ADV(&pdata->phy, Asym_Pause);
821
else
822
XGBE_SET_ADV(&pdata->phy, Asym_Pause);
823
}
824
825
if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
826
rc = pdata->phy_if.phy_config_aneg(pdata);
827
828
}
829
830
return (rc);
831
}
832
833
static int
834
sysctl_link_ksettings_handler(SYSCTL_HANDLER_ARGS)
835
{
836
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
837
struct sysctl_op *sys_op = pdata->sys_op;
838
struct sysctl_info sysctl_linksettings[] = {
839
{ "autoneg", SYSL_BOOL, autoneg, "supported" },
840
{ "speed", SYSL_U32, speed, "supported" },
841
{ "duplex", SYSL_U8, duplex, "supported" },
842
};
843
ssize_t buf_size = 512;
844
char buf[buf_size], link_modes[16], speed_modes[16];
845
struct sbuf *sb;
846
uint32_t speed;
847
int rc = 0;
848
849
if (req->newptr == NULL) {
850
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
851
if (sb == NULL) {
852
rc = ENOMEM;
853
return (rc);
854
}
855
sys_op->autoneg = pdata->phy.autoneg;
856
sys_op->speed = pdata->phy.speed;
857
sys_op->duplex = pdata->phy.duplex;
858
859
XGBE_LM_COPY(&pdata->phy, supported, &pdata->phy, supported);
860
XGBE_LM_COPY(&pdata->phy, advertising, &pdata->phy, advertising);
861
XGBE_LM_COPY(&pdata->phy, lp_advertising, &pdata->phy, lp_advertising);
862
863
switch (sys_op->speed) {
864
case 1:
865
strcpy(link_modes, "Unknown");
866
strcpy(speed_modes, "Unknown");
867
break;
868
case 2:
869
strcpy(link_modes, "10Gbps/Full");
870
strcpy(speed_modes, "10000");
871
break;
872
case 3:
873
strcpy(link_modes, "2.5Gbps/Full");
874
strcpy(speed_modes, "2500");
875
break;
876
case 4:
877
strcpy(link_modes, "1Gbps/Full");
878
strcpy(speed_modes, "1000");
879
break;
880
case 5:
881
strcpy(link_modes, "100Mbps/Full");
882
strcpy(speed_modes, "100");
883
break;
884
case 6:
885
strcpy(link_modes, "10Mbps/Full");
886
strcpy(speed_modes, "10");
887
break;
888
}
889
890
sbuf_printf(sb,
891
"\nlink_modes: %s\n"
892
"autonegotiation: %s\n"
893
"speed: %sMbps\n",
894
link_modes,
895
(sys_op->autoneg == AUTONEG_DISABLE) ? "off" : "on",
896
speed_modes);
897
898
switch (sys_op->duplex) {
899
case DUPLEX_HALF:
900
sbuf_printf(sb, "Duplex: Half\n");
901
break;
902
case DUPLEX_FULL:
903
sbuf_printf(sb, "Duplex: Full\n");
904
break;
905
default:
906
sbuf_printf(sb, "Duplex: Unknown\n");
907
break;
908
}
909
rc = sbuf_finish(sb);
910
sbuf_delete(sb);
911
return (0);
912
}
913
914
rc = get_ubuf(req, buf);
915
if (rc == 0) {
916
parse_generic_sysctl(pdata, buf, sysctl_linksettings,
917
ARRAY_SIZE(sysctl_linksettings));
918
919
speed = sys_op->speed;
920
921
if ((sys_op->autoneg != AUTONEG_ENABLE) &&
922
(sys_op->autoneg != AUTONEG_DISABLE)) {
923
axgbe_error("unsupported autoneg %hhu\n",
924
(unsigned char)sys_op->autoneg);
925
return (-EINVAL);
926
}
927
928
if (sys_op->autoneg == AUTONEG_DISABLE) {
929
if (!pdata->phy_if.phy_valid_speed(pdata, speed)) {
930
axgbe_error("unsupported speed %u\n", speed);
931
return (-EINVAL);
932
}
933
934
if (sys_op->duplex != DUPLEX_FULL) {
935
axgbe_error("unsupported duplex %hhu\n",
936
(unsigned char)sys_op->duplex);
937
return (-EINVAL);
938
}
939
}
940
941
pdata->phy.autoneg = sys_op->autoneg;
942
pdata->phy.speed = speed;
943
pdata->phy.duplex = sys_op->duplex;
944
945
if (sys_op->autoneg == AUTONEG_ENABLE)
946
XGBE_SET_ADV(&pdata->phy, Autoneg);
947
else
948
XGBE_CLR_ADV(&pdata->phy, Autoneg);
949
950
if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
951
rc = pdata->phy_if.phy_config_aneg(pdata);
952
}
953
954
return (rc);
955
}
956
957
static int
958
sysctl_ringparam_handler(SYSCTL_HANDLER_ARGS)
959
{
960
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
961
struct sysctl_op *sys_op = pdata->sys_op;
962
struct sysctl_info sysctl_ringparam[] = {
963
{ "rx", SYSL_S32, rx_pending, "supported" },
964
{ "rx-mini", SYSL_S32, rx_mini_pending, "supported" },
965
{ "rx-jumbo", SYSL_S32, rx_jumbo_pending, "supported" },
966
{ "tx", SYSL_S32, tx_pending, "supported" },
967
};
968
ssize_t buf_size = 512;
969
unsigned int rx, tx;
970
char buf[buf_size];
971
struct sbuf *sb;
972
int rc = 0;
973
974
if (req->newptr == NULL) {
975
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
976
if (sb == NULL) {
977
rc = ENOMEM;
978
return (rc);
979
}
980
sys_op->rx_max_pending = XGBE_RX_DESC_CNT_MAX;
981
sys_op->tx_max_pending = XGBE_TX_DESC_CNT_MAX;
982
sys_op->rx_pending = pdata->rx_desc_count;
983
sys_op->tx_pending = pdata->tx_desc_count;
984
985
sbuf_printf(sb,
986
"\nPre-set maximums:\n"
987
"RX: %u\n"
988
"RX Mini: %u\n"
989
"RX Jumbo: %u\n"
990
"TX: %u\n",
991
sys_op->rx_max_pending,
992
sys_op->rx_mini_max_pending,
993
sys_op->rx_jumbo_max_pending,
994
sys_op->tx_max_pending);
995
996
sbuf_printf(sb,
997
"\nCurrent hardware settings:\n"
998
"RX: %u\n"
999
"RX Mini: %u\n"
1000
"RX Jumbo: %u\n"
1001
"TX: %u\n",
1002
sys_op->rx_pending,
1003
sys_op->rx_mini_pending,
1004
sys_op->rx_jumbo_pending,
1005
sys_op->tx_pending);
1006
1007
rc = sbuf_finish(sb);
1008
sbuf_delete(sb);
1009
return (0);
1010
}
1011
1012
rc = get_ubuf(req, buf);
1013
if (rc == 0) {
1014
parse_generic_sysctl(pdata, buf, sysctl_ringparam,
1015
ARRAY_SIZE(sysctl_ringparam));
1016
1017
if (sys_op->rx_mini_pending || sys_op->rx_jumbo_pending) {
1018
axgbe_error("unsupported ring parameter\n");
1019
return (-EINVAL);
1020
}
1021
1022
if ((sys_op->rx_pending < XGBE_RX_DESC_CNT_MIN) ||
1023
(sys_op->rx_pending > XGBE_RX_DESC_CNT_MAX)) {
1024
axgbe_error("rx ring param must be between %u and %u\n",
1025
XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX);
1026
return (-EINVAL);
1027
}
1028
1029
if ((sys_op->tx_pending < XGBE_TX_DESC_CNT_MIN) ||
1030
(sys_op->tx_pending > XGBE_TX_DESC_CNT_MAX)) {
1031
axgbe_error("tx ring param must be between %u and %u\n",
1032
XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX);
1033
return (-EINVAL);
1034
}
1035
1036
rx = rounddown_pow_of_two(sys_op->rx_pending);
1037
if (rx != sys_op->rx_pending)
1038
axgbe_printf(1, "rx ring param rounded to power of 2: %u\n",
1039
rx);
1040
1041
tx = rounddown_pow_of_two(sys_op->tx_pending);
1042
if (tx != sys_op->tx_pending)
1043
axgbe_printf(1, "tx ring param rounded to power of 2: %u\n",
1044
tx);
1045
1046
if ((rx == pdata->rx_desc_count) &&
1047
(tx == pdata->tx_desc_count))
1048
goto out;
1049
1050
pdata->rx_desc_count = rx;
1051
pdata->tx_desc_count = tx;
1052
1053
/* TODO - restart dev */
1054
}
1055
1056
out:
1057
return (0);
1058
}
1059
1060
static int
1061
sysctl_channels_handler(SYSCTL_HANDLER_ARGS)
1062
{
1063
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1064
struct sysctl_op *sys_op = pdata->sys_op;
1065
struct sysctl_info sysctl_channels[] = {
1066
{ "rx", SYSL_S32, rx_count, "supported" },
1067
{ "tx", SYSL_S32, tx_count, "supported" },
1068
{ "other", SYSL_S32, other_count, "supported" },
1069
{ "combined", SYSL_S32, combined_count, "supported" },
1070
};
1071
unsigned int rx, tx, combined;
1072
ssize_t buf_size = 512;
1073
char buf[buf_size];
1074
struct sbuf *sb;
1075
int rc = 0;
1076
1077
if (req->newptr == NULL) {
1078
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1079
if (sb == NULL) {
1080
rc = ENOMEM;
1081
return (rc);
1082
}
1083
rx = min(pdata->hw_feat.rx_ch_cnt, pdata->rx_max_channel_count);
1084
rx = min(rx, pdata->channel_irq_count);
1085
tx = min(pdata->hw_feat.tx_ch_cnt, pdata->tx_max_channel_count);
1086
tx = min(tx, pdata->channel_irq_count);
1087
tx = min(tx, pdata->tx_max_q_count);
1088
1089
combined = min(rx, tx);
1090
1091
sys_op->max_combined = combined;
1092
sys_op->max_rx = rx ? rx - 1 : 0;
1093
sys_op->max_tx = tx ? tx - 1 : 0;
1094
1095
/* Get current settings based on device state */
1096
rx = pdata->rx_ring_count;
1097
tx = pdata->tx_ring_count;
1098
1099
combined = min(rx, tx);
1100
rx -= combined;
1101
tx -= combined;
1102
1103
sys_op->combined_count = combined;
1104
sys_op->rx_count = rx;
1105
sys_op->tx_count = tx;
1106
1107
sbuf_printf(sb,
1108
"\nPre-set maximums:\n"
1109
"RX: %u\n"
1110
"TX: %u\n"
1111
"Other: %u\n"
1112
"Combined: %u\n",
1113
sys_op->max_rx, sys_op->max_tx,
1114
sys_op->max_other,
1115
sys_op->max_combined);
1116
1117
sbuf_printf(sb,
1118
"\nCurrent hardware settings:\n"
1119
"RX: %u\n"
1120
"TX: %u\n"
1121
"Other: %u\n"
1122
"Combined: %u\n",
1123
sys_op->rx_count, sys_op->tx_count,
1124
sys_op->other_count,
1125
sys_op->combined_count);
1126
1127
rc = sbuf_finish(sb);
1128
sbuf_delete(sb);
1129
return (0);
1130
}
1131
1132
rc = get_ubuf(req, buf);
1133
if (rc == 0) {
1134
parse_generic_sysctl(pdata, buf, sysctl_channels,
1135
ARRAY_SIZE(sysctl_channels));
1136
1137
axgbe_error( "channel inputs: combined=%u, rx-only=%u,"
1138
" tx-only=%u\n", sys_op->combined_count,
1139
sys_op->rx_count, sys_op->tx_count);
1140
}
1141
1142
return (rc);
1143
}
1144
1145
1146
static int
1147
sysctl_mac_stats_handler(SYSCTL_HANDLER_ARGS)
1148
{
1149
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1150
ssize_t buf_size = 64;
1151
struct sbuf *sb;
1152
int rc = 0;
1153
int i;
1154
1155
if (req->newptr == NULL) {
1156
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1157
if (sb == NULL) {
1158
rc = ENOMEM;
1159
return (rc);
1160
}
1161
1162
pdata->hw_if.read_mmc_stats(pdata);
1163
for (i = 0; i < XGBE_STATS_COUNT; i++) {
1164
sbuf_printf(sb, "\n %s: %lu",
1165
xgbe_gstring_stats[i].stat_string,
1166
*(uint64_t *)((uint8_t *)pdata + xgbe_gstring_stats[i].stat_offset));
1167
}
1168
for (i = 0; i < pdata->tx_ring_count; i++) {
1169
sbuf_printf(sb,
1170
"\n txq_packets[%d]: %lu"
1171
"\n txq_bytes[%d]: %lu",
1172
i, pdata->ext_stats.txq_packets[i],
1173
i, pdata->ext_stats.txq_bytes[i]);
1174
}
1175
for (i = 0; i < pdata->rx_ring_count; i++) {
1176
sbuf_printf(sb,
1177
"\n rxq_packets[%d]: %lu"
1178
"\n rxq_bytes[%d]: %lu",
1179
i, pdata->ext_stats.rxq_packets[i],
1180
i, pdata->ext_stats.rxq_bytes[i]);
1181
}
1182
1183
rc = sbuf_finish(sb);
1184
sbuf_delete(sb);
1185
return (rc);
1186
}
1187
1188
return (-EINVAL);
1189
}
1190
1191
static int
1192
sysctl_xgmac_reg_value_handler(SYSCTL_HANDLER_ARGS)
1193
{
1194
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1195
ssize_t buf_size = 64;
1196
char buf[buf_size];
1197
unsigned int value;
1198
struct sbuf *sb;
1199
int rc = 0;
1200
1201
if (req->newptr == NULL) {
1202
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1203
if (sb == NULL) {
1204
rc = ENOMEM;
1205
return (rc);
1206
}
1207
1208
value = XGMAC_IOREAD(pdata, pdata->sysctl_xgmac_reg);
1209
axgbe_printf(2, "READ: %s: value: 0x%x\n", __func__, value);
1210
sbuf_printf(sb, "\nXGMAC reg_value: 0x%x\n", value);
1211
rc = sbuf_finish(sb);
1212
sbuf_delete(sb);
1213
return (rc);
1214
}
1215
1216
rc = get_ubuf(req, buf);
1217
if (rc == 0) {
1218
sscanf(buf, "%x", &value);
1219
axgbe_printf(2, "WRITE: %s: value: 0x%x\n", __func__, value);
1220
XGMAC_IOWRITE(pdata, pdata->sysctl_xgmac_reg, value);
1221
}
1222
1223
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1224
return (rc);
1225
}
1226
1227
static int
1228
sysctl_xpcs_mmd_reg_handler(SYSCTL_HANDLER_ARGS)
1229
{
1230
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1231
ssize_t buf_size = 64;
1232
char buf[buf_size];
1233
struct sbuf *sb;
1234
unsigned int reg;
1235
int rc = 0;
1236
1237
if (req->newptr == NULL) {
1238
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1239
if (sb == NULL) {
1240
rc = ENOMEM;
1241
return (rc);
1242
}
1243
1244
axgbe_printf(2, "READ: %s: xpcs_mmd: 0x%x\n", __func__,
1245
pdata->sysctl_xpcs_mmd);
1246
sbuf_printf(sb, "\nXPCS mmd_reg: 0x%x\n",
1247
pdata->sysctl_xpcs_mmd);
1248
rc = sbuf_finish(sb);
1249
sbuf_delete(sb);
1250
return (rc);
1251
}
1252
1253
rc = get_ubuf(req, buf);
1254
if (rc == 0) {
1255
sscanf(buf, "%x", &reg);
1256
axgbe_printf(2, "WRITE: %s: mmd_reg: 0x%x\n", __func__, reg);
1257
pdata->sysctl_xpcs_mmd = reg;
1258
}
1259
1260
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1261
return (rc);
1262
}
1263
1264
static int
1265
sysctl_xpcs_reg_addr_handler(SYSCTL_HANDLER_ARGS)
1266
{
1267
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1268
ssize_t buf_size = 64;
1269
char buf[buf_size];
1270
struct sbuf *sb;
1271
unsigned int reg;
1272
int rc = 0;
1273
1274
if (req->newptr == NULL) {
1275
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1276
if (sb == NULL) {
1277
rc = ENOMEM;
1278
return (rc);
1279
}
1280
1281
axgbe_printf(2, "READ: %s: sysctl_xpcs_reg: 0x%x\n", __func__,
1282
pdata->sysctl_xpcs_reg);
1283
sbuf_printf(sb, "\nXPCS reg_addr: 0x%x\n",
1284
pdata->sysctl_xpcs_reg);
1285
rc = sbuf_finish(sb);
1286
sbuf_delete(sb);
1287
return (rc);
1288
}
1289
1290
rc = get_ubuf(req, buf);
1291
if (rc == 0) {
1292
sscanf(buf, "%x", &reg);
1293
axgbe_printf(2, "WRITE: %s: reg: 0x%x\n", __func__, reg);
1294
pdata->sysctl_xpcs_reg = reg;
1295
}
1296
1297
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1298
return (rc);
1299
}
1300
1301
static int
1302
sysctl_xpcs_reg_value_handler(SYSCTL_HANDLER_ARGS)
1303
{
1304
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1305
ssize_t buf_size = 64;
1306
char buf[buf_size];
1307
unsigned int value;
1308
struct sbuf *sb;
1309
int rc = 0;
1310
1311
if (req->newptr == NULL) {
1312
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1313
if (sb == NULL) {
1314
rc = ENOMEM;
1315
return (rc);
1316
}
1317
1318
value = XMDIO_READ(pdata, pdata->sysctl_xpcs_mmd,
1319
pdata->sysctl_xpcs_reg);
1320
axgbe_printf(2, "READ: %s: value: 0x%x\n", __func__, value);
1321
sbuf_printf(sb, "\nXPCS reg_value: 0x%x\n", value);
1322
rc = sbuf_finish(sb);
1323
sbuf_delete(sb);
1324
return (rc);
1325
}
1326
1327
rc = get_ubuf(req, buf);
1328
if (rc == 0) {
1329
sscanf(buf, "%x", &value);
1330
axgbe_printf(2, "WRITE: %s: value: 0x%x\n", __func__, value);
1331
XMDIO_WRITE(pdata, pdata->sysctl_xpcs_mmd,
1332
pdata->sysctl_xpcs_reg, value);
1333
}
1334
1335
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1336
return (rc);
1337
}
1338
1339
static int
1340
sysctl_xprop_reg_addr_handler(SYSCTL_HANDLER_ARGS)
1341
{
1342
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1343
ssize_t buf_size = 64;
1344
char buf[buf_size];
1345
struct sbuf *sb;
1346
unsigned int reg;
1347
int rc = 0;
1348
1349
if (req->newptr == NULL) {
1350
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1351
if (sb == NULL) {
1352
rc = ENOMEM;
1353
return (rc);
1354
}
1355
1356
axgbe_printf(2, "READ: %s: sysctl_xprop_reg: 0x%x\n", __func__,
1357
pdata->sysctl_xprop_reg);
1358
sbuf_printf(sb, "\nXPROP reg_addr: 0x%x\n",
1359
pdata->sysctl_xprop_reg);
1360
rc = sbuf_finish(sb);
1361
sbuf_delete(sb);
1362
return (rc);
1363
}
1364
1365
rc = get_ubuf(req, buf);
1366
if (rc == 0) {
1367
sscanf(buf, "%x", &reg);
1368
axgbe_printf(2, "WRITE: %s: reg: 0x%x\n", __func__, reg);
1369
pdata->sysctl_xprop_reg = reg;
1370
}
1371
1372
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1373
return (rc);
1374
}
1375
1376
static int
1377
sysctl_xprop_reg_value_handler(SYSCTL_HANDLER_ARGS)
1378
{
1379
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1380
ssize_t buf_size = 64;
1381
char buf[buf_size];
1382
unsigned int value;
1383
struct sbuf *sb;
1384
int rc = 0;
1385
1386
if (req->newptr == NULL) {
1387
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1388
if (sb == NULL) {
1389
rc = ENOMEM;
1390
return (rc);
1391
}
1392
1393
value = XP_IOREAD(pdata, pdata->sysctl_xprop_reg);
1394
axgbe_printf(2, "READ: %s: value: 0x%x\n", __func__, value);
1395
sbuf_printf(sb, "\nXPROP reg_value: 0x%x\n", value);
1396
rc = sbuf_finish(sb);
1397
sbuf_delete(sb);
1398
return (rc);
1399
}
1400
1401
rc = get_ubuf(req, buf);
1402
if (rc == 0) {
1403
sscanf(buf, "%x", &value);
1404
axgbe_printf(2, "WRITE: %s: value: 0x%x\n", __func__, value);
1405
XP_IOWRITE(pdata, pdata->sysctl_xprop_reg, value);
1406
}
1407
1408
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1409
return (rc);
1410
}
1411
1412
static int
1413
sysctl_xi2c_reg_addr_handler(SYSCTL_HANDLER_ARGS)
1414
{
1415
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1416
ssize_t buf_size = 64;
1417
char buf[buf_size];
1418
struct sbuf *sb;
1419
unsigned int reg;
1420
int rc = 0;
1421
1422
if (req->newptr == NULL) {
1423
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1424
if (sb == NULL) {
1425
rc = ENOMEM;
1426
return (rc);
1427
}
1428
1429
axgbe_printf(2, "READ: %s: sysctl_xi2c_reg: 0x%x\n", __func__,
1430
pdata->sysctl_xi2c_reg);
1431
sbuf_printf(sb, "\nXI2C reg_addr: 0x%x\n",
1432
pdata->sysctl_xi2c_reg);
1433
rc = sbuf_finish(sb);
1434
sbuf_delete(sb);
1435
return (rc);
1436
}
1437
1438
rc = get_ubuf(req, buf);
1439
if (rc == 0) {
1440
sscanf(buf, "%x", &reg);
1441
axgbe_printf(2, "WRITE: %s: reg: 0x%x\n", __func__, reg);
1442
pdata->sysctl_xi2c_reg = reg;
1443
}
1444
1445
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1446
return (rc);
1447
}
1448
1449
static int
1450
sysctl_xi2c_reg_value_handler(SYSCTL_HANDLER_ARGS)
1451
{
1452
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1453
ssize_t buf_size = 64;
1454
char buf[buf_size];
1455
unsigned int value;
1456
struct sbuf *sb;
1457
int rc = 0;
1458
1459
if (req->newptr == NULL) {
1460
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1461
if (sb == NULL) {
1462
rc = ENOMEM;
1463
return (rc);
1464
}
1465
1466
value = XI2C_IOREAD(pdata, pdata->sysctl_xi2c_reg);
1467
axgbe_printf(2, "READ: %s: value: 0x%x\n", __func__, value);
1468
sbuf_printf(sb, "\nXI2C reg_value: 0x%x\n", value);
1469
rc = sbuf_finish(sb);
1470
sbuf_delete(sb);
1471
return (rc);
1472
}
1473
1474
rc = get_ubuf(req, buf);
1475
if (rc == 0) {
1476
sscanf(buf, "%x", &value);
1477
axgbe_printf(2, "WRITE: %s: value: 0x%x\n", __func__, value);
1478
XI2C_IOWRITE(pdata, pdata->sysctl_xi2c_reg, value);
1479
}
1480
1481
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1482
return (rc);
1483
}
1484
1485
static int
1486
sysctl_an_cdr_wr_handler(SYSCTL_HANDLER_ARGS)
1487
{
1488
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1489
unsigned int an_cdr_wr = 0;
1490
ssize_t buf_size = 64;
1491
char buf[buf_size];
1492
struct sbuf *sb;
1493
int rc = 0;
1494
1495
if (req->newptr == NULL) {
1496
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1497
if (sb == NULL) {
1498
rc = ENOMEM;
1499
return (rc);
1500
}
1501
1502
axgbe_printf(2, "READ: %s: an_cdr_wr: %d\n", __func__,
1503
pdata->sysctl_an_cdr_workaround);
1504
sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_workaround);
1505
rc = sbuf_finish(sb);
1506
sbuf_delete(sb);
1507
return (rc);
1508
}
1509
1510
rc = get_ubuf(req, buf);
1511
if (rc == 0) {
1512
sscanf(buf, "%u", &an_cdr_wr);
1513
axgbe_printf(2, "WRITE: %s: an_cdr_wr: 0x%d\n", __func__,
1514
an_cdr_wr);
1515
1516
if (an_cdr_wr)
1517
pdata->sysctl_an_cdr_workaround = 1;
1518
else
1519
pdata->sysctl_an_cdr_workaround = 0;
1520
}
1521
1522
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1523
return (rc);
1524
}
1525
1526
static int
1527
sysctl_an_cdr_track_early_handler(SYSCTL_HANDLER_ARGS)
1528
{
1529
struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)arg1;
1530
unsigned int an_cdr_track_early = 0;
1531
ssize_t buf_size = 64;
1532
char buf[buf_size];
1533
struct sbuf *sb;
1534
int rc = 0;
1535
1536
if (req->newptr == NULL) {
1537
sb = sbuf_new_for_sysctl(NULL, NULL, buf_size, req);
1538
if (sb == NULL) {
1539
rc = ENOMEM;
1540
return (rc);
1541
}
1542
1543
axgbe_printf(2, "READ: %s: an_cdr_track_early %d\n", __func__,
1544
pdata->sysctl_an_cdr_track_early);
1545
sbuf_printf(sb, "%d\n", pdata->sysctl_an_cdr_track_early);
1546
rc = sbuf_finish(sb);
1547
sbuf_delete(sb);
1548
return (rc);
1549
}
1550
1551
rc = get_ubuf(req, buf);
1552
if (rc == 0) {
1553
sscanf(buf, "%u", &an_cdr_track_early);
1554
axgbe_printf(2, "WRITE: %s: an_cdr_track_early: %d\n", __func__,
1555
an_cdr_track_early);
1556
1557
if (an_cdr_track_early)
1558
pdata->sysctl_an_cdr_track_early = 1;
1559
else
1560
pdata->sysctl_an_cdr_track_early = 0;
1561
}
1562
1563
axgbe_printf(2, "%s: rc= %d\n", __func__, rc);
1564
return (rc);
1565
}
1566
1567
void
1568
axgbe_sysctl_exit(struct xgbe_prv_data *pdata)
1569
{
1570
1571
if (pdata->sys_op)
1572
free(pdata->sys_op, M_AXGBE);
1573
}
1574
1575
void
1576
axgbe_sysctl_init(struct xgbe_prv_data *pdata)
1577
{
1578
struct sysctl_ctx_list *clist;
1579
struct sysctl_oid_list *top;
1580
struct sysctl_oid *parent;
1581
struct sysctl_op *sys_op;
1582
1583
sys_op = malloc(sizeof(*sys_op), M_AXGBE, M_WAITOK | M_ZERO);
1584
pdata->sys_op = sys_op;
1585
1586
clist = device_get_sysctl_ctx(pdata->dev);
1587
parent = device_get_sysctl_tree(pdata->dev);
1588
top = SYSCTL_CHILDREN(parent);
1589
1590
/* Set defaults */
1591
pdata->sysctl_xgmac_reg = 0;
1592
pdata->sysctl_xpcs_mmd = 1;
1593
pdata->sysctl_xpcs_reg = 0;
1594
pdata->link_workaround = 1;
1595
pdata->tx_pause = 1;
1596
pdata->rx_pause = 1;
1597
pdata->enable_rss = 1;
1598
1599
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "axgbe_debug_level", CTLFLAG_RWTUN,
1600
&pdata->debug_level, 0, "axgbe log level -- higher is verbose");
1601
1602
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "sph_enable",
1603
CTLFLAG_RDTUN, &pdata->sph_enable, 1,
1604
"shows the split header feature state (1 - enable, 0 - disable");
1605
1606
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "link_workaround",
1607
CTLFLAG_RWTUN, &pdata->link_workaround, 0,
1608
"enable the workaround for link issue in coming up");
1609
1610
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rss_enabled",
1611
CTLFLAG_RDTUN, &pdata->enable_rss, 1,
1612
"shows the RSS feature state (1 - enable, 0 - disable)");
1613
1614
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "tx_pause",
1615
CTLFLAG_RDTUN, &pdata->tx_pause, 1,
1616
"shows the Flow Control TX pause feature state (1 - enable, 0 - disable)");
1617
1618
SYSCTL_ADD_UINT(clist, top, OID_AUTO, "rx_pause",
1619
CTLFLAG_RDTUN, &pdata->rx_pause, 1,
1620
"shows the Flow Control RX pause feature state (1 - enable, 0 - disable)");
1621
1622
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register",
1623
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1624
pdata, 0, sysctl_xgmac_reg_addr_handler, "IU",
1625
"xgmac register addr");
1626
1627
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xgmac_register_value",
1628
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1629
pdata, 0, sysctl_xgmac_reg_value_handler, "IU",
1630
"xgmac register value");
1631
1632
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_mmd",
1633
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1634
pdata, 0, sysctl_xpcs_mmd_reg_handler, "IU", "xpcs mmd register");
1635
1636
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register",
1637
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1638
pdata, 0, sysctl_xpcs_reg_addr_handler, "IU", "xpcs register");
1639
1640
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xpcs_register_value",
1641
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1642
pdata, 0, sysctl_xpcs_reg_value_handler, "IU",
1643
"xpcs register value");
1644
1645
if (pdata->xpcs_res) {
1646
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register",
1647
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1648
pdata, 0, sysctl_xprop_reg_addr_handler,
1649
"IU", "xprop register");
1650
1651
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xprop_register_value",
1652
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1653
pdata, 0, sysctl_xprop_reg_value_handler,
1654
"IU", "xprop register value");
1655
}
1656
1657
if (pdata->xpcs_res) {
1658
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register",
1659
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1660
pdata, 0, sysctl_xi2c_reg_addr_handler,
1661
"IU", "xi2c register");
1662
1663
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "xi2c_register_value",
1664
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1665
pdata, 0, sysctl_xi2c_reg_value_handler,
1666
"IU", "xi2c register value");
1667
}
1668
1669
if (pdata->vdata->an_cdr_workaround) {
1670
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_workaround",
1671
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1672
pdata, 0, sysctl_an_cdr_wr_handler, "IU",
1673
"an cdr workaround");
1674
1675
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "an_cdr_track_early",
1676
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1677
pdata, 0, sysctl_an_cdr_track_early_handler, "IU",
1678
"an cdr track early");
1679
}
1680
1681
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "drv_info",
1682
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1683
pdata, 0, sysctl_get_drv_info_handler, "IU",
1684
"xgbe drv info");
1685
1686
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_info",
1687
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1688
pdata, 0, sysctl_get_link_info_handler, "IU",
1689
"xgbe link info");
1690
1691
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "coalesce_info",
1692
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1693
pdata, 0, sysctl_coalesce_handler, "IU",
1694
"xgbe coalesce info");
1695
1696
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "pauseparam_info",
1697
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1698
pdata, 0, sysctl_pauseparam_handler, "IU",
1699
"xgbe pauseparam info");
1700
1701
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "link_ksettings_info",
1702
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1703
pdata, 0, sysctl_link_ksettings_handler, "IU",
1704
"xgbe link_ksettings info");
1705
1706
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "ringparam_info",
1707
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1708
pdata, 0, sysctl_ringparam_handler, "IU",
1709
"xgbe ringparam info");
1710
1711
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "channels_info",
1712
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1713
pdata, 0, sysctl_channels_handler, "IU",
1714
"xgbe channels info");
1715
1716
SYSCTL_ADD_PROC(clist, top, OID_AUTO, "mac_stats",
1717
CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
1718
pdata, 0, sysctl_mac_stats_handler, "IU",
1719
"xgbe mac stats");
1720
}
1721
1722