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