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