Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/mac80211/debugfs.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* mac80211 debugfs for wireless PHYs
4
*
5
* Copyright 2007 Johannes Berg <[email protected]>
6
* Copyright 2013-2014 Intel Mobile Communications GmbH
7
* Copyright (C) 2018 - 2019, 2021-2025 Intel Corporation
8
*/
9
10
#include <linux/debugfs.h>
11
#include <linux/rtnetlink.h>
12
#include <linux/vmalloc.h>
13
#include "ieee80211_i.h"
14
#include "driver-ops.h"
15
#include "rate.h"
16
#include "debugfs.h"
17
18
#define DEBUGFS_FORMAT_BUFFER_SIZE 100
19
20
int mac80211_format_buffer(char __user *userbuf, size_t count,
21
loff_t *ppos, char *fmt, ...)
22
{
23
va_list args;
24
char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
25
int res;
26
27
va_start(args, fmt);
28
res = vscnprintf(buf, sizeof(buf), fmt, args);
29
va_end(args);
30
31
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
32
}
33
34
#define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \
35
static ssize_t name## _read(struct file *file, char __user *userbuf, \
36
size_t count, loff_t *ppos) \
37
{ \
38
struct ieee80211_local *local = file->private_data; \
39
\
40
return mac80211_format_buffer(userbuf, count, ppos, \
41
fmt "\n", ##value); \
42
}
43
44
#define DEBUGFS_READONLY_FILE_OPS(name) \
45
static const struct debugfs_short_fops name## _ops = { \
46
.read = name## _read, \
47
.llseek = generic_file_llseek, \
48
};
49
50
#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
51
DEBUGFS_READONLY_FILE_FN(name, fmt, value) \
52
DEBUGFS_READONLY_FILE_OPS(name)
53
54
#define DEBUGFS_ADD(name) \
55
debugfs_create_file(#name, 0400, phyd, local, &name## _ops)
56
57
#define DEBUGFS_ADD_MODE(name, mode) \
58
debugfs_create_file(#name, mode, phyd, local, &name## _ops);
59
60
61
DEBUGFS_READONLY_FILE(hw_conf, "%x",
62
local->hw.conf.flags);
63
DEBUGFS_READONLY_FILE(user_power, "%d",
64
local->user_power_level);
65
DEBUGFS_READONLY_FILE(power, "%d",
66
local->hw.conf.power_level);
67
DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
68
local->total_ps_buffered);
69
DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
70
local->wep_iv & 0xffffff);
71
DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
72
local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
73
74
static ssize_t aqm_read(struct file *file,
75
char __user *user_buf,
76
size_t count,
77
loff_t *ppos)
78
{
79
struct ieee80211_local *local = file->private_data;
80
struct fq *fq = &local->fq;
81
char buf[200];
82
int len = 0;
83
84
spin_lock_bh(&local->fq.lock);
85
rcu_read_lock();
86
87
len = scnprintf(buf, sizeof(buf),
88
"access name value\n"
89
"R fq_flows_cnt %u\n"
90
"R fq_backlog %u\n"
91
"R fq_overlimit %u\n"
92
"R fq_overmemory %u\n"
93
"R fq_collisions %u\n"
94
"R fq_memory_usage %u\n"
95
"RW fq_memory_limit %u\n"
96
"RW fq_limit %u\n"
97
"RW fq_quantum %u\n",
98
fq->flows_cnt,
99
fq->backlog,
100
fq->overmemory,
101
fq->overlimit,
102
fq->collisions,
103
fq->memory_usage,
104
fq->memory_limit,
105
fq->limit,
106
fq->quantum);
107
108
rcu_read_unlock();
109
spin_unlock_bh(&local->fq.lock);
110
111
return simple_read_from_buffer(user_buf, count, ppos,
112
buf, len);
113
}
114
115
static ssize_t aqm_write(struct file *file,
116
const char __user *user_buf,
117
size_t count,
118
loff_t *ppos)
119
{
120
struct ieee80211_local *local = file->private_data;
121
char buf[100];
122
123
if (count >= sizeof(buf))
124
return -EINVAL;
125
126
if (copy_from_user(buf, user_buf, count))
127
return -EFAULT;
128
129
if (count && buf[count - 1] == '\n')
130
buf[count - 1] = '\0';
131
else
132
buf[count] = '\0';
133
134
if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
135
return count;
136
else if (sscanf(buf, "fq_memory_limit %u", &local->fq.memory_limit) == 1)
137
return count;
138
else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
139
return count;
140
141
return -EINVAL;
142
}
143
144
static const struct debugfs_short_fops aqm_ops = {
145
.write = aqm_write,
146
.read = aqm_read,
147
.llseek = default_llseek,
148
};
149
150
static ssize_t airtime_flags_read(struct file *file,
151
char __user *user_buf,
152
size_t count, loff_t *ppos)
153
{
154
struct ieee80211_local *local = file->private_data;
155
char buf[128] = {}, *pos, *end;
156
157
pos = buf;
158
end = pos + sizeof(buf) - 1;
159
160
if (local->airtime_flags & AIRTIME_USE_TX)
161
pos += scnprintf(pos, end - pos, "AIRTIME_TX\t(%lx)\n",
162
AIRTIME_USE_TX);
163
if (local->airtime_flags & AIRTIME_USE_RX)
164
pos += scnprintf(pos, end - pos, "AIRTIME_RX\t(%lx)\n",
165
AIRTIME_USE_RX);
166
167
return simple_read_from_buffer(user_buf, count, ppos, buf,
168
strlen(buf));
169
}
170
171
static ssize_t airtime_flags_write(struct file *file,
172
const char __user *user_buf,
173
size_t count, loff_t *ppos)
174
{
175
struct ieee80211_local *local = file->private_data;
176
char buf[16];
177
178
if (count >= sizeof(buf))
179
return -EINVAL;
180
181
if (copy_from_user(buf, user_buf, count))
182
return -EFAULT;
183
184
if (count && buf[count - 1] == '\n')
185
buf[count - 1] = '\0';
186
else
187
buf[count] = '\0';
188
189
if (kstrtou16(buf, 0, &local->airtime_flags))
190
return -EINVAL;
191
192
return count;
193
}
194
195
static const struct debugfs_short_fops airtime_flags_ops = {
196
.write = airtime_flags_write,
197
.read = airtime_flags_read,
198
.llseek = default_llseek,
199
};
200
201
static ssize_t aql_pending_read(struct file *file,
202
char __user *user_buf,
203
size_t count, loff_t *ppos)
204
{
205
struct ieee80211_local *local = file->private_data;
206
char buf[400];
207
int len = 0;
208
209
len = scnprintf(buf, sizeof(buf),
210
"AC AQL pending\n"
211
"VO %u us\n"
212
"VI %u us\n"
213
"BE %u us\n"
214
"BK %u us\n"
215
"total %u us\n",
216
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
217
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
218
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
219
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
220
atomic_read(&local->aql_total_pending_airtime));
221
return simple_read_from_buffer(user_buf, count, ppos,
222
buf, len);
223
}
224
225
static const struct debugfs_short_fops aql_pending_ops = {
226
.read = aql_pending_read,
227
.llseek = default_llseek,
228
};
229
230
static ssize_t aql_txq_limit_read(struct file *file,
231
char __user *user_buf,
232
size_t count,
233
loff_t *ppos)
234
{
235
struct ieee80211_local *local = file->private_data;
236
char buf[400];
237
int len = 0;
238
239
len = scnprintf(buf, sizeof(buf),
240
"AC AQL limit low AQL limit high\n"
241
"VO %u %u\n"
242
"VI %u %u\n"
243
"BE %u %u\n"
244
"BK %u %u\n",
245
local->aql_txq_limit_low[IEEE80211_AC_VO],
246
local->aql_txq_limit_high[IEEE80211_AC_VO],
247
local->aql_txq_limit_low[IEEE80211_AC_VI],
248
local->aql_txq_limit_high[IEEE80211_AC_VI],
249
local->aql_txq_limit_low[IEEE80211_AC_BE],
250
local->aql_txq_limit_high[IEEE80211_AC_BE],
251
local->aql_txq_limit_low[IEEE80211_AC_BK],
252
local->aql_txq_limit_high[IEEE80211_AC_BK]);
253
return simple_read_from_buffer(user_buf, count, ppos,
254
buf, len);
255
}
256
257
static ssize_t aql_txq_limit_write(struct file *file,
258
const char __user *user_buf,
259
size_t count,
260
loff_t *ppos)
261
{
262
struct ieee80211_local *local = file->private_data;
263
char buf[100];
264
u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
265
struct sta_info *sta;
266
267
if (count >= sizeof(buf))
268
return -EINVAL;
269
270
if (copy_from_user(buf, user_buf, count))
271
return -EFAULT;
272
273
if (count && buf[count - 1] == '\n')
274
buf[count - 1] = '\0';
275
else
276
buf[count] = '\0';
277
278
if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
279
return -EINVAL;
280
281
if (ac >= IEEE80211_NUM_ACS)
282
return -EINVAL;
283
284
q_limit_low_old = local->aql_txq_limit_low[ac];
285
q_limit_high_old = local->aql_txq_limit_high[ac];
286
287
guard(wiphy)(local->hw.wiphy);
288
289
local->aql_txq_limit_low[ac] = q_limit_low;
290
local->aql_txq_limit_high[ac] = q_limit_high;
291
292
list_for_each_entry(sta, &local->sta_list, list) {
293
/* If a sta has customized queue limits, keep it */
294
if (sta->airtime[ac].aql_limit_low == q_limit_low_old &&
295
sta->airtime[ac].aql_limit_high == q_limit_high_old) {
296
sta->airtime[ac].aql_limit_low = q_limit_low;
297
sta->airtime[ac].aql_limit_high = q_limit_high;
298
}
299
}
300
301
return count;
302
}
303
304
static const struct debugfs_short_fops aql_txq_limit_ops = {
305
.write = aql_txq_limit_write,
306
.read = aql_txq_limit_read,
307
.llseek = default_llseek,
308
};
309
310
static ssize_t aql_enable_read(struct file *file, char __user *user_buf,
311
size_t count, loff_t *ppos)
312
{
313
char buf[3];
314
int len;
315
316
len = scnprintf(buf, sizeof(buf), "%d\n",
317
!static_key_false(&aql_disable.key));
318
319
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
320
}
321
322
static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
323
size_t count, loff_t *ppos)
324
{
325
bool aql_disabled = static_key_false(&aql_disable.key);
326
char buf[3];
327
size_t len;
328
329
if (count > sizeof(buf))
330
return -EINVAL;
331
332
if (copy_from_user(buf, user_buf, count))
333
return -EFAULT;
334
335
buf[sizeof(buf) - 1] = '\0';
336
len = strlen(buf);
337
if (len > 0 && buf[len - 1] == '\n')
338
buf[len - 1] = 0;
339
340
if (buf[0] == '0' && buf[1] == '\0') {
341
if (!aql_disabled)
342
static_branch_inc(&aql_disable);
343
} else if (buf[0] == '1' && buf[1] == '\0') {
344
if (aql_disabled)
345
static_branch_dec(&aql_disable);
346
} else {
347
return -EINVAL;
348
}
349
350
return count;
351
}
352
353
static const struct debugfs_short_fops aql_enable_ops = {
354
.write = aql_enable_write,
355
.read = aql_enable_read,
356
.llseek = default_llseek,
357
};
358
359
static ssize_t force_tx_status_read(struct file *file,
360
char __user *user_buf,
361
size_t count,
362
loff_t *ppos)
363
{
364
struct ieee80211_local *local = file->private_data;
365
char buf[3];
366
int len = 0;
367
368
len = scnprintf(buf, sizeof(buf), "%d\n", (int)local->force_tx_status);
369
370
return simple_read_from_buffer(user_buf, count, ppos,
371
buf, len);
372
}
373
374
static ssize_t force_tx_status_write(struct file *file,
375
const char __user *user_buf,
376
size_t count,
377
loff_t *ppos)
378
{
379
struct ieee80211_local *local = file->private_data;
380
char buf[3];
381
382
if (count >= sizeof(buf))
383
return -EINVAL;
384
385
if (copy_from_user(buf, user_buf, count))
386
return -EFAULT;
387
388
if (count && buf[count - 1] == '\n')
389
buf[count - 1] = '\0';
390
else
391
buf[count] = '\0';
392
393
if (buf[0] == '0' && buf[1] == '\0')
394
local->force_tx_status = 0;
395
else if (buf[0] == '1' && buf[1] == '\0')
396
local->force_tx_status = 1;
397
else
398
return -EINVAL;
399
400
return count;
401
}
402
403
static const struct debugfs_short_fops force_tx_status_ops = {
404
.write = force_tx_status_write,
405
.read = force_tx_status_read,
406
.llseek = default_llseek,
407
};
408
409
#ifdef CONFIG_PM
410
static ssize_t reset_write(struct file *file, const char __user *user_buf,
411
size_t count, loff_t *ppos)
412
{
413
struct ieee80211_local *local = file->private_data;
414
int ret;
415
416
rtnl_lock();
417
wiphy_lock(local->hw.wiphy);
418
__ieee80211_suspend(&local->hw, NULL);
419
ret = __ieee80211_resume(&local->hw);
420
wiphy_unlock(local->hw.wiphy);
421
422
if (ret)
423
cfg80211_shutdown_all_interfaces(local->hw.wiphy);
424
425
rtnl_unlock();
426
427
return count;
428
}
429
430
static const struct debugfs_short_fops reset_ops = {
431
.write = reset_write,
432
.llseek = noop_llseek,
433
};
434
#endif
435
436
static const char *hw_flag_names[] = {
437
#define FLAG(F) [IEEE80211_HW_##F] = #F
438
FLAG(HAS_RATE_CONTROL),
439
FLAG(RX_INCLUDES_FCS),
440
FLAG(HOST_BROADCAST_PS_BUFFERING),
441
FLAG(SIGNAL_UNSPEC),
442
FLAG(SIGNAL_DBM),
443
FLAG(NEED_DTIM_BEFORE_ASSOC),
444
FLAG(SPECTRUM_MGMT),
445
FLAG(AMPDU_AGGREGATION),
446
FLAG(SUPPORTS_PS),
447
FLAG(PS_NULLFUNC_STACK),
448
FLAG(SUPPORTS_DYNAMIC_PS),
449
FLAG(MFP_CAPABLE),
450
FLAG(WANT_MONITOR_VIF),
451
FLAG(NO_VIRTUAL_MONITOR),
452
FLAG(NO_AUTO_VIF),
453
FLAG(SW_CRYPTO_CONTROL),
454
FLAG(SUPPORT_FAST_XMIT),
455
FLAG(REPORTS_TX_ACK_STATUS),
456
FLAG(CONNECTION_MONITOR),
457
FLAG(QUEUE_CONTROL),
458
FLAG(SUPPORTS_PER_STA_GTK),
459
FLAG(AP_LINK_PS),
460
FLAG(TX_AMPDU_SETUP_IN_HW),
461
FLAG(SUPPORTS_RC_TABLE),
462
FLAG(P2P_DEV_ADDR_FOR_INTF),
463
FLAG(TIMING_BEACON_ONLY),
464
FLAG(SUPPORTS_HT_CCK_RATES),
465
FLAG(CHANCTX_STA_CSA),
466
FLAG(SUPPORTS_CLONED_SKBS),
467
FLAG(SINGLE_SCAN_ON_ALL_BANDS),
468
FLAG(TDLS_WIDER_BW),
469
FLAG(SUPPORTS_AMSDU_IN_AMPDU),
470
FLAG(BEACON_TX_STATUS),
471
FLAG(NEEDS_UNIQUE_STA_ADDR),
472
FLAG(SUPPORTS_REORDERING_BUFFER),
473
FLAG(USES_RSS),
474
FLAG(TX_AMSDU),
475
FLAG(TX_FRAG_LIST),
476
FLAG(REPORTS_LOW_ACK),
477
FLAG(SUPPORTS_TX_FRAG),
478
FLAG(SUPPORTS_TDLS_BUFFER_STA),
479
FLAG(DOESNT_SUPPORT_QOS_NDP),
480
FLAG(BUFF_MMPDU_TXQ),
481
FLAG(SUPPORTS_VHT_EXT_NSS_BW),
482
FLAG(STA_MMPDU_TXQ),
483
FLAG(TX_STATUS_NO_AMPDU_LEN),
484
FLAG(SUPPORTS_MULTI_BSSID),
485
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
486
FLAG(AMPDU_KEYBORDER_SUPPORT),
487
FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
488
FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
489
FLAG(SUPPORTS_CONC_MON_RX_DECAP),
490
FLAG(DETECTS_COLOR_COLLISION),
491
FLAG(MLO_MCAST_MULTI_LINK_TX),
492
FLAG(DISALLOW_PUNCTURING),
493
FLAG(HANDLES_QUIET_CSA),
494
FLAG(STRICT),
495
#undef FLAG
496
};
497
498
static ssize_t hwflags_read(struct file *file, char __user *user_buf,
499
size_t count, loff_t *ppos)
500
{
501
struct ieee80211_local *local = file->private_data;
502
size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
503
char *buf = kzalloc(bufsz, GFP_KERNEL);
504
char *pos = buf, *end = buf + bufsz - 1;
505
ssize_t rv;
506
int i;
507
508
if (!buf)
509
return -ENOMEM;
510
511
/* fail compilation if somebody adds or removes
512
* a flag without updating the name array above
513
*/
514
BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
515
516
for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
517
if (test_bit(i, local->hw.flags))
518
pos += scnprintf(pos, end - pos, "%s\n",
519
hw_flag_names[i]);
520
}
521
522
rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
523
kfree(buf);
524
return rv;
525
}
526
527
static ssize_t hwflags_write(struct file *file, const char __user *user_buf,
528
size_t count, loff_t *ppos)
529
{
530
struct ieee80211_local *local = file->private_data;
531
char buf[100];
532
int val;
533
534
if (count >= sizeof(buf))
535
return -EINVAL;
536
537
if (copy_from_user(buf, user_buf, count))
538
return -EFAULT;
539
540
if (count && buf[count - 1] == '\n')
541
buf[count - 1] = '\0';
542
else
543
buf[count] = '\0';
544
545
if (sscanf(buf, "strict=%d", &val) == 1) {
546
switch (val) {
547
case 0:
548
ieee80211_hw_set(&local->hw, STRICT);
549
return count;
550
case 1:
551
__clear_bit(IEEE80211_HW_STRICT, local->hw.flags);
552
return count;
553
default:
554
return -EINVAL;
555
}
556
}
557
558
return -EINVAL;
559
}
560
561
static const struct file_operations hwflags_ops = {
562
.open = simple_open,
563
.read = hwflags_read,
564
.write = hwflags_write,
565
};
566
567
static ssize_t misc_read(struct file *file, char __user *user_buf,
568
size_t count, loff_t *ppos)
569
{
570
struct ieee80211_local *local = file->private_data;
571
/* Max len of each line is 16 characters, plus 9 for 'pending:\n' */
572
size_t bufsz = IEEE80211_MAX_QUEUES * 16 + 9;
573
char *buf;
574
char *pos, *end;
575
ssize_t rv;
576
int i;
577
int ln;
578
579
buf = kzalloc(bufsz, GFP_KERNEL);
580
if (!buf)
581
return -ENOMEM;
582
583
pos = buf;
584
end = buf + bufsz - 1;
585
586
pos += scnprintf(pos, end - pos, "pending:\n");
587
588
for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
589
ln = skb_queue_len(&local->pending[i]);
590
pos += scnprintf(pos, end - pos, "[%i] %d\n",
591
i, ln);
592
}
593
594
rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
595
kfree(buf);
596
return rv;
597
}
598
599
static ssize_t queues_read(struct file *file, char __user *user_buf,
600
size_t count, loff_t *ppos)
601
{
602
struct ieee80211_local *local = file->private_data;
603
unsigned long flags;
604
char buf[IEEE80211_MAX_QUEUES * 20];
605
int q, res = 0;
606
607
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
608
for (q = 0; q < local->hw.queues; q++)
609
res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
610
local->queue_stop_reasons[q],
611
skb_queue_len(&local->pending[q]));
612
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
613
614
return simple_read_from_buffer(user_buf, count, ppos, buf, res);
615
}
616
617
DEBUGFS_READONLY_FILE_OPS(queues);
618
DEBUGFS_READONLY_FILE_OPS(misc);
619
620
/* statistics stuff */
621
622
static ssize_t format_devstat_counter(struct ieee80211_local *local,
623
char __user *userbuf,
624
size_t count, loff_t *ppos,
625
int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
626
int buflen))
627
{
628
struct ieee80211_low_level_stats stats;
629
char buf[20];
630
int res;
631
632
wiphy_lock(local->hw.wiphy);
633
res = drv_get_stats(local, &stats);
634
wiphy_unlock(local->hw.wiphy);
635
if (res)
636
return res;
637
res = printvalue(&stats, buf, sizeof(buf));
638
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
639
}
640
641
#define DEBUGFS_DEVSTATS_FILE(name) \
642
static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
643
char *buf, int buflen) \
644
{ \
645
return scnprintf(buf, buflen, "%u\n", stats->name); \
646
} \
647
static ssize_t stats_ ##name## _read(struct file *file, \
648
char __user *userbuf, \
649
size_t count, loff_t *ppos) \
650
{ \
651
return format_devstat_counter(file->private_data, \
652
userbuf, \
653
count, \
654
ppos, \
655
print_devstats_##name); \
656
} \
657
\
658
static const struct debugfs_short_fops stats_ ##name## _ops = { \
659
.read = stats_ ##name## _read, \
660
.llseek = generic_file_llseek, \
661
};
662
663
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
664
#define DEBUGFS_STATS_ADD(name) \
665
debugfs_create_u32(#name, 0400, statsd, &local->name);
666
#endif
667
#define DEBUGFS_DEVSTATS_ADD(name) \
668
debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
669
670
DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
671
DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
672
DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
673
DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
674
675
void debugfs_hw_add(struct ieee80211_local *local)
676
{
677
struct dentry *phyd = local->hw.wiphy->debugfsdir;
678
struct dentry *statsd;
679
680
if (!phyd)
681
return;
682
683
local->debugfs.keys = debugfs_create_dir("keys", phyd);
684
685
DEBUGFS_ADD(total_ps_buffered);
686
DEBUGFS_ADD(wep_iv);
687
DEBUGFS_ADD(rate_ctrl_alg);
688
DEBUGFS_ADD(queues);
689
DEBUGFS_ADD(misc);
690
#ifdef CONFIG_PM
691
DEBUGFS_ADD_MODE(reset, 0200);
692
#endif
693
DEBUGFS_ADD_MODE(hwflags, 0600);
694
DEBUGFS_ADD(user_power);
695
DEBUGFS_ADD(power);
696
DEBUGFS_ADD(hw_conf);
697
DEBUGFS_ADD_MODE(force_tx_status, 0600);
698
DEBUGFS_ADD_MODE(aql_enable, 0600);
699
DEBUGFS_ADD(aql_pending);
700
DEBUGFS_ADD_MODE(aqm, 0600);
701
702
DEBUGFS_ADD_MODE(airtime_flags, 0600);
703
704
DEBUGFS_ADD(aql_txq_limit);
705
debugfs_create_u32("aql_threshold", 0600,
706
phyd, &local->aql_threshold);
707
708
statsd = debugfs_create_dir("statistics", phyd);
709
710
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
711
DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
712
DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
713
DEBUGFS_STATS_ADD(dot11FailedCount);
714
DEBUGFS_STATS_ADD(dot11RetryCount);
715
DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
716
DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
717
DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
718
DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
719
DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
720
DEBUGFS_STATS_ADD(tx_handlers_drop);
721
DEBUGFS_STATS_ADD(tx_handlers_queued);
722
DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
723
DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
724
DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
725
DEBUGFS_STATS_ADD(rx_handlers_drop);
726
DEBUGFS_STATS_ADD(rx_handlers_queued);
727
DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
728
DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
729
DEBUGFS_STATS_ADD(tx_expand_skb_head);
730
DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
731
DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
732
DEBUGFS_STATS_ADD(rx_handlers_fragments);
733
DEBUGFS_STATS_ADD(tx_status_drop);
734
#endif
735
DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
736
DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
737
DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
738
DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
739
}
740
741