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