1// SPDX-License-Identifier: BSD-3-Clause-Clear
2/*
3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/vmalloc.h>
7
8#include "debugfs.h"
9
10#include "core.h"
11#include "debug.h"
12#include "wmi.h"
13#include "hal_rx.h"
14#include "dp_tx.h"
15#include "debugfs_htt_stats.h"
16#include "peer.h"
17#include "hif.h"
18
19static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
20	"REO2SW1_RING",
21	"REO2SW2_RING",
22	"REO2SW3_RING",
23	"REO2SW4_RING",
24	"WBM2REO_LINK_RING",
25	"REO2TCL_RING",
26	"REO2FW_RING",
27	"RELEASE_RING",
28	"PPE_RELEASE_RING",
29	"TCL2TQM_RING",
30	"TQM_RELEASE_RING",
31	"REO_RELEASE_RING",
32	"WBM2SW0_RELEASE_RING",
33	"WBM2SW1_RELEASE_RING",
34	"WBM2SW2_RELEASE_RING",
35	"WBM2SW3_RELEASE_RING",
36	"REO_CMD_RING",
37	"REO_STATUS_RING",
38};
39
40static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
41	"FW2RXDMA_BUF_RING",
42	"FW2RXDMA_STATUS_RING",
43	"FW2RXDMA_LINK_RING",
44	"SW2RXDMA_BUF_RING",
45	"WBM2RXDMA_LINK_RING",
46	"RXDMA2FW_RING",
47	"RXDMA2SW_RING",
48	"RXDMA2RELEASE_RING",
49	"RXDMA2REO_RING",
50	"MONITOR_STATUS_RING",
51	"MONITOR_BUF_RING",
52	"MONITOR_DESC_RING",
53	"MONITOR_DEST_RING",
54};
55
56void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
57				     enum wmi_direct_buffer_module id,
58				     enum ath11k_dbg_dbr_event event,
59				     struct hal_srng *srng)
60{
61	struct ath11k_debug_dbr *dbr_debug;
62	struct ath11k_dbg_dbr_data *dbr_data;
63	struct ath11k_dbg_dbr_entry *entry;
64
65	if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
66		return;
67
68	dbr_debug = ar->debug.dbr_debug[id];
69	if (!dbr_debug)
70		return;
71
72	if (!dbr_debug->dbr_debug_enabled)
73		return;
74
75	dbr_data = &dbr_debug->dbr_dbg_data;
76
77	spin_lock_bh(&dbr_data->lock);
78
79	if (dbr_data->entries) {
80		entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
81		entry->hp = srng->u.src_ring.hp;
82		entry->tp = *srng->u.src_ring.tp_addr;
83		entry->timestamp = jiffies;
84		entry->event = event;
85
86		dbr_data->dbr_debug_idx++;
87		if (dbr_data->dbr_debug_idx ==
88		    dbr_data->num_ring_debug_entries)
89			dbr_data->dbr_debug_idx = 0;
90	}
91
92	spin_unlock_bh(&dbr_data->lock);
93}
94
95static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
96{
97	spin_lock_bh(&ar->data_lock);
98	ar->fw_stats_done = false;
99	ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
100	ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
101	spin_unlock_bh(&ar->data_lock);
102}
103
104void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
105{
106	struct ath11k_base *ab = ar->ab;
107	struct ath11k_pdev *pdev;
108	bool is_end;
109	static unsigned int num_vdev, num_bcn;
110	size_t total_vdevs_started = 0;
111	int i;
112
113	/* WMI_REQUEST_PDEV_STAT request has been already processed */
114
115	if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
116		ar->fw_stats_done = true;
117		return;
118	}
119
120	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
121		if (list_empty(&stats->vdevs)) {
122			ath11k_warn(ab, "empty vdev stats");
123			return;
124		}
125		/* FW sends all the active VDEV stats irrespective of PDEV,
126		 * hence limit until the count of all VDEVs started
127		 */
128		for (i = 0; i < ab->num_radios; i++) {
129			pdev = rcu_dereference(ab->pdevs_active[i]);
130			if (pdev && pdev->ar)
131				total_vdevs_started += ar->num_started_vdevs;
132		}
133
134		is_end = ((++num_vdev) == total_vdevs_started);
135
136		list_splice_tail_init(&stats->vdevs,
137				      &ar->fw_stats.vdevs);
138
139		if (is_end) {
140			ar->fw_stats_done = true;
141			num_vdev = 0;
142		}
143		return;
144	}
145
146	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
147		if (list_empty(&stats->bcn)) {
148			ath11k_warn(ab, "empty bcn stats");
149			return;
150		}
151		/* Mark end until we reached the count of all started VDEVs
152		 * within the PDEV
153		 */
154		is_end = ((++num_bcn) == ar->num_started_vdevs);
155
156		list_splice_tail_init(&stats->bcn,
157				      &ar->fw_stats.bcn);
158
159		if (is_end) {
160			ar->fw_stats_done = true;
161			num_bcn = 0;
162		}
163	}
164}
165
166static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
167					   struct stats_request_params *req_param)
168{
169	struct ath11k_base *ab = ar->ab;
170	unsigned long timeout, time_left;
171	int ret;
172
173	lockdep_assert_held(&ar->conf_mutex);
174
175	/* FW stats can get split when exceeding the stats data buffer limit.
176	 * In that case, since there is no end marking for the back-to-back
177	 * received 'update stats' event, we keep a 3 seconds timeout in case,
178	 * fw_stats_done is not marked yet
179	 */
180	timeout = jiffies + msecs_to_jiffies(3 * 1000);
181
182	ath11k_debugfs_fw_stats_reset(ar);
183
184	reinit_completion(&ar->fw_stats_complete);
185
186	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
187
188	if (ret) {
189		ath11k_warn(ab, "could not request fw stats (%d)\n",
190			    ret);
191		return ret;
192	}
193
194	time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
195
196	if (!time_left)
197		return -ETIMEDOUT;
198
199	for (;;) {
200		if (time_after(jiffies, timeout))
201			break;
202
203		spin_lock_bh(&ar->data_lock);
204		if (ar->fw_stats_done) {
205			spin_unlock_bh(&ar->data_lock);
206			break;
207		}
208		spin_unlock_bh(&ar->data_lock);
209	}
210	return 0;
211}
212
213int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
214				u32 vdev_id, u32 stats_id)
215{
216	struct ath11k_base *ab = ar->ab;
217	struct stats_request_params req_param;
218	int ret;
219
220	mutex_lock(&ar->conf_mutex);
221
222	if (ar->state != ATH11K_STATE_ON) {
223		ret = -ENETDOWN;
224		goto err_unlock;
225	}
226
227	req_param.pdev_id = pdev_id;
228	req_param.vdev_id = vdev_id;
229	req_param.stats_id = stats_id;
230
231	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
232	if (ret)
233		ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
234
235	ath11k_dbg(ab, ATH11K_DBG_WMI,
236		   "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
237		   pdev_id, vdev_id, stats_id);
238
239err_unlock:
240	mutex_unlock(&ar->conf_mutex);
241
242	return ret;
243}
244
245static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
246{
247	struct ath11k *ar = inode->i_private;
248	struct ath11k_base *ab = ar->ab;
249	struct stats_request_params req_param;
250	void *buf = NULL;
251	int ret;
252
253	mutex_lock(&ar->conf_mutex);
254
255	if (ar->state != ATH11K_STATE_ON) {
256		ret = -ENETDOWN;
257		goto err_unlock;
258	}
259
260	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
261	if (!buf) {
262		ret = -ENOMEM;
263		goto err_unlock;
264	}
265
266	req_param.pdev_id = ar->pdev->pdev_id;
267	req_param.vdev_id = 0;
268	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
269
270	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
271	if (ret) {
272		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
273		goto err_free;
274	}
275
276	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
277
278	file->private_data = buf;
279
280	mutex_unlock(&ar->conf_mutex);
281	return 0;
282
283err_free:
284	vfree(buf);
285
286err_unlock:
287	mutex_unlock(&ar->conf_mutex);
288	return ret;
289}
290
291static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
292{
293	vfree(file->private_data);
294
295	return 0;
296}
297
298static ssize_t ath11k_read_pdev_stats(struct file *file,
299				      char __user *user_buf,
300				      size_t count, loff_t *ppos)
301{
302	const char *buf = file->private_data;
303	size_t len = strlen(buf);
304
305	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
306}
307
308static const struct file_operations fops_pdev_stats = {
309	.open = ath11k_open_pdev_stats,
310	.release = ath11k_release_pdev_stats,
311	.read = ath11k_read_pdev_stats,
312	.owner = THIS_MODULE,
313	.llseek = default_llseek,
314};
315
316static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
317{
318	struct ath11k *ar = inode->i_private;
319	struct stats_request_params req_param;
320	void *buf = NULL;
321	int ret;
322
323	mutex_lock(&ar->conf_mutex);
324
325	if (ar->state != ATH11K_STATE_ON) {
326		ret = -ENETDOWN;
327		goto err_unlock;
328	}
329
330	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
331	if (!buf) {
332		ret = -ENOMEM;
333		goto err_unlock;
334	}
335
336	req_param.pdev_id = ar->pdev->pdev_id;
337	/* VDEV stats is always sent for all active VDEVs from FW */
338	req_param.vdev_id = 0;
339	req_param.stats_id = WMI_REQUEST_VDEV_STAT;
340
341	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
342	if (ret) {
343		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
344		goto err_free;
345	}
346
347	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
348
349	file->private_data = buf;
350
351	mutex_unlock(&ar->conf_mutex);
352	return 0;
353
354err_free:
355	vfree(buf);
356
357err_unlock:
358	mutex_unlock(&ar->conf_mutex);
359	return ret;
360}
361
362static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
363{
364	vfree(file->private_data);
365
366	return 0;
367}
368
369static ssize_t ath11k_read_vdev_stats(struct file *file,
370				      char __user *user_buf,
371				      size_t count, loff_t *ppos)
372{
373	const char *buf = file->private_data;
374	size_t len = strlen(buf);
375
376	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
377}
378
379static const struct file_operations fops_vdev_stats = {
380	.open = ath11k_open_vdev_stats,
381	.release = ath11k_release_vdev_stats,
382	.read = ath11k_read_vdev_stats,
383	.owner = THIS_MODULE,
384	.llseek = default_llseek,
385};
386
387static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
388{
389	struct ath11k *ar = inode->i_private;
390	struct ath11k_vif *arvif;
391	struct stats_request_params req_param;
392	void *buf = NULL;
393	int ret;
394
395	mutex_lock(&ar->conf_mutex);
396
397	if (ar->state != ATH11K_STATE_ON) {
398		ret = -ENETDOWN;
399		goto err_unlock;
400	}
401
402	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
403	if (!buf) {
404		ret = -ENOMEM;
405		goto err_unlock;
406	}
407
408	req_param.stats_id = WMI_REQUEST_BCN_STAT;
409	req_param.pdev_id = ar->pdev->pdev_id;
410
411	/* loop all active VDEVs for bcn stats */
412	list_for_each_entry(arvif, &ar->arvifs, list) {
413		if (!arvif->is_up)
414			continue;
415
416		req_param.vdev_id = arvif->vdev_id;
417		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
418		if (ret) {
419			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
420			goto err_free;
421		}
422	}
423
424	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
425
426	/* since beacon stats request is looped for all active VDEVs, saved fw
427	 * stats is not freed for each request until done for all active VDEVs
428	 */
429	spin_lock_bh(&ar->data_lock);
430	ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
431	spin_unlock_bh(&ar->data_lock);
432
433	file->private_data = buf;
434
435	mutex_unlock(&ar->conf_mutex);
436	return 0;
437
438err_free:
439	vfree(buf);
440
441err_unlock:
442	mutex_unlock(&ar->conf_mutex);
443	return ret;
444}
445
446static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
447{
448	vfree(file->private_data);
449
450	return 0;
451}
452
453static ssize_t ath11k_read_bcn_stats(struct file *file,
454				     char __user *user_buf,
455				     size_t count, loff_t *ppos)
456{
457	const char *buf = file->private_data;
458	size_t len = strlen(buf);
459
460	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
461}
462
463static const struct file_operations fops_bcn_stats = {
464	.open = ath11k_open_bcn_stats,
465	.release = ath11k_release_bcn_stats,
466	.read = ath11k_read_bcn_stats,
467	.owner = THIS_MODULE,
468	.llseek = default_llseek,
469};
470
471static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
472					     char __user *user_buf,
473					     size_t count, loff_t *ppos)
474{
475	const char buf[] =
476		"To simulate firmware crash write one of the keywords to this file:\n"
477		"`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
478		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
479
480	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
481}
482
483/* Simulate firmware crash:
484 * 'soft': Call wmi command causing firmware hang. This firmware hang is
485 * recoverable by warm firmware reset.
486 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
487 * vdev id. This is hard firmware crash because it is recoverable only by cold
488 * firmware reset.
489 */
490static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
491					      const char __user *user_buf,
492					      size_t count, loff_t *ppos)
493{
494	struct ath11k_base *ab = file->private_data;
495	struct ath11k_pdev *pdev;
496	struct ath11k *ar = ab->pdevs[0].ar;
497	char buf[32] = {0};
498	ssize_t rc;
499	int i, ret, radioup = 0;
500
501	for (i = 0; i < ab->num_radios; i++) {
502		pdev = &ab->pdevs[i];
503		ar = pdev->ar;
504		if (ar && ar->state == ATH11K_STATE_ON) {
505			radioup = 1;
506			break;
507		}
508	}
509	/* filter partial writes and invalid commands */
510	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
511		return -EINVAL;
512
513	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
514	if (rc < 0)
515		return rc;
516
517	/* drop the possible '\n' from the end */
518	if (buf[*ppos - 1] == '\n')
519		buf[*ppos - 1] = '\0';
520
521	if (radioup == 0) {
522		ret = -ENETDOWN;
523		goto exit;
524	}
525
526	if (!strcmp(buf, "assert")) {
527		ath11k_info(ab, "simulating firmware assert crash\n");
528		ret = ath11k_wmi_force_fw_hang_cmd(ar,
529						   ATH11K_WMI_FW_HANG_ASSERT_TYPE,
530						   ATH11K_WMI_FW_HANG_DELAY);
531	} else if (!strcmp(buf, "hw-restart")) {
532		ath11k_info(ab, "user requested hw restart\n");
533		queue_work(ab->workqueue_aux, &ab->reset_work);
534		ret = 0;
535	} else {
536		ret = -EINVAL;
537		goto exit;
538	}
539
540	if (ret) {
541		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
542		goto exit;
543	}
544
545	ret = count;
546
547exit:
548	return ret;
549}
550
551static const struct file_operations fops_simulate_fw_crash = {
552	.read = ath11k_read_simulate_fw_crash,
553	.write = ath11k_write_simulate_fw_crash,
554	.open = simple_open,
555	.owner = THIS_MODULE,
556	.llseek = default_llseek,
557};
558
559static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
560						 const char __user *ubuf,
561						 size_t count, loff_t *ppos)
562{
563	struct ath11k *ar = file->private_data;
564	u32 filter;
565	int ret;
566
567	if (kstrtouint_from_user(ubuf, count, 0, &filter))
568		return -EINVAL;
569
570	mutex_lock(&ar->conf_mutex);
571
572	if (ar->state != ATH11K_STATE_ON) {
573		ret = -ENETDOWN;
574		goto out;
575	}
576
577	if (filter == ar->debug.extd_tx_stats) {
578		ret = count;
579		goto out;
580	}
581
582	ar->debug.extd_tx_stats = filter;
583	ret = count;
584
585out:
586	mutex_unlock(&ar->conf_mutex);
587	return ret;
588}
589
590static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
591						char __user *ubuf,
592						size_t count, loff_t *ppos)
593
594{
595	char buf[32] = {0};
596	struct ath11k *ar = file->private_data;
597	int len = 0;
598
599	mutex_lock(&ar->conf_mutex);
600	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
601			ar->debug.extd_tx_stats);
602	mutex_unlock(&ar->conf_mutex);
603
604	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
605}
606
607static const struct file_operations fops_extd_tx_stats = {
608	.read = ath11k_read_enable_extd_tx_stats,
609	.write = ath11k_write_enable_extd_tx_stats,
610	.open = simple_open
611};
612
613static ssize_t ath11k_write_extd_rx_stats(struct file *file,
614					  const char __user *ubuf,
615					  size_t count, loff_t *ppos)
616{
617	struct ath11k *ar = file->private_data;
618	struct ath11k_base *ab = ar->ab;
619	struct htt_rx_ring_tlv_filter tlv_filter = {0};
620	u32 enable, rx_filter = 0, ring_id;
621	int i;
622	int ret;
623
624	if (kstrtouint_from_user(ubuf, count, 0, &enable))
625		return -EINVAL;
626
627	mutex_lock(&ar->conf_mutex);
628
629	if (ar->state != ATH11K_STATE_ON) {
630		ret = -ENETDOWN;
631		goto exit;
632	}
633
634	if (enable > 1) {
635		ret = -EINVAL;
636		goto exit;
637	}
638
639	if (enable == ar->debug.extd_rx_stats) {
640		ret = count;
641		goto exit;
642	}
643
644	if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
645		ar->debug.extd_rx_stats = enable;
646		ret = count;
647		goto exit;
648	}
649
650	if (enable) {
651		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
652		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
653		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
654		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
655		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
656		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
657
658		tlv_filter.rx_filter = rx_filter;
659		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
660		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
661		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
662		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
663			HTT_RX_FP_DATA_FILTER_FLASG3;
664	} else {
665		tlv_filter = ath11k_mac_mon_status_filter_default;
666	}
667
668	ar->debug.rx_filter = tlv_filter.rx_filter;
669
670	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
671		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
672		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
673						       HAL_RXDMA_MONITOR_STATUS,
674						       DP_RX_BUFFER_SIZE, &tlv_filter);
675
676		if (ret) {
677			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
678			goto exit;
679		}
680	}
681
682	ar->debug.extd_rx_stats = enable;
683	ret = count;
684exit:
685	mutex_unlock(&ar->conf_mutex);
686	return ret;
687}
688
689static ssize_t ath11k_read_extd_rx_stats(struct file *file,
690					 char __user *ubuf,
691					 size_t count, loff_t *ppos)
692{
693	struct ath11k *ar = file->private_data;
694	char buf[32];
695	int len = 0;
696
697	mutex_lock(&ar->conf_mutex);
698	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
699			ar->debug.extd_rx_stats);
700	mutex_unlock(&ar->conf_mutex);
701
702	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
703}
704
705static const struct file_operations fops_extd_rx_stats = {
706	.read = ath11k_read_extd_rx_stats,
707	.write = ath11k_write_extd_rx_stats,
708	.open = simple_open,
709};
710
711static int ath11k_fill_bp_stats(struct ath11k_base *ab,
712				struct ath11k_bp_stats *bp_stats,
713				char *buf, int len, int size)
714{
715	lockdep_assert_held(&ab->base_lock);
716
717	len += scnprintf(buf + len, size - len, "count: %u\n",
718			 bp_stats->count);
719	len += scnprintf(buf + len, size - len, "hp: %u\n",
720			 bp_stats->hp);
721	len += scnprintf(buf + len, size - len, "tp: %u\n",
722			 bp_stats->tp);
723	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
724			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
725	return len;
726}
727
728static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
729						     char *buf, int size)
730{
731	struct ath11k_bp_stats *bp_stats;
732	bool stats_rxd = false;
733	u8 i, pdev_idx;
734	int len = 0;
735
736	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
737	len += scnprintf(buf + len, size - len, "==================\n");
738
739	spin_lock_bh(&ab->base_lock);
740	for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
741		bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
742
743		if (!bp_stats->count)
744			continue;
745
746		len += scnprintf(buf + len, size - len, "Ring: %s\n",
747				 htt_bp_umac_ring[i]);
748		len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
749		stats_rxd = true;
750	}
751
752	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
753		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
754			bp_stats =
755				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
756
757			if (!bp_stats->count)
758				continue;
759
760			len += scnprintf(buf + len, size - len, "Ring: %s\n",
761					 htt_bp_lmac_ring[i]);
762			len += scnprintf(buf + len, size - len, "pdev: %d\n",
763					 pdev_idx);
764			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
765			stats_rxd = true;
766		}
767	}
768	spin_unlock_bh(&ab->base_lock);
769
770	if (!stats_rxd)
771		len += scnprintf(buf + len, size - len,
772				 "No Ring Backpressure stats received\n\n");
773
774	return len;
775}
776
777static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
778						char __user *user_buf,
779						size_t count, loff_t *ppos)
780{
781	struct ath11k_base *ab = file->private_data;
782	struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
783	int len = 0, i, retval;
784	const int size = 4096;
785	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
786			"Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
787			"Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
788			"AMSDU parse", "SA timeout", "DA timeout",
789			"Flow timeout", "Flush req"};
790	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
791			"Desc addr zero", "Desc inval", "AMPDU in non BA",
792			"Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
793			"Frame OOR", "BAR OOR", "No BA session",
794			"Frame SN equal SSN", "PN check fail", "2k err",
795			"PN err", "Desc blocked"};
796
797	char *buf;
798
799	buf = kzalloc(size, GFP_KERNEL);
800	if (!buf)
801		return -ENOMEM;
802
803	len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
804	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
805			 soc_stats->err_ring_pkts);
806	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
807			 soc_stats->invalid_rbm);
808	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
809	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
810		len += scnprintf(buf + len, size - len, "%s: %u\n",
811				 rxdma_err[i], soc_stats->rxdma_error[i]);
812
813	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
814	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
815		len += scnprintf(buf + len, size - len, "%s: %u\n",
816				 reo_err[i], soc_stats->reo_error[i]);
817
818	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
819	len += scnprintf(buf + len, size - len,
820			 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
821			 soc_stats->hal_reo_error[0],
822			 soc_stats->hal_reo_error[1],
823			 soc_stats->hal_reo_error[2],
824			 soc_stats->hal_reo_error[3]);
825
826	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
827	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
828
829	for (i = 0; i < ab->hw_params.max_tx_ring; i++)
830		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
831				 i, soc_stats->tx_err.desc_na[i]);
832
833	len += scnprintf(buf + len, size - len,
834			 "\nMisc Transmit Failures: %d\n",
835			 atomic_read(&soc_stats->tx_err.misc_fail));
836
837	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
838
839	if (len > size)
840		len = size;
841	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
842	kfree(buf);
843
844	return retval;
845}
846
847static const struct file_operations fops_soc_dp_stats = {
848	.read = ath11k_debugfs_dump_soc_dp_stats,
849	.open = simple_open,
850	.owner = THIS_MODULE,
851	.llseek = default_llseek,
852};
853
854static ssize_t ath11k_write_fw_dbglog(struct file *file,
855				      const char __user *user_buf,
856				      size_t count, loff_t *ppos)
857{
858	struct ath11k *ar = file->private_data;
859	char buf[128] = {0};
860	struct ath11k_fw_dbglog dbglog;
861	unsigned int param, mod_id_index, is_end;
862	u64 value;
863	int ret, num;
864
865	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
866				     user_buf, count);
867	if (ret <= 0)
868		return ret;
869
870	num = sscanf(buf, "%u %llx %u %u", &param, &value, &mod_id_index, &is_end);
871
872	if (num < 2)
873		return -EINVAL;
874
875	mutex_lock(&ar->conf_mutex);
876	if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
877	    param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
878		if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
879			ret = -EINVAL;
880			goto out;
881		}
882		ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
883		if (!is_end) {
884			ret = count;
885			goto out;
886		}
887	} else {
888		if (num != 2) {
889			ret = -EINVAL;
890			goto out;
891		}
892	}
893
894	dbglog.param = param;
895	dbglog.value = lower_32_bits(value);
896	ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
897	if (ret) {
898		ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
899			    ret);
900		goto out;
901	}
902
903	ret = count;
904
905out:
906	mutex_unlock(&ar->conf_mutex);
907	return ret;
908}
909
910static const struct file_operations fops_fw_dbglog = {
911	.write = ath11k_write_fw_dbglog,
912	.open = simple_open,
913	.owner = THIS_MODULE,
914	.llseek = default_llseek,
915};
916
917static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
918{
919	struct ath11k_base *ab = inode->i_private;
920	u8 *buf;
921	u32 start, end;
922	int ret;
923
924	start = ab->hw_params.sram_dump.start;
925	end = ab->hw_params.sram_dump.end;
926
927	buf = vmalloc(end - start + 1);
928	if (!buf)
929		return -ENOMEM;
930
931	ret = ath11k_hif_read(ab, buf, start, end);
932	if (ret) {
933		ath11k_warn(ab, "failed to dump sram: %d\n", ret);
934		vfree(buf);
935		return ret;
936	}
937
938	file->private_data = buf;
939	return 0;
940}
941
942static ssize_t ath11k_read_sram_dump(struct file *file,
943				     char __user *user_buf,
944				     size_t count, loff_t *ppos)
945{
946	struct ath11k_base *ab = file->f_inode->i_private;
947	const char *buf = file->private_data;
948	int len;
949	u32 start, end;
950
951	start = ab->hw_params.sram_dump.start;
952	end = ab->hw_params.sram_dump.end;
953	len = end - start + 1;
954
955	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
956}
957
958static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
959{
960	vfree(file->private_data);
961	file->private_data = NULL;
962
963	return 0;
964}
965
966static const struct file_operations fops_sram_dump = {
967	.open = ath11k_open_sram_dump,
968	.read = ath11k_read_sram_dump,
969	.release = ath11k_release_sram_dump,
970	.owner = THIS_MODULE,
971	.llseek = default_llseek,
972};
973
974int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
975{
976	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
977		return 0;
978
979	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
980			    &fops_simulate_fw_crash);
981
982	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
983			    &fops_soc_dp_stats);
984
985	if (ab->hw_params.sram_dump.start != 0)
986		debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
987				    &fops_sram_dump);
988
989	return 0;
990}
991
992void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
993{
994	debugfs_remove_recursive(ab->debugfs_soc);
995	ab->debugfs_soc = NULL;
996}
997
998int ath11k_debugfs_soc_create(struct ath11k_base *ab)
999{
1000	struct dentry *root;
1001	bool dput_needed;
1002	char name[64];
1003	int ret;
1004
1005	root = debugfs_lookup("ath11k", NULL);
1006	if (!root) {
1007		root = debugfs_create_dir("ath11k", NULL);
1008		if (IS_ERR_OR_NULL(root))
1009			return PTR_ERR(root);
1010
1011		dput_needed = false;
1012	} else {
1013		/* a dentry from lookup() needs dput() after we don't use it */
1014		dput_needed = true;
1015	}
1016
1017	scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
1018		  dev_name(ab->dev));
1019
1020	ab->debugfs_soc = debugfs_create_dir(name, root);
1021	if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
1022		ret = PTR_ERR(ab->debugfs_soc);
1023		goto out;
1024	}
1025
1026	ret = 0;
1027
1028out:
1029	if (dput_needed)
1030		dput(root);
1031
1032	return ret;
1033}
1034
1035void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1036{
1037	debugfs_remove_recursive(ab->debugfs_soc);
1038	ab->debugfs_soc = NULL;
1039
1040	/* We are not removing ath11k directory on purpose, even if it
1041	 * would be empty. This simplifies the directory handling and it's
1042	 * a minor cosmetic issue to leave an empty ath11k directory to
1043	 * debugfs.
1044	 */
1045}
1046EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1047
1048void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1049{
1050	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1051							ar->debug.debugfs_pdev);
1052
1053	ar->fw_stats.debugfs_fwstats = fwstats_dir;
1054
1055	/* all stats debugfs files created are under "fw_stats" directory
1056	 * created per PDEV
1057	 */
1058	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1059			    &fops_pdev_stats);
1060	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1061			    &fops_vdev_stats);
1062	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1063			    &fops_bcn_stats);
1064}
1065
1066static ssize_t ath11k_write_pktlog_filter(struct file *file,
1067					  const char __user *ubuf,
1068					  size_t count, loff_t *ppos)
1069{
1070	struct ath11k *ar = file->private_data;
1071	struct ath11k_base *ab = ar->ab;
1072	struct htt_rx_ring_tlv_filter tlv_filter = {0};
1073	u32 rx_filter = 0, ring_id, filter, mode;
1074	u8 buf[128] = {0};
1075	int i, ret, rx_buf_sz = 0;
1076	ssize_t rc;
1077
1078	mutex_lock(&ar->conf_mutex);
1079	if (ar->state != ATH11K_STATE_ON) {
1080		ret = -ENETDOWN;
1081		goto out;
1082	}
1083
1084	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1085	if (rc < 0) {
1086		ret = rc;
1087		goto out;
1088	}
1089	buf[rc] = '\0';
1090
1091	ret = sscanf(buf, "0x%x %u", &filter, &mode);
1092	if (ret != 2) {
1093		ret = -EINVAL;
1094		goto out;
1095	}
1096
1097	if (filter) {
1098		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1099		if (ret) {
1100			ath11k_warn(ar->ab,
1101				    "failed to enable pktlog filter %x: %d\n",
1102				    ar->debug.pktlog_filter, ret);
1103			goto out;
1104		}
1105	} else {
1106		ret = ath11k_wmi_pdev_pktlog_disable(ar);
1107		if (ret) {
1108			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1109			goto out;
1110		}
1111	}
1112
1113	/* Clear rx filter set for monitor mode and rx status */
1114	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1115		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1116		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
1117						       HAL_RXDMA_MONITOR_STATUS,
1118						       rx_buf_sz, &tlv_filter);
1119		if (ret) {
1120			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1121			goto out;
1122		}
1123	}
1124#define HTT_RX_FILTER_TLV_LITE_MODE \
1125			(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1126			HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1127			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1128			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1129			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1130			HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1131
1132	if (mode == ATH11K_PKTLOG_MODE_FULL) {
1133		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1134			    HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1135			    HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1136			    HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1137			    HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1138			    HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1139		rx_buf_sz = DP_RX_BUFFER_SIZE;
1140	} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1141		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1142							  HTT_PPDU_STATS_TAG_PKTLOG);
1143		if (ret) {
1144			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1145			goto out;
1146		}
1147
1148		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1149		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1150	} else {
1151		rx_buf_sz = DP_RX_BUFFER_SIZE;
1152		tlv_filter = ath11k_mac_mon_status_filter_default;
1153		rx_filter = tlv_filter.rx_filter;
1154
1155		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1156							  HTT_PPDU_STATS_TAG_DEFAULT);
1157		if (ret) {
1158			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1159				   ret);
1160			goto out;
1161		}
1162	}
1163
1164	tlv_filter.rx_filter = rx_filter;
1165	if (rx_filter) {
1166		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1167		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1168		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1169		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1170					       HTT_RX_FP_DATA_FILTER_FLASG3;
1171	}
1172
1173	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1174		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1175		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1176						       ar->dp.mac_id + i,
1177						       HAL_RXDMA_MONITOR_STATUS,
1178						       rx_buf_sz, &tlv_filter);
1179
1180		if (ret) {
1181			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1182			goto out;
1183		}
1184	}
1185
1186	ath11k_info(ab, "pktlog mode %s\n",
1187		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1188
1189	ar->debug.pktlog_filter = filter;
1190	ar->debug.pktlog_mode = mode;
1191	ret = count;
1192
1193out:
1194	mutex_unlock(&ar->conf_mutex);
1195	return ret;
1196}
1197
1198static ssize_t ath11k_read_pktlog_filter(struct file *file,
1199					 char __user *ubuf,
1200					 size_t count, loff_t *ppos)
1201
1202{
1203	char buf[32] = {0};
1204	struct ath11k *ar = file->private_data;
1205	int len = 0;
1206
1207	mutex_lock(&ar->conf_mutex);
1208	len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1209			ar->debug.pktlog_filter,
1210			ar->debug.pktlog_mode);
1211	mutex_unlock(&ar->conf_mutex);
1212
1213	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1214}
1215
1216static const struct file_operations fops_pktlog_filter = {
1217	.read = ath11k_read_pktlog_filter,
1218	.write = ath11k_write_pktlog_filter,
1219	.open = simple_open
1220};
1221
1222static ssize_t ath11k_write_simulate_radar(struct file *file,
1223					   const char __user *user_buf,
1224					   size_t count, loff_t *ppos)
1225{
1226	struct ath11k *ar = file->private_data;
1227	int ret;
1228
1229	ret = ath11k_wmi_simulate_radar(ar);
1230	if (ret)
1231		return ret;
1232
1233	return count;
1234}
1235
1236static const struct file_operations fops_simulate_radar = {
1237	.write = ath11k_write_simulate_radar,
1238	.open = simple_open
1239};
1240
1241static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1242					     char __user *user_buf,
1243					     size_t count, loff_t *ppos)
1244{
1245	struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
1246	static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
1247	int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
1248	char *buf;
1249	int i, ret;
1250	int len = 0;
1251
1252	buf = kzalloc(size, GFP_KERNEL);
1253	if (!buf)
1254		return -ENOMEM;
1255
1256	len += scnprintf(buf + len, size - len,
1257			 "-----------------------------------------\n");
1258	len += scnprintf(buf + len, size - len,
1259			 "| idx |  hp  |  tp  | timestamp |  event |\n");
1260	len += scnprintf(buf + len, size - len,
1261			 "-----------------------------------------\n");
1262
1263	spin_lock_bh(&dbr_dbg_data->lock);
1264
1265	for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
1266		len += scnprintf(buf + len, size - len,
1267				 "|%4u|%8u|%8u|%11llu|%8s|\n", i,
1268				 dbr_dbg_data->entries[i].hp,
1269				 dbr_dbg_data->entries[i].tp,
1270				 dbr_dbg_data->entries[i].timestamp,
1271				 event_id_to_string[dbr_dbg_data->entries[i].event]);
1272	}
1273
1274	spin_unlock_bh(&dbr_dbg_data->lock);
1275
1276	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1277	kfree(buf);
1278
1279	return ret;
1280}
1281
1282static const struct file_operations fops_debug_dump_dbr_entries = {
1283	.read = ath11k_debug_dump_dbr_entries,
1284	.open = simple_open,
1285	.owner = THIS_MODULE,
1286	.llseek = default_llseek,
1287};
1288
1289static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1290{
1291	struct ath11k_debug_dbr *dbr_debug;
1292	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1293
1294	if (!ar->debug.dbr_debug[dbr_id])
1295		return;
1296
1297	dbr_debug = ar->debug.dbr_debug[dbr_id];
1298	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1299
1300	debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1301	kfree(dbr_dbg_data->entries);
1302	kfree(dbr_debug);
1303	ar->debug.dbr_debug[dbr_id] = NULL;
1304}
1305
1306static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1307{
1308	struct ath11k_debug_dbr *dbr_debug;
1309	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1310	static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
1311
1312	if (ar->debug.dbr_debug[dbr_id])
1313		return 0;
1314
1315	ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1316					      GFP_KERNEL);
1317
1318	if (!ar->debug.dbr_debug[dbr_id])
1319		return -ENOMEM;
1320
1321	dbr_debug = ar->debug.dbr_debug[dbr_id];
1322	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1323
1324	if (dbr_debug->dbr_debugfs)
1325		return 0;
1326
1327	dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
1328						    ar->debug.debugfs_pdev);
1329	if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
1330		if (IS_ERR(dbr_debug->dbr_debugfs))
1331			return PTR_ERR(dbr_debug->dbr_debugfs);
1332		return -ENOMEM;
1333	}
1334
1335	dbr_debug->dbr_debug_enabled = true;
1336	dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
1337	dbr_dbg_data->dbr_debug_idx = 0;
1338	dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
1339					sizeof(struct ath11k_dbg_dbr_entry),
1340					GFP_KERNEL);
1341	if (!dbr_dbg_data->entries)
1342		return -ENOMEM;
1343
1344	spin_lock_init(&dbr_dbg_data->lock);
1345
1346	debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1347			    dbr_dbg_data, &fops_debug_dump_dbr_entries);
1348
1349	return 0;
1350}
1351
1352static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
1353						   const char __user *ubuf,
1354						   size_t count, loff_t *ppos)
1355{
1356	struct ath11k *ar = file->private_data;
1357	char buf[32] = {0};
1358	u32 dbr_id, enable;
1359	int ret;
1360
1361	mutex_lock(&ar->conf_mutex);
1362
1363	if (ar->state != ATH11K_STATE_ON) {
1364		ret = -ENETDOWN;
1365		goto out;
1366	}
1367
1368	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1369	if (ret < 0)
1370		goto out;
1371
1372	buf[ret] = '\0';
1373	ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1374	if (ret != 2 || dbr_id > 1 || enable > 1) {
1375		ret = -EINVAL;
1376		ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1377		goto out;
1378	}
1379
1380	if (enable) {
1381		ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1382		if (ret) {
1383			ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1384				    ret);
1385			goto out;
1386		}
1387	} else {
1388		ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1389	}
1390
1391	ret = count;
1392out:
1393	mutex_unlock(&ar->conf_mutex);
1394	return ret;
1395}
1396
1397static const struct file_operations fops_dbr_debug = {
1398	.write = ath11k_debugfs_write_enable_dbr_dbg,
1399	.open = simple_open,
1400	.owner = THIS_MODULE,
1401	.llseek = default_llseek,
1402};
1403
1404static ssize_t ath11k_write_ps_timekeeper_enable(struct file *file,
1405						 const char __user *user_buf,
1406						 size_t count, loff_t *ppos)
1407{
1408	struct ath11k *ar = file->private_data;
1409	ssize_t ret;
1410	u8 ps_timekeeper_enable;
1411
1412	if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1413		return -EINVAL;
1414
1415	mutex_lock(&ar->conf_mutex);
1416
1417	if (ar->state != ATH11K_STATE_ON) {
1418		ret = -ENETDOWN;
1419		goto exit;
1420	}
1421
1422	if (!ar->ps_state_enable) {
1423		ret = -EINVAL;
1424		goto exit;
1425	}
1426
1427	ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1428	ret = count;
1429exit:
1430	mutex_unlock(&ar->conf_mutex);
1431
1432	return ret;
1433}
1434
1435static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1436						char __user *user_buf,
1437						size_t count, loff_t *ppos)
1438{
1439	struct ath11k *ar = file->private_data;
1440	char buf[32];
1441	int len;
1442
1443	mutex_lock(&ar->conf_mutex);
1444	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1445	mutex_unlock(&ar->conf_mutex);
1446
1447	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1448}
1449
1450static const struct file_operations fops_ps_timekeeper_enable = {
1451	.read = ath11k_read_ps_timekeeper_enable,
1452	.write = ath11k_write_ps_timekeeper_enable,
1453	.open = simple_open,
1454	.owner = THIS_MODULE,
1455	.llseek = default_llseek,
1456};
1457
1458static void ath11k_reset_peer_ps_duration(void *data,
1459					  struct ieee80211_sta *sta)
1460{
1461	struct ath11k *ar = data;
1462	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1463
1464	spin_lock_bh(&ar->data_lock);
1465	arsta->ps_total_duration = 0;
1466	spin_unlock_bh(&ar->data_lock);
1467}
1468
1469static ssize_t ath11k_write_reset_ps_duration(struct file *file,
1470					      const  char __user *user_buf,
1471					      size_t count, loff_t *ppos)
1472{
1473	struct ath11k *ar = file->private_data;
1474	int ret;
1475	u8 reset_ps_duration;
1476
1477	if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1478		return -EINVAL;
1479
1480	mutex_lock(&ar->conf_mutex);
1481
1482	if (ar->state != ATH11K_STATE_ON) {
1483		ret = -ENETDOWN;
1484		goto exit;
1485	}
1486
1487	if (!ar->ps_state_enable) {
1488		ret = -EINVAL;
1489		goto exit;
1490	}
1491
1492	ieee80211_iterate_stations_atomic(ar->hw,
1493					  ath11k_reset_peer_ps_duration,
1494					  ar);
1495
1496	ret = count;
1497exit:
1498	mutex_unlock(&ar->conf_mutex);
1499	return ret;
1500}
1501
1502static const struct file_operations fops_reset_ps_duration = {
1503	.write = ath11k_write_reset_ps_duration,
1504	.open = simple_open,
1505	.owner = THIS_MODULE,
1506	.llseek = default_llseek,
1507};
1508
1509static void ath11k_peer_ps_state_disable(void *data,
1510					 struct ieee80211_sta *sta)
1511{
1512	struct ath11k *ar = data;
1513	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1514
1515	spin_lock_bh(&ar->data_lock);
1516	arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
1517	arsta->ps_start_time = 0;
1518	arsta->ps_total_duration = 0;
1519	spin_unlock_bh(&ar->data_lock);
1520}
1521
1522static ssize_t ath11k_write_ps_state_enable(struct file *file,
1523					    const char __user *user_buf,
1524					    size_t count, loff_t *ppos)
1525{
1526	struct ath11k *ar = file->private_data;
1527	struct ath11k_pdev *pdev = ar->pdev;
1528	int ret;
1529	u32 param;
1530	u8 ps_state_enable;
1531
1532	if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1533		return -EINVAL;
1534
1535	mutex_lock(&ar->conf_mutex);
1536
1537	ps_state_enable = !!ps_state_enable;
1538
1539	if (ar->ps_state_enable == ps_state_enable) {
1540		ret = count;
1541		goto exit;
1542	}
1543
1544	param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1545	ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1546	if (ret) {
1547		ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1548			    ret);
1549		goto exit;
1550	}
1551	ar->ps_state_enable = ps_state_enable;
1552
1553	if (!ar->ps_state_enable) {
1554		ar->ps_timekeeper_enable = false;
1555		ieee80211_iterate_stations_atomic(ar->hw,
1556						  ath11k_peer_ps_state_disable,
1557						  ar);
1558	}
1559
1560	ret = count;
1561
1562exit:
1563	mutex_unlock(&ar->conf_mutex);
1564
1565	return ret;
1566}
1567
1568static ssize_t ath11k_read_ps_state_enable(struct file *file,
1569					   char __user *user_buf,
1570					   size_t count, loff_t *ppos)
1571{
1572	struct ath11k *ar = file->private_data;
1573	char buf[32];
1574	int len;
1575
1576	mutex_lock(&ar->conf_mutex);
1577	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1578	mutex_unlock(&ar->conf_mutex);
1579
1580	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1581}
1582
1583static const struct file_operations fops_ps_state_enable = {
1584	.read = ath11k_read_ps_state_enable,
1585	.write = ath11k_write_ps_state_enable,
1586	.open = simple_open,
1587	.owner = THIS_MODULE,
1588	.llseek = default_llseek,
1589};
1590
1591int ath11k_debugfs_register(struct ath11k *ar)
1592{
1593	struct ath11k_base *ab = ar->ab;
1594	char pdev_name[5];
1595	char buf[100] = {0};
1596
1597	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1598
1599	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1600	if (IS_ERR(ar->debug.debugfs_pdev))
1601		return PTR_ERR(ar->debug.debugfs_pdev);
1602
1603	/* Create a symlink under ieee80211/phy* */
1604	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1605	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1606
1607	ath11k_debugfs_htt_stats_init(ar);
1608
1609	ath11k_debugfs_fw_stats_init(ar);
1610
1611	debugfs_create_file("ext_tx_stats", 0644,
1612			    ar->debug.debugfs_pdev, ar,
1613			    &fops_extd_tx_stats);
1614	debugfs_create_file("ext_rx_stats", 0644,
1615			    ar->debug.debugfs_pdev, ar,
1616			    &fops_extd_rx_stats);
1617	debugfs_create_file("pktlog_filter", 0644,
1618			    ar->debug.debugfs_pdev, ar,
1619			    &fops_pktlog_filter);
1620	debugfs_create_file("fw_dbglog_config", 0600,
1621			    ar->debug.debugfs_pdev, ar,
1622			    &fops_fw_dbglog);
1623
1624	if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1625		debugfs_create_file("dfs_simulate_radar", 0200,
1626				    ar->debug.debugfs_pdev, ar,
1627				    &fops_simulate_radar);
1628		debugfs_create_bool("dfs_block_radar_events", 0200,
1629				    ar->debug.debugfs_pdev,
1630				    &ar->dfs_block_radar_events);
1631	}
1632
1633	if (ab->hw_params.dbr_debug_support)
1634		debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
1635				    ar, &fops_dbr_debug);
1636
1637	debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1638			    &fops_ps_state_enable);
1639
1640	if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
1641		     ar->ab->wmi_ab.svc_map)) {
1642		debugfs_create_file("ps_timekeeper_enable", 0600,
1643				    ar->debug.debugfs_pdev, ar,
1644				    &fops_ps_timekeeper_enable);
1645
1646		debugfs_create_file("reset_ps_duration", 0200,
1647				    ar->debug.debugfs_pdev, ar,
1648				    &fops_reset_ps_duration);
1649	}
1650
1651	return 0;
1652}
1653
1654void ath11k_debugfs_unregister(struct ath11k *ar)
1655{
1656	struct ath11k_debug_dbr *dbr_debug;
1657	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1658	int i;
1659
1660	for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1661		dbr_debug = ar->debug.dbr_debug[i];
1662		if (!dbr_debug)
1663			continue;
1664
1665		dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1666		kfree(dbr_dbg_data->entries);
1667		debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1668		kfree(dbr_debug);
1669		ar->debug.dbr_debug[i] = NULL;
1670	}
1671}
1672
1673static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1674					   const char __user *ubuf,
1675					   size_t count, loff_t *ppos)
1676{
1677	struct ath11k_vif *arvif = file->private_data;
1678	struct wmi_twt_add_dialog_params params = { 0 };
1679	struct wmi_twt_enable_params twt_params = {0};
1680	struct ath11k *ar = arvif->ar;
1681	u8 buf[128] = {0};
1682	int ret;
1683
1684	if (ar->twt_enabled == 0) {
1685		ath11k_err(ar->ab, "twt support is not enabled\n");
1686		return -EOPNOTSUPP;
1687	}
1688
1689	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1690	if (ret < 0)
1691		return ret;
1692
1693	buf[ret] = '\0';
1694	ret = sscanf(buf,
1695		     "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1696		     &params.peer_macaddr[0],
1697		     &params.peer_macaddr[1],
1698		     &params.peer_macaddr[2],
1699		     &params.peer_macaddr[3],
1700		     &params.peer_macaddr[4],
1701		     &params.peer_macaddr[5],
1702		     &params.dialog_id,
1703		     &params.wake_intvl_us,
1704		     &params.wake_intvl_mantis,
1705		     &params.wake_dura_us,
1706		     &params.sp_offset_us,
1707		     &params.twt_cmd,
1708		     &params.flag_bcast,
1709		     &params.flag_trigger,
1710		     &params.flag_flow_type,
1711		     &params.flag_protection);
1712	if (ret != 16)
1713		return -EINVAL;
1714
1715	/* In the case of station vif, TWT is entirely handled by
1716	 * the firmware based on the input parameters in the TWT enable
1717	 * WMI command that is sent to the target during assoc.
1718	 * For manually testing the TWT feature, we need to first disable
1719	 * TWT and send enable command again with TWT input parameter
1720	 * sta_cong_timer_ms set to 0.
1721	 */
1722	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1723		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1724
1725		ath11k_wmi_fill_default_twt_params(&twt_params);
1726		twt_params.sta_cong_timer_ms = 0;
1727
1728		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1729	}
1730
1731	params.vdev_id = arvif->vdev_id;
1732
1733	ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, &params);
1734	if (ret)
1735		goto err_twt_add_dialog;
1736
1737	return count;
1738
1739err_twt_add_dialog:
1740	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1741		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1742		ath11k_wmi_fill_default_twt_params(&twt_params);
1743		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1744	}
1745
1746	return ret;
1747}
1748
1749static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1750					   const char __user *ubuf,
1751					   size_t count, loff_t *ppos)
1752{
1753	struct ath11k_vif *arvif = file->private_data;
1754	struct wmi_twt_del_dialog_params params = { 0 };
1755	struct wmi_twt_enable_params twt_params = {0};
1756	struct ath11k *ar = arvif->ar;
1757	u8 buf[64] = {0};
1758	int ret;
1759
1760	if (ar->twt_enabled == 0) {
1761		ath11k_err(ar->ab, "twt support is not enabled\n");
1762		return -EOPNOTSUPP;
1763	}
1764
1765	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1766	if (ret < 0)
1767		return ret;
1768
1769	buf[ret] = '\0';
1770	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1771		     &params.peer_macaddr[0],
1772		     &params.peer_macaddr[1],
1773		     &params.peer_macaddr[2],
1774		     &params.peer_macaddr[3],
1775		     &params.peer_macaddr[4],
1776		     &params.peer_macaddr[5],
1777		     &params.dialog_id);
1778	if (ret != 7)
1779		return -EINVAL;
1780
1781	params.vdev_id = arvif->vdev_id;
1782
1783	ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, &params);
1784	if (ret)
1785		return ret;
1786
1787	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1788		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1789		ath11k_wmi_fill_default_twt_params(&twt_params);
1790		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1791	}
1792
1793	return count;
1794}
1795
1796static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1797					     const char __user *ubuf,
1798					     size_t count, loff_t *ppos)
1799{
1800	struct ath11k_vif *arvif = file->private_data;
1801	struct wmi_twt_pause_dialog_params params = { 0 };
1802	u8 buf[64] = {0};
1803	int ret;
1804
1805	if (arvif->ar->twt_enabled == 0) {
1806		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1807		return -EOPNOTSUPP;
1808	}
1809
1810	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1811	if (ret < 0)
1812		return ret;
1813
1814	buf[ret] = '\0';
1815	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1816		     &params.peer_macaddr[0],
1817		     &params.peer_macaddr[1],
1818		     &params.peer_macaddr[2],
1819		     &params.peer_macaddr[3],
1820		     &params.peer_macaddr[4],
1821		     &params.peer_macaddr[5],
1822		     &params.dialog_id);
1823	if (ret != 7)
1824		return -EINVAL;
1825
1826	params.vdev_id = arvif->vdev_id;
1827
1828	ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, &params);
1829	if (ret)
1830		return ret;
1831
1832	return count;
1833}
1834
1835static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1836					      const char __user *ubuf,
1837					      size_t count, loff_t *ppos)
1838{
1839	struct ath11k_vif *arvif = file->private_data;
1840	struct wmi_twt_resume_dialog_params params = { 0 };
1841	u8 buf[64] = {0};
1842	int ret;
1843
1844	if (arvif->ar->twt_enabled == 0) {
1845		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1846		return -EOPNOTSUPP;
1847	}
1848
1849	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1850	if (ret < 0)
1851		return ret;
1852
1853	buf[ret] = '\0';
1854	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1855		     &params.peer_macaddr[0],
1856		     &params.peer_macaddr[1],
1857		     &params.peer_macaddr[2],
1858		     &params.peer_macaddr[3],
1859		     &params.peer_macaddr[4],
1860		     &params.peer_macaddr[5],
1861		     &params.dialog_id,
1862		     &params.sp_offset_us,
1863		     &params.next_twt_size);
1864	if (ret != 9)
1865		return -EINVAL;
1866
1867	params.vdev_id = arvif->vdev_id;
1868
1869	ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, &params);
1870	if (ret)
1871		return ret;
1872
1873	return count;
1874}
1875
1876static const struct file_operations ath11k_fops_twt_add_dialog = {
1877	.write = ath11k_write_twt_add_dialog,
1878	.open = simple_open
1879};
1880
1881static const struct file_operations ath11k_fops_twt_del_dialog = {
1882	.write = ath11k_write_twt_del_dialog,
1883	.open = simple_open
1884};
1885
1886static const struct file_operations ath11k_fops_twt_pause_dialog = {
1887	.write = ath11k_write_twt_pause_dialog,
1888	.open = simple_open
1889};
1890
1891static const struct file_operations ath11k_fops_twt_resume_dialog = {
1892	.write = ath11k_write_twt_resume_dialog,
1893	.open = simple_open
1894};
1895
1896void ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
1897{
1898	struct ath11k_base *ab = arvif->ar->ab;
1899
1900	if (arvif->vif->type != NL80211_IFTYPE_AP &&
1901	    !(arvif->vif->type == NL80211_IFTYPE_STATION &&
1902	      test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
1903		return;
1904
1905	arvif->debugfs_twt = debugfs_create_dir("twt",
1906						arvif->vif->debugfs_dir);
1907	debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
1908			    arvif, &ath11k_fops_twt_add_dialog);
1909
1910	debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
1911			    arvif, &ath11k_fops_twt_del_dialog);
1912
1913	debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
1914			    arvif, &ath11k_fops_twt_pause_dialog);
1915
1916	debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
1917			    arvif, &ath11k_fops_twt_resume_dialog);
1918}
1919
1920void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
1921{
1922	if (!arvif->debugfs_twt)
1923		return;
1924
1925	debugfs_remove_recursive(arvif->debugfs_twt);
1926	arvif->debugfs_twt = NULL;
1927}
1928