xref: /freebsd/sys/contrib/dev/athk/ath11k/debugfs.c (revision 911f0260390e18cf85f3dbf2c719b593efdc1e3c)
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 static void ath11k_fw_stats_pdevs_free(struct list_head *head)
56 {
57 	struct ath11k_fw_stats_pdev *i, *tmp;
58 
59 	list_for_each_entry_safe(i, tmp, head, list) {
60 		list_del(&i->list);
61 		kfree(i);
62 	}
63 }
64 
65 static void ath11k_fw_stats_vdevs_free(struct list_head *head)
66 {
67 	struct ath11k_fw_stats_vdev *i, *tmp;
68 
69 	list_for_each_entry_safe(i, tmp, head, list) {
70 		list_del(&i->list);
71 		kfree(i);
72 	}
73 }
74 
75 static void ath11k_fw_stats_bcn_free(struct list_head *head)
76 {
77 	struct ath11k_fw_stats_bcn *i, *tmp;
78 
79 	list_for_each_entry_safe(i, tmp, head, list) {
80 		list_del(&i->list);
81 		kfree(i);
82 	}
83 }
84 
85 static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
86 {
87 	spin_lock_bh(&ar->data_lock);
88 	ar->debug.fw_stats_done = false;
89 	ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
90 	ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
91 	spin_unlock_bh(&ar->data_lock);
92 }
93 
94 void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
95 {
96 	struct ath11k_fw_stats stats = {};
97 	struct ath11k *ar;
98 	struct ath11k_pdev *pdev;
99 	bool is_end;
100 	static unsigned int num_vdev, num_bcn;
101 	size_t total_vdevs_started = 0;
102 	int i, ret;
103 
104 	INIT_LIST_HEAD(&stats.pdevs);
105 	INIT_LIST_HEAD(&stats.vdevs);
106 	INIT_LIST_HEAD(&stats.bcn);
107 
108 	ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
109 	if (ret) {
110 		ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
111 		goto free;
112 	}
113 
114 	rcu_read_lock();
115 	ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
116 	if (!ar) {
117 		rcu_read_unlock();
118 		ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
119 			    stats.pdev_id, ret);
120 		goto free;
121 	}
122 
123 	spin_lock_bh(&ar->data_lock);
124 
125 	if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
126 		list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
127 		ar->debug.fw_stats_done = true;
128 		goto complete;
129 	}
130 
131 	if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
132 		ar->debug.fw_stats_done = true;
133 		goto complete;
134 	}
135 
136 	if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
137 		if (list_empty(&stats.vdevs)) {
138 			ath11k_warn(ab, "empty vdev stats");
139 			goto complete;
140 		}
141 		/* FW sends all the active VDEV stats irrespective of PDEV,
142 		 * hence limit until the count of all VDEVs started
143 		 */
144 		for (i = 0; i < ab->num_radios; i++) {
145 			pdev = rcu_dereference(ab->pdevs_active[i]);
146 			if (pdev && pdev->ar)
147 				total_vdevs_started += ar->num_started_vdevs;
148 		}
149 
150 		is_end = ((++num_vdev) == total_vdevs_started);
151 
152 		list_splice_tail_init(&stats.vdevs,
153 				      &ar->debug.fw_stats.vdevs);
154 
155 		if (is_end) {
156 			ar->debug.fw_stats_done = true;
157 			num_vdev = 0;
158 		}
159 		goto complete;
160 	}
161 
162 	if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
163 		if (list_empty(&stats.bcn)) {
164 			ath11k_warn(ab, "empty bcn stats");
165 			goto complete;
166 		}
167 		/* Mark end until we reached the count of all started VDEVs
168 		 * within the PDEV
169 		 */
170 		is_end = ((++num_bcn) == ar->num_started_vdevs);
171 
172 		list_splice_tail_init(&stats.bcn,
173 				      &ar->debug.fw_stats.bcn);
174 
175 		if (is_end) {
176 			ar->debug.fw_stats_done = true;
177 			num_bcn = 0;
178 		}
179 	}
180 complete:
181 	complete(&ar->debug.fw_stats_complete);
182 	rcu_read_unlock();
183 	spin_unlock_bh(&ar->data_lock);
184 
185 free:
186 	ath11k_fw_stats_pdevs_free(&stats.pdevs);
187 	ath11k_fw_stats_vdevs_free(&stats.vdevs);
188 	ath11k_fw_stats_bcn_free(&stats.bcn);
189 }
190 
191 static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
192 					   struct stats_request_params *req_param)
193 {
194 	struct ath11k_base *ab = ar->ab;
195 	unsigned long timeout, time_left;
196 	int ret;
197 
198 	lockdep_assert_held(&ar->conf_mutex);
199 
200 	/* FW stats can get split when exceeding the stats data buffer limit.
201 	 * In that case, since there is no end marking for the back-to-back
202 	 * received 'update stats' event, we keep a 3 seconds timeout in case,
203 	 * fw_stats_done is not marked yet
204 	 */
205 	timeout = jiffies + msecs_to_jiffies(3 * 1000);
206 
207 	ath11k_debugfs_fw_stats_reset(ar);
208 
209 	reinit_completion(&ar->debug.fw_stats_complete);
210 
211 	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
212 
213 	if (ret) {
214 		ath11k_warn(ab, "could not request fw stats (%d)\n",
215 			    ret);
216 		return ret;
217 	}
218 
219 	time_left =
220 	wait_for_completion_timeout(&ar->debug.fw_stats_complete,
221 				    1 * HZ);
222 	if (!time_left)
223 		return -ETIMEDOUT;
224 
225 	for (;;) {
226 		if (time_after(jiffies, timeout))
227 			break;
228 
229 		spin_lock_bh(&ar->data_lock);
230 		if (ar->debug.fw_stats_done) {
231 			spin_unlock_bh(&ar->data_lock);
232 			break;
233 		}
234 		spin_unlock_bh(&ar->data_lock);
235 	}
236 	return 0;
237 }
238 
239 int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
240 				u32 vdev_id, u32 stats_id)
241 {
242 	struct ath11k_base *ab = ar->ab;
243 	struct stats_request_params req_param;
244 	int ret;
245 
246 	mutex_lock(&ar->conf_mutex);
247 
248 	if (ar->state != ATH11K_STATE_ON) {
249 		ret = -ENETDOWN;
250 		goto err_unlock;
251 	}
252 
253 	req_param.pdev_id = pdev_id;
254 	req_param.vdev_id = vdev_id;
255 	req_param.stats_id = stats_id;
256 
257 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
258 	if (ret)
259 		ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
260 
261 	ath11k_dbg(ab, ATH11K_DBG_WMI,
262 		   "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
263 		   pdev_id, vdev_id, stats_id);
264 
265 err_unlock:
266 	mutex_unlock(&ar->conf_mutex);
267 
268 	return ret;
269 }
270 
271 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
272 {
273 	struct ath11k *ar = inode->i_private;
274 	struct ath11k_base *ab = ar->ab;
275 	struct stats_request_params req_param;
276 	void *buf = NULL;
277 	int ret;
278 
279 	mutex_lock(&ar->conf_mutex);
280 
281 	if (ar->state != ATH11K_STATE_ON) {
282 		ret = -ENETDOWN;
283 		goto err_unlock;
284 	}
285 
286 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
287 	if (!buf) {
288 		ret = -ENOMEM;
289 		goto err_unlock;
290 	}
291 
292 	req_param.pdev_id = ar->pdev->pdev_id;
293 	req_param.vdev_id = 0;
294 	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
295 
296 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
297 	if (ret) {
298 		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
299 		goto err_free;
300 	}
301 
302 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
303 				 buf);
304 
305 	file->private_data = buf;
306 
307 	mutex_unlock(&ar->conf_mutex);
308 	return 0;
309 
310 err_free:
311 	vfree(buf);
312 
313 err_unlock:
314 	mutex_unlock(&ar->conf_mutex);
315 	return ret;
316 }
317 
318 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
319 {
320 	vfree(file->private_data);
321 
322 	return 0;
323 }
324 
325 static ssize_t ath11k_read_pdev_stats(struct file *file,
326 				      char __user *user_buf,
327 				      size_t count, loff_t *ppos)
328 {
329 	const char *buf = file->private_data;
330 	size_t len = strlen(buf);
331 
332 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
333 }
334 
335 static const struct file_operations fops_pdev_stats = {
336 	.open = ath11k_open_pdev_stats,
337 	.release = ath11k_release_pdev_stats,
338 	.read = ath11k_read_pdev_stats,
339 	.owner = THIS_MODULE,
340 	.llseek = default_llseek,
341 };
342 
343 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
344 {
345 	struct ath11k *ar = inode->i_private;
346 	struct stats_request_params req_param;
347 	void *buf = NULL;
348 	int ret;
349 
350 	mutex_lock(&ar->conf_mutex);
351 
352 	if (ar->state != ATH11K_STATE_ON) {
353 		ret = -ENETDOWN;
354 		goto err_unlock;
355 	}
356 
357 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
358 	if (!buf) {
359 		ret = -ENOMEM;
360 		goto err_unlock;
361 	}
362 
363 	req_param.pdev_id = ar->pdev->pdev_id;
364 	/* VDEV stats is always sent for all active VDEVs from FW */
365 	req_param.vdev_id = 0;
366 	req_param.stats_id = WMI_REQUEST_VDEV_STAT;
367 
368 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
369 	if (ret) {
370 		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
371 		goto err_free;
372 	}
373 
374 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
375 				 buf);
376 
377 	file->private_data = buf;
378 
379 	mutex_unlock(&ar->conf_mutex);
380 	return 0;
381 
382 err_free:
383 	vfree(buf);
384 
385 err_unlock:
386 	mutex_unlock(&ar->conf_mutex);
387 	return ret;
388 }
389 
390 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
391 {
392 	vfree(file->private_data);
393 
394 	return 0;
395 }
396 
397 static ssize_t ath11k_read_vdev_stats(struct file *file,
398 				      char __user *user_buf,
399 				      size_t count, loff_t *ppos)
400 {
401 	const char *buf = file->private_data;
402 	size_t len = strlen(buf);
403 
404 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
405 }
406 
407 static const struct file_operations fops_vdev_stats = {
408 	.open = ath11k_open_vdev_stats,
409 	.release = ath11k_release_vdev_stats,
410 	.read = ath11k_read_vdev_stats,
411 	.owner = THIS_MODULE,
412 	.llseek = default_llseek,
413 };
414 
415 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
416 {
417 	struct ath11k *ar = inode->i_private;
418 	struct ath11k_vif *arvif;
419 	struct stats_request_params req_param;
420 	void *buf = NULL;
421 	int ret;
422 
423 	mutex_lock(&ar->conf_mutex);
424 
425 	if (ar->state != ATH11K_STATE_ON) {
426 		ret = -ENETDOWN;
427 		goto err_unlock;
428 	}
429 
430 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
431 	if (!buf) {
432 		ret = -ENOMEM;
433 		goto err_unlock;
434 	}
435 
436 	req_param.stats_id = WMI_REQUEST_BCN_STAT;
437 	req_param.pdev_id = ar->pdev->pdev_id;
438 
439 	/* loop all active VDEVs for bcn stats */
440 	list_for_each_entry(arvif, &ar->arvifs, list) {
441 		if (!arvif->is_up)
442 			continue;
443 
444 		req_param.vdev_id = arvif->vdev_id;
445 		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
446 		if (ret) {
447 			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
448 			goto err_free;
449 		}
450 	}
451 
452 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
453 				 buf);
454 
455 	/* since beacon stats request is looped for all active VDEVs, saved fw
456 	 * stats is not freed for each request until done for all active VDEVs
457 	 */
458 	spin_lock_bh(&ar->data_lock);
459 	ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
460 	spin_unlock_bh(&ar->data_lock);
461 
462 	file->private_data = buf;
463 
464 	mutex_unlock(&ar->conf_mutex);
465 	return 0;
466 
467 err_free:
468 	vfree(buf);
469 
470 err_unlock:
471 	mutex_unlock(&ar->conf_mutex);
472 	return ret;
473 }
474 
475 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
476 {
477 	vfree(file->private_data);
478 
479 	return 0;
480 }
481 
482 static ssize_t ath11k_read_bcn_stats(struct file *file,
483 				     char __user *user_buf,
484 				     size_t count, loff_t *ppos)
485 {
486 	const char *buf = file->private_data;
487 	size_t len = strlen(buf);
488 
489 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
490 }
491 
492 static const struct file_operations fops_bcn_stats = {
493 	.open = ath11k_open_bcn_stats,
494 	.release = ath11k_release_bcn_stats,
495 	.read = ath11k_read_bcn_stats,
496 	.owner = THIS_MODULE,
497 	.llseek = default_llseek,
498 };
499 
500 static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
501 					     char __user *user_buf,
502 					     size_t count, loff_t *ppos)
503 {
504 	const char buf[] =
505 		"To simulate firmware crash write one of the keywords to this file:\n"
506 		"`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
507 		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
508 
509 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
510 }
511 
512 /* Simulate firmware crash:
513  * 'soft': Call wmi command causing firmware hang. This firmware hang is
514  * recoverable by warm firmware reset.
515  * 'hard': Force firmware crash by setting any vdev parameter for not allowed
516  * vdev id. This is hard firmware crash because it is recoverable only by cold
517  * firmware reset.
518  */
519 static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
520 					      const char __user *user_buf,
521 					      size_t count, loff_t *ppos)
522 {
523 	struct ath11k_base *ab = file->private_data;
524 	struct ath11k_pdev *pdev;
525 	struct ath11k *ar = ab->pdevs[0].ar;
526 	char buf[32] = {0};
527 	ssize_t rc;
528 	int i, ret, radioup = 0;
529 
530 	for (i = 0; i < ab->num_radios; i++) {
531 		pdev = &ab->pdevs[i];
532 		ar = pdev->ar;
533 		if (ar && ar->state == ATH11K_STATE_ON) {
534 			radioup = 1;
535 			break;
536 		}
537 	}
538 	/* filter partial writes and invalid commands */
539 	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
540 		return -EINVAL;
541 
542 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
543 	if (rc < 0)
544 		return rc;
545 
546 	/* drop the possible '\n' from the end */
547 	if (buf[*ppos - 1] == '\n')
548 		buf[*ppos - 1] = '\0';
549 
550 	if (radioup == 0) {
551 		ret = -ENETDOWN;
552 		goto exit;
553 	}
554 
555 	if (!strcmp(buf, "assert")) {
556 		ath11k_info(ab, "simulating firmware assert crash\n");
557 		ret = ath11k_wmi_force_fw_hang_cmd(ar,
558 						   ATH11K_WMI_FW_HANG_ASSERT_TYPE,
559 						   ATH11K_WMI_FW_HANG_DELAY);
560 	} else {
561 		ret = -EINVAL;
562 		goto exit;
563 	}
564 
565 	if (ret) {
566 		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
567 		goto exit;
568 	}
569 
570 	ret = count;
571 
572 exit:
573 	return ret;
574 }
575 
576 static const struct file_operations fops_simulate_fw_crash = {
577 	.read = ath11k_read_simulate_fw_crash,
578 	.write = ath11k_write_simulate_fw_crash,
579 	.open = simple_open,
580 	.owner = THIS_MODULE,
581 	.llseek = default_llseek,
582 };
583 
584 static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
585 						 const char __user *ubuf,
586 						 size_t count, loff_t *ppos)
587 {
588 	struct ath11k *ar = file->private_data;
589 	u32 filter;
590 	int ret;
591 
592 	if (kstrtouint_from_user(ubuf, count, 0, &filter))
593 		return -EINVAL;
594 
595 	mutex_lock(&ar->conf_mutex);
596 
597 	if (ar->state != ATH11K_STATE_ON) {
598 		ret = -ENETDOWN;
599 		goto out;
600 	}
601 
602 	if (filter == ar->debug.extd_tx_stats) {
603 		ret = count;
604 		goto out;
605 	}
606 
607 	ar->debug.extd_tx_stats = filter;
608 	ret = count;
609 
610 out:
611 	mutex_unlock(&ar->conf_mutex);
612 	return ret;
613 }
614 
615 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
616 						char __user *ubuf,
617 						size_t count, loff_t *ppos)
618 
619 {
620 	char buf[32] = {0};
621 	struct ath11k *ar = file->private_data;
622 	int len = 0;
623 
624 	mutex_lock(&ar->conf_mutex);
625 	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
626 			ar->debug.extd_tx_stats);
627 	mutex_unlock(&ar->conf_mutex);
628 
629 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
630 }
631 
632 static const struct file_operations fops_extd_tx_stats = {
633 	.read = ath11k_read_enable_extd_tx_stats,
634 	.write = ath11k_write_enable_extd_tx_stats,
635 	.open = simple_open
636 };
637 
638 static ssize_t ath11k_write_extd_rx_stats(struct file *file,
639 					  const char __user *ubuf,
640 					  size_t count, loff_t *ppos)
641 {
642 	struct ath11k *ar = file->private_data;
643 	struct ath11k_base *ab = ar->ab;
644 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
645 	u32 enable, rx_filter = 0, ring_id;
646 	int i;
647 	int ret;
648 
649 	if (kstrtouint_from_user(ubuf, count, 0, &enable))
650 		return -EINVAL;
651 
652 	mutex_lock(&ar->conf_mutex);
653 
654 	if (ar->state != ATH11K_STATE_ON) {
655 		ret = -ENETDOWN;
656 		goto exit;
657 	}
658 
659 	if (enable > 1) {
660 		ret = -EINVAL;
661 		goto exit;
662 	}
663 
664 	if (enable == ar->debug.extd_rx_stats) {
665 		ret = count;
666 		goto exit;
667 	}
668 
669 	if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
670 		ar->debug.extd_rx_stats = enable;
671 		ret = count;
672 		goto exit;
673 	}
674 
675 	if (enable) {
676 		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
677 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
678 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
679 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
680 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
681 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
682 
683 		tlv_filter.rx_filter = rx_filter;
684 		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
685 		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
686 		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
687 		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
688 			HTT_RX_FP_DATA_FILTER_FLASG3;
689 	} else {
690 		tlv_filter = ath11k_mac_mon_status_filter_default;
691 	}
692 
693 	ar->debug.rx_filter = tlv_filter.rx_filter;
694 
695 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
696 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
697 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
698 						       HAL_RXDMA_MONITOR_STATUS,
699 						       DP_RX_BUFFER_SIZE, &tlv_filter);
700 
701 		if (ret) {
702 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
703 			goto exit;
704 		}
705 	}
706 
707 	ar->debug.extd_rx_stats = enable;
708 	ret = count;
709 exit:
710 	mutex_unlock(&ar->conf_mutex);
711 	return ret;
712 }
713 
714 static ssize_t ath11k_read_extd_rx_stats(struct file *file,
715 					 char __user *ubuf,
716 					 size_t count, loff_t *ppos)
717 {
718 	struct ath11k *ar = file->private_data;
719 	char buf[32];
720 	int len = 0;
721 
722 	mutex_lock(&ar->conf_mutex);
723 	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
724 			ar->debug.extd_rx_stats);
725 	mutex_unlock(&ar->conf_mutex);
726 
727 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
728 }
729 
730 static const struct file_operations fops_extd_rx_stats = {
731 	.read = ath11k_read_extd_rx_stats,
732 	.write = ath11k_write_extd_rx_stats,
733 	.open = simple_open,
734 };
735 
736 static int ath11k_fill_bp_stats(struct ath11k_base *ab,
737 				struct ath11k_bp_stats *bp_stats,
738 				char *buf, int len, int size)
739 {
740 	lockdep_assert_held(&ab->base_lock);
741 
742 	len += scnprintf(buf + len, size - len, "count: %u\n",
743 			 bp_stats->count);
744 	len += scnprintf(buf + len, size - len, "hp: %u\n",
745 			 bp_stats->hp);
746 	len += scnprintf(buf + len, size - len, "tp: %u\n",
747 			 bp_stats->tp);
748 	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
749 			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
750 	return len;
751 }
752 
753 static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
754 						     char *buf, int size)
755 {
756 	struct ath11k_bp_stats *bp_stats;
757 	bool stats_rxd = false;
758 	u8 i, pdev_idx;
759 	int len = 0;
760 
761 	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
762 	len += scnprintf(buf + len, size - len, "==================\n");
763 
764 	spin_lock_bh(&ab->base_lock);
765 	for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
766 		bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
767 
768 		if (!bp_stats->count)
769 			continue;
770 
771 		len += scnprintf(buf + len, size - len, "Ring: %s\n",
772 				 htt_bp_umac_ring[i]);
773 		len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
774 		stats_rxd = true;
775 	}
776 
777 	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
778 		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
779 			bp_stats =
780 				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
781 
782 			if (!bp_stats->count)
783 				continue;
784 
785 			len += scnprintf(buf + len, size - len, "Ring: %s\n",
786 					 htt_bp_lmac_ring[i]);
787 			len += scnprintf(buf + len, size - len, "pdev: %d\n",
788 					 pdev_idx);
789 			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
790 			stats_rxd = true;
791 		}
792 	}
793 	spin_unlock_bh(&ab->base_lock);
794 
795 	if (!stats_rxd)
796 		len += scnprintf(buf + len, size - len,
797 				 "No Ring Backpressure stats received\n\n");
798 
799 	return len;
800 }
801 
802 static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
803 						char __user *user_buf,
804 						size_t count, loff_t *ppos)
805 {
806 	struct ath11k_base *ab = file->private_data;
807 	struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
808 	int len = 0, i, retval;
809 	const int size = 4096;
810 	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
811 			"Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
812 			"Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
813 			"AMSDU parse", "SA timeout", "DA timeout",
814 			"Flow timeout", "Flush req"};
815 	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
816 			"Desc addr zero", "Desc inval", "AMPDU in non BA",
817 			"Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
818 			"Frame OOR", "BAR OOR", "No BA session",
819 			"Frame SN equal SSN", "PN check fail", "2k err",
820 			"PN err", "Desc blocked"};
821 
822 	char *buf;
823 
824 	buf = kzalloc(size, GFP_KERNEL);
825 	if (!buf)
826 		return -ENOMEM;
827 
828 	len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
829 	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
830 			 soc_stats->err_ring_pkts);
831 	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
832 			 soc_stats->invalid_rbm);
833 	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
834 	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
835 		len += scnprintf(buf + len, size - len, "%s: %u\n",
836 				 rxdma_err[i], soc_stats->rxdma_error[i]);
837 
838 	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
839 	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
840 		len += scnprintf(buf + len, size - len, "%s: %u\n",
841 				 reo_err[i], soc_stats->reo_error[i]);
842 
843 	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
844 	len += scnprintf(buf + len, size - len,
845 			 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
846 			 soc_stats->hal_reo_error[0],
847 			 soc_stats->hal_reo_error[1],
848 			 soc_stats->hal_reo_error[2],
849 			 soc_stats->hal_reo_error[3]);
850 
851 	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
852 	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
853 
854 	for (i = 0; i < ab->hw_params.max_tx_ring; i++)
855 		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
856 				 i, soc_stats->tx_err.desc_na[i]);
857 
858 	len += scnprintf(buf + len, size - len,
859 			 "\nMisc Transmit Failures: %d\n",
860 			 atomic_read(&soc_stats->tx_err.misc_fail));
861 
862 	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
863 
864 	if (len > size)
865 		len = size;
866 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
867 	kfree(buf);
868 
869 	return retval;
870 }
871 
872 static const struct file_operations fops_soc_dp_stats = {
873 	.read = ath11k_debugfs_dump_soc_dp_stats,
874 	.open = simple_open,
875 	.owner = THIS_MODULE,
876 	.llseek = default_llseek,
877 };
878 
879 int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
880 {
881 	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
882 		return 0;
883 
884 	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
885 	if (IS_ERR(ab->debugfs_soc))
886 		return PTR_ERR(ab->debugfs_soc);
887 
888 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
889 			    &fops_simulate_fw_crash);
890 
891 	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
892 			    &fops_soc_dp_stats);
893 
894 	return 0;
895 }
896 
897 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
898 {
899 	debugfs_remove_recursive(ab->debugfs_soc);
900 	ab->debugfs_soc = NULL;
901 }
902 
903 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
904 {
905 	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
906 
907 	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
908 }
909 
910 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
911 {
912 	debugfs_remove_recursive(ab->debugfs_ath11k);
913 	ab->debugfs_ath11k = NULL;
914 }
915 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
916 
917 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
918 {
919 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
920 							ar->debug.debugfs_pdev);
921 
922 	ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
923 
924 	/* all stats debugfs files created are under "fw_stats" directory
925 	 * created per PDEV
926 	 */
927 	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
928 			    &fops_pdev_stats);
929 	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
930 			    &fops_vdev_stats);
931 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
932 			    &fops_bcn_stats);
933 
934 	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
935 	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
936 	INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
937 
938 	init_completion(&ar->debug.fw_stats_complete);
939 }
940 
941 static ssize_t ath11k_write_pktlog_filter(struct file *file,
942 					  const char __user *ubuf,
943 					  size_t count, loff_t *ppos)
944 {
945 	struct ath11k *ar = file->private_data;
946 	struct ath11k_base *ab = ar->ab;
947 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
948 	u32 rx_filter = 0, ring_id, filter, mode;
949 	u8 buf[128] = {0};
950 	int i, ret, rx_buf_sz = 0;
951 	ssize_t rc;
952 
953 	mutex_lock(&ar->conf_mutex);
954 	if (ar->state != ATH11K_STATE_ON) {
955 		ret = -ENETDOWN;
956 		goto out;
957 	}
958 
959 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
960 	if (rc < 0) {
961 		ret = rc;
962 		goto out;
963 	}
964 	buf[rc] = '\0';
965 
966 	ret = sscanf(buf, "0x%x %u", &filter, &mode);
967 	if (ret != 2) {
968 		ret = -EINVAL;
969 		goto out;
970 	}
971 
972 	if (filter) {
973 		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
974 		if (ret) {
975 			ath11k_warn(ar->ab,
976 				    "failed to enable pktlog filter %x: %d\n",
977 				    ar->debug.pktlog_filter, ret);
978 			goto out;
979 		}
980 	} else {
981 		ret = ath11k_wmi_pdev_pktlog_disable(ar);
982 		if (ret) {
983 			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
984 			goto out;
985 		}
986 	}
987 
988 	/* Clear rx filter set for monitor mode and rx status */
989 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
990 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
991 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
992 						       HAL_RXDMA_MONITOR_STATUS,
993 						       rx_buf_sz, &tlv_filter);
994 		if (ret) {
995 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
996 			goto out;
997 		}
998 	}
999 #define HTT_RX_FILTER_TLV_LITE_MODE \
1000 			(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1001 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1002 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1003 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1004 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1005 			HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1006 
1007 	if (mode == ATH11K_PKTLOG_MODE_FULL) {
1008 		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1009 			    HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1010 			    HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1011 			    HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1012 			    HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1013 			    HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1014 		rx_buf_sz = DP_RX_BUFFER_SIZE;
1015 	} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1016 		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1017 							  HTT_PPDU_STATS_TAG_PKTLOG);
1018 		if (ret) {
1019 			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1020 			goto out;
1021 		}
1022 
1023 		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1024 		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1025 	} else {
1026 		rx_buf_sz = DP_RX_BUFFER_SIZE;
1027 		tlv_filter = ath11k_mac_mon_status_filter_default;
1028 		rx_filter = tlv_filter.rx_filter;
1029 
1030 		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1031 							  HTT_PPDU_STATS_TAG_DEFAULT);
1032 		if (ret) {
1033 			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1034 				   ret);
1035 			goto out;
1036 		}
1037 	}
1038 
1039 	tlv_filter.rx_filter = rx_filter;
1040 	if (rx_filter) {
1041 		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1042 		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1043 		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1044 		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1045 					       HTT_RX_FP_DATA_FILTER_FLASG3;
1046 	}
1047 
1048 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1049 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1050 		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1051 						       ar->dp.mac_id + i,
1052 						       HAL_RXDMA_MONITOR_STATUS,
1053 						       rx_buf_sz, &tlv_filter);
1054 
1055 		if (ret) {
1056 			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1057 			goto out;
1058 		}
1059 	}
1060 
1061 	ath11k_info(ab, "pktlog mode %s\n",
1062 		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1063 
1064 	ar->debug.pktlog_filter = filter;
1065 	ar->debug.pktlog_mode = mode;
1066 	ret = count;
1067 
1068 out:
1069 	mutex_unlock(&ar->conf_mutex);
1070 	return ret;
1071 }
1072 
1073 static ssize_t ath11k_read_pktlog_filter(struct file *file,
1074 					 char __user *ubuf,
1075 					 size_t count, loff_t *ppos)
1076 
1077 {
1078 	char buf[32] = {0};
1079 	struct ath11k *ar = file->private_data;
1080 	int len = 0;
1081 
1082 	mutex_lock(&ar->conf_mutex);
1083 	len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1084 			ar->debug.pktlog_filter,
1085 			ar->debug.pktlog_mode);
1086 	mutex_unlock(&ar->conf_mutex);
1087 
1088 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1089 }
1090 
1091 static const struct file_operations fops_pktlog_filter = {
1092 	.read = ath11k_read_pktlog_filter,
1093 	.write = ath11k_write_pktlog_filter,
1094 	.open = simple_open
1095 };
1096 
1097 static ssize_t ath11k_write_simulate_radar(struct file *file,
1098 					   const char __user *user_buf,
1099 					   size_t count, loff_t *ppos)
1100 {
1101 	struct ath11k *ar = file->private_data;
1102 	int ret;
1103 
1104 	ret = ath11k_wmi_simulate_radar(ar);
1105 	if (ret)
1106 		return ret;
1107 
1108 	return count;
1109 }
1110 
1111 static const struct file_operations fops_simulate_radar = {
1112 	.write = ath11k_write_simulate_radar,
1113 	.open = simple_open
1114 };
1115 
1116 int ath11k_debugfs_register(struct ath11k *ar)
1117 {
1118 	struct ath11k_base *ab = ar->ab;
1119 	char pdev_name[5];
1120 	char buf[100] = {0};
1121 
1122 	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1123 
1124 	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1125 	if (IS_ERR(ar->debug.debugfs_pdev))
1126 		return PTR_ERR(ar->debug.debugfs_pdev);
1127 
1128 	/* Create a symlink under ieee80211/phy* */
1129 	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1130 	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1131 
1132 	ath11k_debugfs_htt_stats_init(ar);
1133 
1134 	ath11k_debugfs_fw_stats_init(ar);
1135 
1136 	debugfs_create_file("ext_tx_stats", 0644,
1137 			    ar->debug.debugfs_pdev, ar,
1138 			    &fops_extd_tx_stats);
1139 	debugfs_create_file("ext_rx_stats", 0644,
1140 			    ar->debug.debugfs_pdev, ar,
1141 			    &fops_extd_rx_stats);
1142 	debugfs_create_file("pktlog_filter", 0644,
1143 			    ar->debug.debugfs_pdev, ar,
1144 			    &fops_pktlog_filter);
1145 
1146 	if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1147 		debugfs_create_file("dfs_simulate_radar", 0200,
1148 				    ar->debug.debugfs_pdev, ar,
1149 				    &fops_simulate_radar);
1150 		debugfs_create_bool("dfs_block_radar_events", 0200,
1151 				    ar->debug.debugfs_pdev,
1152 				    &ar->dfs_block_radar_events);
1153 	}
1154 
1155 	return 0;
1156 }
1157 
1158 void ath11k_debugfs_unregister(struct ath11k *ar)
1159 {
1160 }
1161