xref: /kernel/linux/linux-5.10/net/mac80211/debugfs.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * mac80211 debugfs for wireless PHYs
4 *
5 * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014  Intel Mobile Communications GmbH
7 * Copyright (C) 2018 - 2019 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
20int 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...)			\
35static 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)			\
45static const struct file_operations name## _ops = {			\
46	.read = name## _read,						\
47	.open = simple_open,						\
48	.llseek = generic_file_llseek,					\
49};
50
51#define DEBUGFS_READONLY_FILE(name, fmt, value...)		\
52	DEBUGFS_READONLY_FILE_FN(name, fmt, value)		\
53	DEBUGFS_READONLY_FILE_OPS(name)
54
55#define DEBUGFS_ADD(name)						\
56	debugfs_create_file(#name, 0400, phyd, local, &name## _ops);
57
58#define DEBUGFS_ADD_MODE(name, mode)					\
59	debugfs_create_file(#name, mode, phyd, local, &name## _ops);
60
61
62DEBUGFS_READONLY_FILE(hw_conf, "%x",
63		      local->hw.conf.flags);
64DEBUGFS_READONLY_FILE(user_power, "%d",
65		      local->user_power_level);
66DEBUGFS_READONLY_FILE(power, "%d",
67		      local->hw.conf.power_level);
68DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
69		      local->total_ps_buffered);
70DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
71		      local->wep_iv & 0xffffff);
72DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
73	local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
74
75static ssize_t aqm_read(struct file *file,
76			char __user *user_buf,
77			size_t count,
78			loff_t *ppos)
79{
80	struct ieee80211_local *local = file->private_data;
81	struct fq *fq = &local->fq;
82	char buf[200];
83	int len = 0;
84
85	spin_lock_bh(&local->fq.lock);
86	rcu_read_lock();
87
88	len = scnprintf(buf, sizeof(buf),
89			"access name value\n"
90			"R fq_flows_cnt %u\n"
91			"R fq_backlog %u\n"
92			"R fq_overlimit %u\n"
93			"R fq_overmemory %u\n"
94			"R fq_collisions %u\n"
95			"R fq_memory_usage %u\n"
96			"RW fq_memory_limit %u\n"
97			"RW fq_limit %u\n"
98			"RW fq_quantum %u\n",
99			fq->flows_cnt,
100			fq->backlog,
101			fq->overmemory,
102			fq->overlimit,
103			fq->collisions,
104			fq->memory_usage,
105			fq->memory_limit,
106			fq->limit,
107			fq->quantum);
108
109	rcu_read_unlock();
110	spin_unlock_bh(&local->fq.lock);
111
112	return simple_read_from_buffer(user_buf, count, ppos,
113				       buf, len);
114}
115
116static ssize_t aqm_write(struct file *file,
117			 const char __user *user_buf,
118			 size_t count,
119			 loff_t *ppos)
120{
121	struct ieee80211_local *local = file->private_data;
122	char buf[100];
123
124	if (count >= sizeof(buf))
125		return -EINVAL;
126
127	if (copy_from_user(buf, user_buf, count))
128		return -EFAULT;
129
130	if (count && buf[count - 1] == '\n')
131		buf[count - 1] = '\0';
132	else
133		buf[count] = '\0';
134
135	if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
136		return count;
137	else if (sscanf(buf, "fq_memory_limit %u", &local->fq.memory_limit) == 1)
138		return count;
139	else if (sscanf(buf, "fq_quantum %u", &local->fq.quantum) == 1)
140		return count;
141
142	return -EINVAL;
143}
144
145static const struct file_operations aqm_ops = {
146	.write = aqm_write,
147	.read = aqm_read,
148	.open = simple_open,
149	.llseek = default_llseek,
150};
151
152static ssize_t airtime_flags_read(struct file *file,
153				  char __user *user_buf,
154				  size_t count, loff_t *ppos)
155{
156	struct ieee80211_local *local = file->private_data;
157	char buf[128] = {}, *pos, *end;
158
159	pos = buf;
160	end = pos + sizeof(buf) - 1;
161
162	if (local->airtime_flags & AIRTIME_USE_TX)
163		pos += scnprintf(pos, end - pos, "AIRTIME_TX\t(%lx)\n",
164				 AIRTIME_USE_TX);
165	if (local->airtime_flags & AIRTIME_USE_RX)
166		pos += scnprintf(pos, end - pos, "AIRTIME_RX\t(%lx)\n",
167				 AIRTIME_USE_RX);
168
169	return simple_read_from_buffer(user_buf, count, ppos, buf,
170				       strlen(buf));
171}
172
173static ssize_t airtime_flags_write(struct file *file,
174				   const char __user *user_buf,
175				   size_t count, loff_t *ppos)
176{
177	struct ieee80211_local *local = file->private_data;
178	char buf[16];
179
180	if (count >= sizeof(buf))
181		return -EINVAL;
182
183	if (copy_from_user(buf, user_buf, count))
184		return -EFAULT;
185
186	if (count && buf[count - 1] == '\n')
187		buf[count - 1] = '\0';
188	else
189		buf[count] = '\0';
190
191	if (kstrtou16(buf, 0, &local->airtime_flags))
192		return -EINVAL;
193
194	return count;
195}
196
197static const struct file_operations airtime_flags_ops = {
198	.write = airtime_flags_write,
199	.read = airtime_flags_read,
200	.open = simple_open,
201	.llseek = default_llseek,
202};
203
204static ssize_t aql_txq_limit_read(struct file *file,
205				  char __user *user_buf,
206				  size_t count,
207				  loff_t *ppos)
208{
209	struct ieee80211_local *local = file->private_data;
210	char buf[400];
211	int len = 0;
212
213	len = scnprintf(buf, sizeof(buf),
214			"AC	AQL limit low	AQL limit high\n"
215			"VO	%u		%u\n"
216			"VI	%u		%u\n"
217			"BE	%u		%u\n"
218			"BK	%u		%u\n",
219			local->aql_txq_limit_low[IEEE80211_AC_VO],
220			local->aql_txq_limit_high[IEEE80211_AC_VO],
221			local->aql_txq_limit_low[IEEE80211_AC_VI],
222			local->aql_txq_limit_high[IEEE80211_AC_VI],
223			local->aql_txq_limit_low[IEEE80211_AC_BE],
224			local->aql_txq_limit_high[IEEE80211_AC_BE],
225			local->aql_txq_limit_low[IEEE80211_AC_BK],
226			local->aql_txq_limit_high[IEEE80211_AC_BK]);
227	return simple_read_from_buffer(user_buf, count, ppos,
228				       buf, len);
229}
230
231static ssize_t aql_txq_limit_write(struct file *file,
232				   const char __user *user_buf,
233				   size_t count,
234				   loff_t *ppos)
235{
236	struct ieee80211_local *local = file->private_data;
237	char buf[100];
238	u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
239	struct sta_info *sta;
240
241	if (count >= sizeof(buf))
242		return -EINVAL;
243
244	if (copy_from_user(buf, user_buf, count))
245		return -EFAULT;
246
247	if (count && buf[count - 1] == '\n')
248		buf[count - 1] = '\0';
249	else
250		buf[count] = '\0';
251
252	if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
253		return -EINVAL;
254
255	if (ac >= IEEE80211_NUM_ACS)
256		return -EINVAL;
257
258	q_limit_low_old = local->aql_txq_limit_low[ac];
259	q_limit_high_old = local->aql_txq_limit_high[ac];
260
261	local->aql_txq_limit_low[ac] = q_limit_low;
262	local->aql_txq_limit_high[ac] = q_limit_high;
263
264	mutex_lock(&local->sta_mtx);
265	list_for_each_entry(sta, &local->sta_list, list) {
266		/* If a sta has customized queue limits, keep it */
267		if (sta->airtime[ac].aql_limit_low == q_limit_low_old &&
268		    sta->airtime[ac].aql_limit_high == q_limit_high_old) {
269			sta->airtime[ac].aql_limit_low = q_limit_low;
270			sta->airtime[ac].aql_limit_high = q_limit_high;
271		}
272	}
273	mutex_unlock(&local->sta_mtx);
274	return count;
275}
276
277static const struct file_operations aql_txq_limit_ops = {
278	.write = aql_txq_limit_write,
279	.read = aql_txq_limit_read,
280	.open = simple_open,
281	.llseek = default_llseek,
282};
283
284static ssize_t force_tx_status_read(struct file *file,
285				    char __user *user_buf,
286				    size_t count,
287				    loff_t *ppos)
288{
289	struct ieee80211_local *local = file->private_data;
290	char buf[3];
291	int len = 0;
292
293	len = scnprintf(buf, sizeof(buf), "%d\n", (int)local->force_tx_status);
294
295	return simple_read_from_buffer(user_buf, count, ppos,
296				       buf, len);
297}
298
299static ssize_t force_tx_status_write(struct file *file,
300				     const char __user *user_buf,
301				     size_t count,
302				     loff_t *ppos)
303{
304	struct ieee80211_local *local = file->private_data;
305	char buf[3];
306
307	if (count >= sizeof(buf))
308		return -EINVAL;
309
310	if (copy_from_user(buf, user_buf, count))
311		return -EFAULT;
312
313	if (count && buf[count - 1] == '\n')
314		buf[count - 1] = '\0';
315	else
316		buf[count] = '\0';
317
318	if (buf[0] == '0' && buf[1] == '\0')
319		local->force_tx_status = 0;
320	else if (buf[0] == '1' && buf[1] == '\0')
321		local->force_tx_status = 1;
322	else
323		return -EINVAL;
324
325	return count;
326}
327
328static const struct file_operations force_tx_status_ops = {
329	.write = force_tx_status_write,
330	.read = force_tx_status_read,
331	.open = simple_open,
332	.llseek = default_llseek,
333};
334
335#ifdef CONFIG_PM
336static ssize_t reset_write(struct file *file, const char __user *user_buf,
337			   size_t count, loff_t *ppos)
338{
339	struct ieee80211_local *local = file->private_data;
340
341	rtnl_lock();
342	__ieee80211_suspend(&local->hw, NULL);
343	__ieee80211_resume(&local->hw);
344	rtnl_unlock();
345
346	return count;
347}
348
349static const struct file_operations reset_ops = {
350	.write = reset_write,
351	.open = simple_open,
352	.llseek = noop_llseek,
353};
354#endif
355
356static const char *hw_flag_names[] = {
357#define FLAG(F)	[IEEE80211_HW_##F] = #F
358	FLAG(HAS_RATE_CONTROL),
359	FLAG(RX_INCLUDES_FCS),
360	FLAG(HOST_BROADCAST_PS_BUFFERING),
361	FLAG(SIGNAL_UNSPEC),
362	FLAG(SIGNAL_DBM),
363	FLAG(NEED_DTIM_BEFORE_ASSOC),
364	FLAG(SPECTRUM_MGMT),
365	FLAG(AMPDU_AGGREGATION),
366	FLAG(SUPPORTS_PS),
367	FLAG(PS_NULLFUNC_STACK),
368	FLAG(SUPPORTS_DYNAMIC_PS),
369	FLAG(MFP_CAPABLE),
370	FLAG(WANT_MONITOR_VIF),
371	FLAG(NO_AUTO_VIF),
372	FLAG(SW_CRYPTO_CONTROL),
373	FLAG(SUPPORT_FAST_XMIT),
374	FLAG(REPORTS_TX_ACK_STATUS),
375	FLAG(CONNECTION_MONITOR),
376	FLAG(QUEUE_CONTROL),
377	FLAG(SUPPORTS_PER_STA_GTK),
378	FLAG(AP_LINK_PS),
379	FLAG(TX_AMPDU_SETUP_IN_HW),
380	FLAG(SUPPORTS_RC_TABLE),
381	FLAG(P2P_DEV_ADDR_FOR_INTF),
382	FLAG(TIMING_BEACON_ONLY),
383	FLAG(SUPPORTS_HT_CCK_RATES),
384	FLAG(CHANCTX_STA_CSA),
385	FLAG(SUPPORTS_CLONED_SKBS),
386	FLAG(SINGLE_SCAN_ON_ALL_BANDS),
387	FLAG(TDLS_WIDER_BW),
388	FLAG(SUPPORTS_AMSDU_IN_AMPDU),
389	FLAG(BEACON_TX_STATUS),
390	FLAG(NEEDS_UNIQUE_STA_ADDR),
391	FLAG(SUPPORTS_REORDERING_BUFFER),
392	FLAG(USES_RSS),
393	FLAG(TX_AMSDU),
394	FLAG(TX_FRAG_LIST),
395	FLAG(REPORTS_LOW_ACK),
396	FLAG(SUPPORTS_TX_FRAG),
397	FLAG(SUPPORTS_TDLS_BUFFER_STA),
398	FLAG(DEAUTH_NEED_MGD_TX_PREP),
399	FLAG(DOESNT_SUPPORT_QOS_NDP),
400	FLAG(BUFF_MMPDU_TXQ),
401	FLAG(SUPPORTS_VHT_EXT_NSS_BW),
402	FLAG(STA_MMPDU_TXQ),
403	FLAG(TX_STATUS_NO_AMPDU_LEN),
404	FLAG(SUPPORTS_MULTI_BSSID),
405	FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
406	FLAG(AMPDU_KEYBORDER_SUPPORT),
407	FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
408#undef FLAG
409};
410
411static ssize_t hwflags_read(struct file *file, char __user *user_buf,
412			    size_t count, loff_t *ppos)
413{
414	struct ieee80211_local *local = file->private_data;
415	size_t bufsz = 30 * NUM_IEEE80211_HW_FLAGS;
416	char *buf = kzalloc(bufsz, GFP_KERNEL);
417	char *pos = buf, *end = buf + bufsz - 1;
418	ssize_t rv;
419	int i;
420
421	if (!buf)
422		return -ENOMEM;
423
424	/* fail compilation if somebody adds or removes
425	 * a flag without updating the name array above
426	 */
427	BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
428
429	for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
430		if (test_bit(i, local->hw.flags))
431			pos += scnprintf(pos, end - pos, "%s\n",
432					 hw_flag_names[i]);
433	}
434
435	rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
436	kfree(buf);
437	return rv;
438}
439
440static ssize_t misc_read(struct file *file, char __user *user_buf,
441			 size_t count, loff_t *ppos)
442{
443	struct ieee80211_local *local = file->private_data;
444	/* Max len of each line is 16 characters, plus 9 for 'pending:\n' */
445	size_t bufsz = IEEE80211_MAX_QUEUES * 16 + 9;
446	char *buf;
447	char *pos, *end;
448	ssize_t rv;
449	int i;
450	int ln;
451
452	buf = kzalloc(bufsz, GFP_KERNEL);
453	if (!buf)
454		return -ENOMEM;
455
456	pos = buf;
457	end = buf + bufsz - 1;
458
459	pos += scnprintf(pos, end - pos, "pending:\n");
460
461	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
462		ln = skb_queue_len(&local->pending[i]);
463		pos += scnprintf(pos, end - pos, "[%i] %d\n",
464				 i, ln);
465	}
466
467	rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
468	kfree(buf);
469	return rv;
470}
471
472static ssize_t queues_read(struct file *file, char __user *user_buf,
473			   size_t count, loff_t *ppos)
474{
475	struct ieee80211_local *local = file->private_data;
476	unsigned long flags;
477	char buf[IEEE80211_MAX_QUEUES * 20];
478	int q, res = 0;
479
480	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
481	for (q = 0; q < local->hw.queues; q++)
482		res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
483				local->queue_stop_reasons[q],
484				skb_queue_len(&local->pending[q]));
485	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
486
487	return simple_read_from_buffer(user_buf, count, ppos, buf, res);
488}
489
490DEBUGFS_READONLY_FILE_OPS(hwflags);
491DEBUGFS_READONLY_FILE_OPS(queues);
492DEBUGFS_READONLY_FILE_OPS(misc);
493
494/* statistics stuff */
495
496static ssize_t format_devstat_counter(struct ieee80211_local *local,
497	char __user *userbuf,
498	size_t count, loff_t *ppos,
499	int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
500			  int buflen))
501{
502	struct ieee80211_low_level_stats stats;
503	char buf[20];
504	int res;
505
506	rtnl_lock();
507	res = drv_get_stats(local, &stats);
508	rtnl_unlock();
509	if (res)
510		return res;
511	res = printvalue(&stats, buf, sizeof(buf));
512	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
513}
514
515#define DEBUGFS_DEVSTATS_FILE(name)					\
516static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
517				 char *buf, int buflen)			\
518{									\
519	return scnprintf(buf, buflen, "%u\n", stats->name);		\
520}									\
521static ssize_t stats_ ##name## _read(struct file *file,			\
522				     char __user *userbuf,		\
523				     size_t count, loff_t *ppos)	\
524{									\
525	return format_devstat_counter(file->private_data,		\
526				      userbuf,				\
527				      count,				\
528				      ppos,				\
529				      print_devstats_##name);		\
530}									\
531									\
532static const struct file_operations stats_ ##name## _ops = {		\
533	.read = stats_ ##name## _read,					\
534	.open = simple_open,						\
535	.llseek = generic_file_llseek,					\
536};
537
538#define DEBUGFS_STATS_ADD(name)					\
539	debugfs_create_u32(#name, 0400, statsd, &local->name);
540#define DEBUGFS_DEVSTATS_ADD(name)					\
541	debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops);
542
543DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
544DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
545DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
546DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
547
548void debugfs_hw_add(struct ieee80211_local *local)
549{
550	struct dentry *phyd = local->hw.wiphy->debugfsdir;
551	struct dentry *statsd;
552
553	if (!phyd)
554		return;
555
556	local->debugfs.keys = debugfs_create_dir("keys", phyd);
557
558	DEBUGFS_ADD(total_ps_buffered);
559	DEBUGFS_ADD(wep_iv);
560	DEBUGFS_ADD(rate_ctrl_alg);
561	DEBUGFS_ADD(queues);
562	DEBUGFS_ADD(misc);
563#ifdef CONFIG_PM
564	DEBUGFS_ADD_MODE(reset, 0200);
565#endif
566	DEBUGFS_ADD(hwflags);
567	DEBUGFS_ADD(user_power);
568	DEBUGFS_ADD(power);
569	DEBUGFS_ADD(hw_conf);
570	DEBUGFS_ADD_MODE(force_tx_status, 0600);
571
572	if (local->ops->wake_tx_queue)
573		DEBUGFS_ADD_MODE(aqm, 0600);
574
575	DEBUGFS_ADD_MODE(airtime_flags, 0600);
576
577	DEBUGFS_ADD(aql_txq_limit);
578	debugfs_create_u32("aql_threshold", 0600,
579			   phyd, &local->aql_threshold);
580
581	statsd = debugfs_create_dir("statistics", phyd);
582
583	/* if the dir failed, don't put all the other things into the root! */
584	if (!statsd)
585		return;
586
587#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
588	DEBUGFS_STATS_ADD(dot11TransmittedFragmentCount);
589	DEBUGFS_STATS_ADD(dot11MulticastTransmittedFrameCount);
590	DEBUGFS_STATS_ADD(dot11FailedCount);
591	DEBUGFS_STATS_ADD(dot11RetryCount);
592	DEBUGFS_STATS_ADD(dot11MultipleRetryCount);
593	DEBUGFS_STATS_ADD(dot11FrameDuplicateCount);
594	DEBUGFS_STATS_ADD(dot11ReceivedFragmentCount);
595	DEBUGFS_STATS_ADD(dot11MulticastReceivedFrameCount);
596	DEBUGFS_STATS_ADD(dot11TransmittedFrameCount);
597	DEBUGFS_STATS_ADD(tx_handlers_drop);
598	DEBUGFS_STATS_ADD(tx_handlers_queued);
599	DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
600	DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
601	DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
602	DEBUGFS_STATS_ADD(rx_handlers_drop);
603	DEBUGFS_STATS_ADD(rx_handlers_queued);
604	DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
605	DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
606	DEBUGFS_STATS_ADD(tx_expand_skb_head);
607	DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
608	DEBUGFS_STATS_ADD(rx_expand_skb_head_defrag);
609	DEBUGFS_STATS_ADD(rx_handlers_fragments);
610	DEBUGFS_STATS_ADD(tx_status_drop);
611#endif
612	DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount);
613	DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
614	DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
615	DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
616}
617