xref: /openbmc/linux/drivers/net/wireless/ath/ath11k/debugfs_sta.c (revision 7e24a55b2122746c2eef192296fc84624354f895)
1d5c65159SKalle Valo // SPDX-License-Identifier: BSD-3-Clause-Clear
2d5c65159SKalle Valo /*
3d5c65159SKalle Valo  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4*586c7fb1SJeff Johnson  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
5d5c65159SKalle Valo  */
6d5c65159SKalle Valo 
7d5c65159SKalle Valo #include <linux/vmalloc.h>
8d5c65159SKalle Valo 
9568f0603SKalle Valo #include "debugfs_sta.h"
10d5c65159SKalle Valo #include "core.h"
11d5c65159SKalle Valo #include "peer.h"
12d5c65159SKalle Valo #include "debug.h"
13559ef68fSAshok Raj Nagarajan #include "dp_tx.h"
1456292162SKalle Valo #include "debugfs_htt_stats.h"
15d5c65159SKalle Valo 
ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta * arsta,struct ath11k_per_peer_tx_stats * peer_stats,u8 legacy_rate_idx)16568f0603SKalle Valo void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta,
17d5c65159SKalle Valo 				     struct ath11k_per_peer_tx_stats *peer_stats,
18d5c65159SKalle Valo 				     u8 legacy_rate_idx)
19d5c65159SKalle Valo {
20d5c65159SKalle Valo 	struct rate_info *txrate = &arsta->txrate;
21d5c65159SKalle Valo 	struct ath11k_htt_tx_stats *tx_stats;
22d5c65159SKalle Valo 	int gi, mcs, bw, nss;
23d5c65159SKalle Valo 
24d5c65159SKalle Valo 	if (!arsta->tx_stats)
25d5c65159SKalle Valo 		return;
26d5c65159SKalle Valo 
27d5c65159SKalle Valo 	tx_stats = arsta->tx_stats;
28d5c65159SKalle Valo 	gi = FIELD_GET(RATE_INFO_FLAGS_SHORT_GI, arsta->txrate.flags);
29d5c65159SKalle Valo 	mcs = txrate->mcs;
3092bacd1cSVenkateswara Naralasetty 	bw = ath11k_mac_mac80211_bw_to_ath11k_bw(txrate->bw);
31d5c65159SKalle Valo 	nss = txrate->nss - 1;
32d5c65159SKalle Valo 
33d5c65159SKalle Valo #define STATS_OP_FMT(name) tx_stats->stats[ATH11K_STATS_TYPE_##name]
34d5c65159SKalle Valo 
35d5c65159SKalle Valo 	if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
36d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).he[0][mcs] += peer_stats->succ_bytes;
37d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).he[1][mcs] += peer_stats->succ_pkts;
38d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).he[0][mcs] += peer_stats->failed_bytes;
39d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).he[1][mcs] += peer_stats->failed_pkts;
40d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).he[0][mcs] += peer_stats->retry_bytes;
41d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).he[1][mcs] += peer_stats->retry_pkts;
42d5c65159SKalle Valo 	} else if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) {
43d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).vht[0][mcs] += peer_stats->succ_bytes;
44d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).vht[1][mcs] += peer_stats->succ_pkts;
45d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).vht[0][mcs] += peer_stats->failed_bytes;
46d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).vht[1][mcs] += peer_stats->failed_pkts;
47d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).vht[0][mcs] += peer_stats->retry_bytes;
48d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).vht[1][mcs] += peer_stats->retry_pkts;
49d5c65159SKalle Valo 	} else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
50d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).ht[0][mcs] += peer_stats->succ_bytes;
51d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).ht[1][mcs] += peer_stats->succ_pkts;
52d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).ht[0][mcs] += peer_stats->failed_bytes;
53d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).ht[1][mcs] += peer_stats->failed_pkts;
54d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).ht[0][mcs] += peer_stats->retry_bytes;
55d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).ht[1][mcs] += peer_stats->retry_pkts;
56d5c65159SKalle Valo 	} else {
57d5c65159SKalle Valo 		mcs = legacy_rate_idx;
58d5c65159SKalle Valo 
59d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).legacy[0][mcs] += peer_stats->succ_bytes;
60d5c65159SKalle Valo 		STATS_OP_FMT(SUCC).legacy[1][mcs] += peer_stats->succ_pkts;
61d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).legacy[0][mcs] += peer_stats->failed_bytes;
62d5c65159SKalle Valo 		STATS_OP_FMT(FAIL).legacy[1][mcs] += peer_stats->failed_pkts;
63d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).legacy[0][mcs] += peer_stats->retry_bytes;
64d5c65159SKalle Valo 		STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts;
65d5c65159SKalle Valo 	}
66d5c65159SKalle Valo 
67d5c65159SKalle Valo 	if (peer_stats->is_ampdu) {
68d5c65159SKalle Valo 		tx_stats->ba_fails += peer_stats->ba_fails;
69d5c65159SKalle Valo 
70d5c65159SKalle Valo 		if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
71d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).he[0][mcs] +=
72d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
73d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).he[1][mcs] +=
74d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
75d5c65159SKalle Valo 		} else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
76d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).ht[0][mcs] +=
77d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
78d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).ht[1][mcs] +=
79d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
80d5c65159SKalle Valo 		} else {
81d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).vht[0][mcs] +=
82d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
83d5c65159SKalle Valo 			STATS_OP_FMT(AMPDU).vht[1][mcs] +=
84d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
85d5c65159SKalle Valo 		}
86d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).bw[0][bw] +=
87d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
88d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).nss[0][nss] +=
89d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
90d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).gi[0][gi] +=
91d5c65159SKalle Valo 			peer_stats->succ_bytes + peer_stats->retry_bytes;
92d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).bw[1][bw] +=
93d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
94d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).nss[1][nss] +=
95d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
96d5c65159SKalle Valo 		STATS_OP_FMT(AMPDU).gi[1][gi] +=
97d5c65159SKalle Valo 			peer_stats->succ_pkts + peer_stats->retry_pkts;
98d5c65159SKalle Valo 	} else {
99d5c65159SKalle Valo 		tx_stats->ack_fails += peer_stats->ba_fails;
100d5c65159SKalle Valo 	}
101d5c65159SKalle Valo 
102d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).bw[0][bw] += peer_stats->succ_bytes;
103d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).nss[0][nss] += peer_stats->succ_bytes;
104d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).gi[0][gi] += peer_stats->succ_bytes;
105d5c65159SKalle Valo 
106d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).bw[1][bw] += peer_stats->succ_pkts;
107d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).nss[1][nss] += peer_stats->succ_pkts;
108d5c65159SKalle Valo 	STATS_OP_FMT(SUCC).gi[1][gi] += peer_stats->succ_pkts;
109d5c65159SKalle Valo 
110d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).bw[0][bw] += peer_stats->failed_bytes;
111d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).nss[0][nss] += peer_stats->failed_bytes;
112d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).gi[0][gi] += peer_stats->failed_bytes;
113d5c65159SKalle Valo 
114d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).bw[1][bw] += peer_stats->failed_pkts;
115d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).nss[1][nss] += peer_stats->failed_pkts;
116d5c65159SKalle Valo 	STATS_OP_FMT(FAIL).gi[1][gi] += peer_stats->failed_pkts;
117d5c65159SKalle Valo 
118d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).bw[0][bw] += peer_stats->retry_bytes;
119d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).nss[0][nss] += peer_stats->retry_bytes;
120d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).gi[0][gi] += peer_stats->retry_bytes;
121d5c65159SKalle Valo 
122d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).bw[1][bw] += peer_stats->retry_pkts;
123d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).nss[1][nss] += peer_stats->retry_pkts;
124d5c65159SKalle Valo 	STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts;
125d5c65159SKalle Valo 
126d5c65159SKalle Valo 	tx_stats->tx_duration += peer_stats->duration;
127d5c65159SKalle Valo }
128d5c65159SKalle Valo 
ath11k_debugfs_sta_update_txcompl(struct ath11k * ar,struct hal_tx_status * ts)129568f0603SKalle Valo void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar,
130d5c65159SKalle Valo 				       struct hal_tx_status *ts)
131d5c65159SKalle Valo {
1321b8bb94cSWen Gong 	ath11k_dp_tx_update_txcompl(ar, ts);
133d5c65159SKalle Valo }
134d5c65159SKalle Valo 
ath11k_dbg_sta_dump_tx_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)135d5c65159SKalle Valo static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file,
136d5c65159SKalle Valo 					    char __user *user_buf,
137d5c65159SKalle Valo 					    size_t count, loff_t *ppos)
138d5c65159SKalle Valo {
139d5c65159SKalle Valo 	struct ieee80211_sta *sta = file->private_data;
140d5c65159SKalle Valo 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
141d5c65159SKalle Valo 	struct ath11k *ar = arsta->arvif->ar;
142d5c65159SKalle Valo 	struct ath11k_htt_data_stats *stats;
143d5c65159SKalle Valo 	static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail",
144d5c65159SKalle Valo 							      "retry", "ampdu"};
145d5c65159SKalle Valo 	static const char *str[ATH11K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
146d5c65159SKalle Valo 	int len = 0, i, j, k, retval = 0;
147d5c65159SKalle Valo 	const int size = 2 * 4096;
148d5c65159SKalle Valo 	char *buf;
149d5c65159SKalle Valo 
150fe0ebb51SPravas Kumar Panda 	if (!arsta->tx_stats)
151fe0ebb51SPravas Kumar Panda 		return -ENOENT;
152fe0ebb51SPravas Kumar Panda 
153d5c65159SKalle Valo 	buf = kzalloc(size, GFP_KERNEL);
154d5c65159SKalle Valo 	if (!buf)
155d5c65159SKalle Valo 		return -ENOMEM;
156d5c65159SKalle Valo 
157d5c65159SKalle Valo 	mutex_lock(&ar->conf_mutex);
158d5c65159SKalle Valo 
159d5c65159SKalle Valo 	spin_lock_bh(&ar->data_lock);
160d5c65159SKalle Valo 	for (k = 0; k < ATH11K_STATS_TYPE_MAX; k++) {
161d5c65159SKalle Valo 		for (j = 0; j < ATH11K_COUNTER_TYPE_MAX; j++) {
162d5c65159SKalle Valo 			stats = &arsta->tx_stats->stats[k];
163d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, "%s_%s\n",
164d5c65159SKalle Valo 					 str_name[k],
165d5c65159SKalle Valo 					 str[j]);
166d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
167d5c65159SKalle Valo 					 " HE MCS %s\n",
168d5c65159SKalle Valo 					 str[j]);
169d5c65159SKalle Valo 			for (i = 0; i < ATH11K_HE_MCS_NUM; i++)
170d5c65159SKalle Valo 				len += scnprintf(buf + len, size - len,
171d5c65159SKalle Valo 						 "  %llu ",
172d5c65159SKalle Valo 						 stats->he[j][i]);
173d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, "\n");
174d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
175d5c65159SKalle Valo 					 " VHT MCS %s\n",
176d5c65159SKalle Valo 					 str[j]);
177d5c65159SKalle Valo 			for (i = 0; i < ATH11K_VHT_MCS_NUM; i++)
178d5c65159SKalle Valo 				len += scnprintf(buf + len, size - len,
179d5c65159SKalle Valo 						 "  %llu ",
180d5c65159SKalle Valo 						 stats->vht[j][i]);
181d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, "\n");
182d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, " HT MCS %s\n",
183d5c65159SKalle Valo 					 str[j]);
184d5c65159SKalle Valo 			for (i = 0; i < ATH11K_HT_MCS_NUM; i++)
185d5c65159SKalle Valo 				len += scnprintf(buf + len, size - len,
186d5c65159SKalle Valo 						 "  %llu ", stats->ht[j][i]);
187d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, "\n");
188d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
189d5c65159SKalle Valo 					" BW %s (20,40,80,160 MHz)\n", str[j]);
190d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
191d5c65159SKalle Valo 					 "  %llu %llu %llu %llu\n",
192d5c65159SKalle Valo 					 stats->bw[j][0], stats->bw[j][1],
193d5c65159SKalle Valo 					 stats->bw[j][2], stats->bw[j][3]);
194d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
195d5c65159SKalle Valo 					 " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
196d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
197d5c65159SKalle Valo 					 "  %llu %llu %llu %llu\n",
198d5c65159SKalle Valo 					 stats->nss[j][0], stats->nss[j][1],
199d5c65159SKalle Valo 					 stats->nss[j][2], stats->nss[j][3]);
200d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
201d5c65159SKalle Valo 					 " GI %s (0.4us,0.8us,1.6us,3.2us)\n",
202d5c65159SKalle Valo 					 str[j]);
203d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
204d5c65159SKalle Valo 					 "  %llu %llu %llu %llu\n",
205d5c65159SKalle Valo 					 stats->gi[j][0], stats->gi[j][1],
206d5c65159SKalle Valo 					 stats->gi[j][2], stats->gi[j][3]);
207d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len,
208d5c65159SKalle Valo 					 " legacy rate %s (1,2 ... Mbps)\n  ",
209d5c65159SKalle Valo 					 str[j]);
210d5c65159SKalle Valo 			for (i = 0; i < ATH11K_LEGACY_NUM; i++)
211d5c65159SKalle Valo 				len += scnprintf(buf + len, size - len, "%llu ",
212d5c65159SKalle Valo 						 stats->legacy[j][i]);
213d5c65159SKalle Valo 			len += scnprintf(buf + len, size - len, "\n");
214d5c65159SKalle Valo 		}
215d5c65159SKalle Valo 	}
216d5c65159SKalle Valo 
217d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
218d5c65159SKalle Valo 			 "\nTX duration\n %llu usecs\n",
219d5c65159SKalle Valo 			 arsta->tx_stats->tx_duration);
220d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
221d5c65159SKalle Valo 			"BA fails\n %llu\n", arsta->tx_stats->ba_fails);
222d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
223d5c65159SKalle Valo 			"ack fails\n %llu\n", arsta->tx_stats->ack_fails);
224d5c65159SKalle Valo 	spin_unlock_bh(&ar->data_lock);
225d5c65159SKalle Valo 
226d5c65159SKalle Valo 	if (len > size)
227d5c65159SKalle Valo 		len = size;
228d5c65159SKalle Valo 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
229d5c65159SKalle Valo 	kfree(buf);
230d5c65159SKalle Valo 
231d5c65159SKalle Valo 	mutex_unlock(&ar->conf_mutex);
232d5c65159SKalle Valo 	return retval;
233d5c65159SKalle Valo }
234d5c65159SKalle Valo 
235d5c65159SKalle Valo static const struct file_operations fops_tx_stats = {
236d5c65159SKalle Valo 	.read = ath11k_dbg_sta_dump_tx_stats,
237d5c65159SKalle Valo 	.open = simple_open,
238d5c65159SKalle Valo 	.owner = THIS_MODULE,
239d5c65159SKalle Valo 	.llseek = default_llseek,
240d5c65159SKalle Valo };
241d5c65159SKalle Valo 
ath11k_dbg_sta_dump_rx_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)242d5c65159SKalle Valo static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file,
243d5c65159SKalle Valo 					    char __user *user_buf,
244d5c65159SKalle Valo 					    size_t count, loff_t *ppos)
245d5c65159SKalle Valo {
246d5c65159SKalle Valo 	struct ieee80211_sta *sta = file->private_data;
247d5c65159SKalle Valo 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
248d5c65159SKalle Valo 	struct ath11k *ar = arsta->arvif->ar;
249d5c65159SKalle Valo 	struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
250d5c65159SKalle Valo 	int len = 0, i, retval = 0;
251d5c65159SKalle Valo 	const int size = 4096;
252d5c65159SKalle Valo 	char *buf;
253d5c65159SKalle Valo 
254d5c65159SKalle Valo 	if (!rx_stats)
255d5c65159SKalle Valo 		return -ENOENT;
256d5c65159SKalle Valo 
257d5c65159SKalle Valo 	buf = kzalloc(size, GFP_KERNEL);
258d5c65159SKalle Valo 	if (!buf)
259d5c65159SKalle Valo 		return -ENOMEM;
260d5c65159SKalle Valo 
261d5c65159SKalle Valo 	mutex_lock(&ar->conf_mutex);
262d5c65159SKalle Valo 	spin_lock_bh(&ar->ab->base_lock);
263d5c65159SKalle Valo 
264d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "RX peer stats:\n");
265d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs: %llu\n",
266d5c65159SKalle Valo 			 rx_stats->num_msdu);
267d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs with TCP L4: %llu\n",
268d5c65159SKalle Valo 			 rx_stats->tcp_msdu_count);
269d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs with UDP L4: %llu\n",
270d5c65159SKalle Valo 			 rx_stats->udp_msdu_count);
271d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs part of AMPDU: %llu\n",
272d5c65159SKalle Valo 			 rx_stats->ampdu_msdu_count);
273d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs not part of AMPDU: %llu\n",
274d5c65159SKalle Valo 			 rx_stats->non_ampdu_msdu_count);
275d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs using STBC: %llu\n",
276d5c65159SKalle Valo 			 rx_stats->stbc_count);
277d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MSDUs beamformed: %llu\n",
278d5c65159SKalle Valo 			 rx_stats->beamformed_count);
279d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS ok: %llu\n",
280d5c65159SKalle Valo 			 rx_stats->num_mpdu_fcs_ok);
281d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS error: %llu\n",
282d5c65159SKalle Valo 			 rx_stats->num_mpdu_fcs_err);
283d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
284d5c65159SKalle Valo 			 "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
285d5c65159SKalle Valo 			 rx_stats->gi_count[0], rx_stats->gi_count[1],
286d5c65159SKalle Valo 			 rx_stats->gi_count[2], rx_stats->gi_count[3]);
287d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
288d5c65159SKalle Valo 			 "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
289d5c65159SKalle Valo 			 rx_stats->bw_count[0], rx_stats->bw_count[1],
290d5c65159SKalle Valo 			 rx_stats->bw_count[2], rx_stats->bw_count[3]);
291d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "BCC %llu LDPC %llu\n",
292d5c65159SKalle Valo 			 rx_stats->coding_count[0], rx_stats->coding_count[1]);
293d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
294d5c65159SKalle Valo 			 "preamble: 11A %llu 11B %llu 11N %llu 11AC %llu 11AX %llu\n",
295d5c65159SKalle Valo 			 rx_stats->pream_cnt[0], rx_stats->pream_cnt[1],
296d5c65159SKalle Valo 			 rx_stats->pream_cnt[2], rx_stats->pream_cnt[3],
297d5c65159SKalle Valo 			 rx_stats->pream_cnt[4]);
298d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len,
299d5c65159SKalle Valo 			 "reception type: SU %llu MU_MIMO %llu MU_OFDMA %llu MU_OFDMA_MIMO %llu\n",
300d5c65159SKalle Valo 			 rx_stats->reception_type[0], rx_stats->reception_type[1],
301d5c65159SKalle Valo 			 rx_stats->reception_type[2], rx_stats->reception_type[3]);
302d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "TID(0-15) Legacy TID(16):");
303d5c65159SKalle Valo 	for (i = 0; i <= IEEE80211_NUM_TIDS; i++)
304d5c65159SKalle Valo 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->tid_count[i]);
305d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):");
306d5c65159SKalle Valo 	for (i = 0; i < HAL_RX_MAX_MCS + 1; i++)
307d5c65159SKalle Valo 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]);
308d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "\nNSS(1-8):");
309d5c65159SKalle Valo 	for (i = 0; i < HAL_RX_MAX_NSS; i++)
310d5c65159SKalle Valo 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]);
311d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ",
312d5c65159SKalle Valo 			 rx_stats->rx_duration);
3136a0c3702SJohn Crispin 	len += scnprintf(buf + len, size - len,
3146a0c3702SJohn Crispin 			 "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n",
3156a0c3702SJohn Crispin 			 rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
3166a0c3702SJohn Crispin 			 rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2],
3176a0c3702SJohn Crispin 			 rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4],
3186a0c3702SJohn Crispin 			 rx_stats->ru_alloc_cnt[5]);
3196a0c3702SJohn Crispin 
320d5c65159SKalle Valo 	len += scnprintf(buf + len, size - len, "\n");
321d5c65159SKalle Valo 
322d5c65159SKalle Valo 	spin_unlock_bh(&ar->ab->base_lock);
323d5c65159SKalle Valo 
324d5c65159SKalle Valo 	if (len > size)
325d5c65159SKalle Valo 		len = size;
326d5c65159SKalle Valo 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
327d5c65159SKalle Valo 	kfree(buf);
328d5c65159SKalle Valo 
329d5c65159SKalle Valo 	mutex_unlock(&ar->conf_mutex);
330d5c65159SKalle Valo 	return retval;
331d5c65159SKalle Valo }
332d5c65159SKalle Valo 
333d5c65159SKalle Valo static const struct file_operations fops_rx_stats = {
334d5c65159SKalle Valo 	.read = ath11k_dbg_sta_dump_rx_stats,
335d5c65159SKalle Valo 	.open = simple_open,
336d5c65159SKalle Valo 	.owner = THIS_MODULE,
337d5c65159SKalle Valo 	.llseek = default_llseek,
338d5c65159SKalle Valo };
339d5c65159SKalle Valo 
340d5c65159SKalle Valo static int
ath11k_dbg_sta_open_htt_peer_stats(struct inode * inode,struct file * file)341d5c65159SKalle Valo ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file)
342d5c65159SKalle Valo {
343d5c65159SKalle Valo 	struct ieee80211_sta *sta = inode->i_private;
344d5c65159SKalle Valo 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
345d5c65159SKalle Valo 	struct ath11k *ar = arsta->arvif->ar;
346d5c65159SKalle Valo 	struct debug_htt_stats_req *stats_req;
347ac83b603SVenkateswara Naralasetty 	int type = ar->debug.htt_stats.type;
348d5c65159SKalle Valo 	int ret;
349d5c65159SKalle Valo 
350ac83b603SVenkateswara Naralasetty 	if ((type != ATH11K_DBG_HTT_EXT_STATS_PEER_INFO &&
351ac83b603SVenkateswara Naralasetty 	     type != ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) ||
352ac83b603SVenkateswara Naralasetty 	    type == ATH11K_DBG_HTT_EXT_STATS_RESET)
353ac83b603SVenkateswara Naralasetty 		return -EPERM;
354ac83b603SVenkateswara Naralasetty 
355d5c65159SKalle Valo 	stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE);
356d5c65159SKalle Valo 	if (!stats_req)
357d5c65159SKalle Valo 		return -ENOMEM;
358d5c65159SKalle Valo 
359d5c65159SKalle Valo 	mutex_lock(&ar->conf_mutex);
360d5c65159SKalle Valo 	ar->debug.htt_stats.stats_req = stats_req;
361ac83b603SVenkateswara Naralasetty 	stats_req->type = type;
362d5c65159SKalle Valo 	memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN);
363568f0603SKalle Valo 	ret = ath11k_debugfs_htt_stats_req(ar);
364d5c65159SKalle Valo 	mutex_unlock(&ar->conf_mutex);
365d5c65159SKalle Valo 	if (ret < 0)
366d5c65159SKalle Valo 		goto out;
367d5c65159SKalle Valo 
368d5c65159SKalle Valo 	file->private_data = stats_req;
369d5c65159SKalle Valo 	return 0;
370d5c65159SKalle Valo out:
371d5c65159SKalle Valo 	vfree(stats_req);
37252f274b5SSowmiya Sree Elavalagan 	ar->debug.htt_stats.stats_req = NULL;
373d5c65159SKalle Valo 	return ret;
374d5c65159SKalle Valo }
375d5c65159SKalle Valo 
376d5c65159SKalle Valo static int
ath11k_dbg_sta_release_htt_peer_stats(struct inode * inode,struct file * file)377d5c65159SKalle Valo ath11k_dbg_sta_release_htt_peer_stats(struct inode *inode, struct file *file)
378d5c65159SKalle Valo {
37952f274b5SSowmiya Sree Elavalagan 	struct ieee80211_sta *sta = inode->i_private;
38052f274b5SSowmiya Sree Elavalagan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
38152f274b5SSowmiya Sree Elavalagan 	struct ath11k *ar = arsta->arvif->ar;
38252f274b5SSowmiya Sree Elavalagan 
38352f274b5SSowmiya Sree Elavalagan 	mutex_lock(&ar->conf_mutex);
384d5c65159SKalle Valo 	vfree(file->private_data);
38552f274b5SSowmiya Sree Elavalagan 	ar->debug.htt_stats.stats_req = NULL;
38652f274b5SSowmiya Sree Elavalagan 	mutex_unlock(&ar->conf_mutex);
38752f274b5SSowmiya Sree Elavalagan 
388d5c65159SKalle Valo 	return 0;
389d5c65159SKalle Valo }
390d5c65159SKalle Valo 
ath11k_dbg_sta_read_htt_peer_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)391d5c65159SKalle Valo static ssize_t ath11k_dbg_sta_read_htt_peer_stats(struct file *file,
392d5c65159SKalle Valo 						  char __user *user_buf,
393d5c65159SKalle Valo 						  size_t count, loff_t *ppos)
394d5c65159SKalle Valo {
395d5c65159SKalle Valo 	struct debug_htt_stats_req *stats_req = file->private_data;
396d5c65159SKalle Valo 	char *buf;
397d5c65159SKalle Valo 	u32 length = 0;
398d5c65159SKalle Valo 
399d5c65159SKalle Valo 	buf = stats_req->buf;
400d5c65159SKalle Valo 	length = min_t(u32, stats_req->buf_len, ATH11K_HTT_STATS_BUF_SIZE);
401d5c65159SKalle Valo 	return simple_read_from_buffer(user_buf, count, ppos, buf, length);
402d5c65159SKalle Valo }
403d5c65159SKalle Valo 
404d5c65159SKalle Valo static const struct file_operations fops_htt_peer_stats = {
405d5c65159SKalle Valo 	.open = ath11k_dbg_sta_open_htt_peer_stats,
406d5c65159SKalle Valo 	.release = ath11k_dbg_sta_release_htt_peer_stats,
407d5c65159SKalle Valo 	.read = ath11k_dbg_sta_read_htt_peer_stats,
408d5c65159SKalle Valo 	.owner = THIS_MODULE,
409d5c65159SKalle Valo 	.llseek = default_llseek,
410d5c65159SKalle Valo };
411d5c65159SKalle Valo 
ath11k_dbg_sta_write_peer_pktlog(struct file * file,const char __user * buf,size_t count,loff_t * ppos)412d5c65159SKalle Valo static ssize_t ath11k_dbg_sta_write_peer_pktlog(struct file *file,
413d5c65159SKalle Valo 						const char __user *buf,
414d5c65159SKalle Valo 						size_t count, loff_t *ppos)
415d5c65159SKalle Valo {
416d5c65159SKalle Valo 	struct ieee80211_sta *sta = file->private_data;
417d5c65159SKalle Valo 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
418d5c65159SKalle Valo 	struct ath11k *ar = arsta->arvif->ar;
419d5c65159SKalle Valo 	int ret, enable;
420d5c65159SKalle Valo 
421d5c65159SKalle Valo 	mutex_lock(&ar->conf_mutex);
422d5c65159SKalle Valo 
423d5c65159SKalle Valo 	if (ar->state != ATH11K_STATE_ON) {
424d5c65159SKalle Valo 		ret = -ENETDOWN;
425d5c65159SKalle Valo 		goto out;
426d5c65159SKalle Valo 	}
427d5c65159SKalle Valo 
428d5c65159SKalle Valo 	ret = kstrtoint_from_user(buf, count, 0, &enable);
429d5c65159SKalle Valo 	if (ret)
430d5c65159SKalle Valo 		goto out;
431d5c65159SKalle Valo 
432d5c65159SKalle Valo 	ar->debug.pktlog_peer_valid = enable;
433d5c65159SKalle Valo 	memcpy(ar->debug.pktlog_peer_addr, sta->addr, ETH_ALEN);
434d5c65159SKalle Valo 
435d5c65159SKalle Valo 	/* Send peer based pktlog enable/disable */
436d5c65159SKalle Valo 	ret = ath11k_wmi_pdev_peer_pktlog_filter(ar, sta->addr, enable);
437d5c65159SKalle Valo 	if (ret) {
438d5c65159SKalle Valo 		ath11k_warn(ar->ab, "failed to set peer pktlog filter %pM: %d\n",
439d5c65159SKalle Valo 			    sta->addr, ret);
440d5c65159SKalle Valo 		goto out;
441d5c65159SKalle Valo 	}
442d5c65159SKalle Valo 
443d5c65159SKalle Valo 	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "peer pktlog filter set to %d\n",
444d5c65159SKalle Valo 		   enable);
445d5c65159SKalle Valo 	ret = count;
446d5c65159SKalle Valo 
447d5c65159SKalle Valo out:
448d5c65159SKalle Valo 	mutex_unlock(&ar->conf_mutex);
449d5c65159SKalle Valo 	return ret;
450d5c65159SKalle Valo }
451d5c65159SKalle Valo 
ath11k_dbg_sta_read_peer_pktlog(struct file * file,char __user * ubuf,size_t count,loff_t * ppos)452d5c65159SKalle Valo static ssize_t ath11k_dbg_sta_read_peer_pktlog(struct file *file,
453d5c65159SKalle Valo 					       char __user *ubuf,
454d5c65159SKalle Valo 					       size_t count, loff_t *ppos)
455d5c65159SKalle Valo {
456d5c65159SKalle Valo 	struct ieee80211_sta *sta = file->private_data;
457d5c65159SKalle Valo 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
458d5c65159SKalle Valo 	struct ath11k *ar = arsta->arvif->ar;
459d5c65159SKalle Valo 	char buf[32] = {0};
460d5c65159SKalle Valo 	int len;
461d5c65159SKalle Valo 
462d5c65159SKalle Valo 	mutex_lock(&ar->conf_mutex);
463d5c65159SKalle Valo 	len = scnprintf(buf, sizeof(buf), "%08x %pM\n",
464d5c65159SKalle Valo 			ar->debug.pktlog_peer_valid,
465d5c65159SKalle Valo 			ar->debug.pktlog_peer_addr);
466d5c65159SKalle Valo 	mutex_unlock(&ar->conf_mutex);
467d5c65159SKalle Valo 
468d5c65159SKalle Valo 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
469d5c65159SKalle Valo }
470d5c65159SKalle Valo 
471d5c65159SKalle Valo static const struct file_operations fops_peer_pktlog = {
472d5c65159SKalle Valo 	.write = ath11k_dbg_sta_write_peer_pktlog,
473d5c65159SKalle Valo 	.read = ath11k_dbg_sta_read_peer_pktlog,
474d5c65159SKalle Valo 	.open = simple_open,
475d5c65159SKalle Valo 	.owner = THIS_MODULE,
476d5c65159SKalle Valo 	.llseek = default_llseek,
477d5c65159SKalle Valo };
478d5c65159SKalle Valo 
ath11k_dbg_sta_write_delba(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)4799556dfa2SMaharaja Kennadyrajan static ssize_t ath11k_dbg_sta_write_delba(struct file *file,
4809556dfa2SMaharaja Kennadyrajan 					  const char __user *user_buf,
4819556dfa2SMaharaja Kennadyrajan 					  size_t count, loff_t *ppos)
4829556dfa2SMaharaja Kennadyrajan {
4839556dfa2SMaharaja Kennadyrajan 	struct ieee80211_sta *sta = file->private_data;
4849556dfa2SMaharaja Kennadyrajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
4859556dfa2SMaharaja Kennadyrajan 	struct ath11k *ar = arsta->arvif->ar;
4869556dfa2SMaharaja Kennadyrajan 	u32 tid, initiator, reason;
4879556dfa2SMaharaja Kennadyrajan 	int ret;
4889556dfa2SMaharaja Kennadyrajan 	char buf[64] = {0};
4899556dfa2SMaharaja Kennadyrajan 
4909556dfa2SMaharaja Kennadyrajan 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
4919556dfa2SMaharaja Kennadyrajan 				     user_buf, count);
4929556dfa2SMaharaja Kennadyrajan 	if (ret <= 0)
4939556dfa2SMaharaja Kennadyrajan 		return ret;
4949556dfa2SMaharaja Kennadyrajan 
4959556dfa2SMaharaja Kennadyrajan 	ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
4969556dfa2SMaharaja Kennadyrajan 	if (ret != 3)
4979556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
4989556dfa2SMaharaja Kennadyrajan 
4999556dfa2SMaharaja Kennadyrajan 	/* Valid TID values are 0 through 15 */
5009556dfa2SMaharaja Kennadyrajan 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
5019556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
5029556dfa2SMaharaja Kennadyrajan 
5039556dfa2SMaharaja Kennadyrajan 	mutex_lock(&ar->conf_mutex);
5049556dfa2SMaharaja Kennadyrajan 	if (ar->state != ATH11K_STATE_ON ||
5059556dfa2SMaharaja Kennadyrajan 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
5069556dfa2SMaharaja Kennadyrajan 		ret = count;
5079556dfa2SMaharaja Kennadyrajan 		goto out;
5089556dfa2SMaharaja Kennadyrajan 	}
5099556dfa2SMaharaja Kennadyrajan 
5109556dfa2SMaharaja Kennadyrajan 	ret = ath11k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
5119556dfa2SMaharaja Kennadyrajan 				    tid, initiator, reason);
5129556dfa2SMaharaja Kennadyrajan 	if (ret) {
5139556dfa2SMaharaja Kennadyrajan 		ath11k_warn(ar->ab, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
5149556dfa2SMaharaja Kennadyrajan 			    arsta->arvif->vdev_id, sta->addr, tid, initiator,
5159556dfa2SMaharaja Kennadyrajan 			    reason);
5169556dfa2SMaharaja Kennadyrajan 	}
5179556dfa2SMaharaja Kennadyrajan 	ret = count;
5189556dfa2SMaharaja Kennadyrajan out:
5199556dfa2SMaharaja Kennadyrajan 	mutex_unlock(&ar->conf_mutex);
5209556dfa2SMaharaja Kennadyrajan 	return ret;
5219556dfa2SMaharaja Kennadyrajan }
5229556dfa2SMaharaja Kennadyrajan 
5239556dfa2SMaharaja Kennadyrajan static const struct file_operations fops_delba = {
5249556dfa2SMaharaja Kennadyrajan 	.write = ath11k_dbg_sta_write_delba,
5259556dfa2SMaharaja Kennadyrajan 	.open = simple_open,
5269556dfa2SMaharaja Kennadyrajan 	.owner = THIS_MODULE,
5279556dfa2SMaharaja Kennadyrajan 	.llseek = default_llseek,
5289556dfa2SMaharaja Kennadyrajan };
5299556dfa2SMaharaja Kennadyrajan 
ath11k_dbg_sta_write_addba_resp(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)5309556dfa2SMaharaja Kennadyrajan static ssize_t ath11k_dbg_sta_write_addba_resp(struct file *file,
5319556dfa2SMaharaja Kennadyrajan 					       const char __user *user_buf,
5329556dfa2SMaharaja Kennadyrajan 					       size_t count, loff_t *ppos)
5339556dfa2SMaharaja Kennadyrajan {
5349556dfa2SMaharaja Kennadyrajan 	struct ieee80211_sta *sta = file->private_data;
5359556dfa2SMaharaja Kennadyrajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
5369556dfa2SMaharaja Kennadyrajan 	struct ath11k *ar = arsta->arvif->ar;
5379556dfa2SMaharaja Kennadyrajan 	u32 tid, status;
5389556dfa2SMaharaja Kennadyrajan 	int ret;
5399556dfa2SMaharaja Kennadyrajan 	char buf[64] = {0};
5409556dfa2SMaharaja Kennadyrajan 
5419556dfa2SMaharaja Kennadyrajan 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
5429556dfa2SMaharaja Kennadyrajan 				     user_buf, count);
5439556dfa2SMaharaja Kennadyrajan 	if (ret <= 0)
5449556dfa2SMaharaja Kennadyrajan 		return ret;
5459556dfa2SMaharaja Kennadyrajan 
5469556dfa2SMaharaja Kennadyrajan 	ret = sscanf(buf, "%u %u", &tid, &status);
5479556dfa2SMaharaja Kennadyrajan 	if (ret != 2)
5489556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
5499556dfa2SMaharaja Kennadyrajan 
5509556dfa2SMaharaja Kennadyrajan 	/* Valid TID values are 0 through 15 */
5519556dfa2SMaharaja Kennadyrajan 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
5529556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
5539556dfa2SMaharaja Kennadyrajan 
5549556dfa2SMaharaja Kennadyrajan 	mutex_lock(&ar->conf_mutex);
5559556dfa2SMaharaja Kennadyrajan 	if (ar->state != ATH11K_STATE_ON ||
5569556dfa2SMaharaja Kennadyrajan 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
5579556dfa2SMaharaja Kennadyrajan 		ret = count;
5589556dfa2SMaharaja Kennadyrajan 		goto out;
5599556dfa2SMaharaja Kennadyrajan 	}
5609556dfa2SMaharaja Kennadyrajan 
5619556dfa2SMaharaja Kennadyrajan 	ret = ath11k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
5629556dfa2SMaharaja Kennadyrajan 					tid, status);
5639556dfa2SMaharaja Kennadyrajan 	if (ret) {
5649556dfa2SMaharaja Kennadyrajan 		ath11k_warn(ar->ab, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
5659556dfa2SMaharaja Kennadyrajan 			    arsta->arvif->vdev_id, sta->addr, tid, status);
5669556dfa2SMaharaja Kennadyrajan 	}
5679556dfa2SMaharaja Kennadyrajan 	ret = count;
5689556dfa2SMaharaja Kennadyrajan out:
5699556dfa2SMaharaja Kennadyrajan 	mutex_unlock(&ar->conf_mutex);
5709556dfa2SMaharaja Kennadyrajan 	return ret;
5719556dfa2SMaharaja Kennadyrajan }
5729556dfa2SMaharaja Kennadyrajan 
5739556dfa2SMaharaja Kennadyrajan static const struct file_operations fops_addba_resp = {
5749556dfa2SMaharaja Kennadyrajan 	.write = ath11k_dbg_sta_write_addba_resp,
5759556dfa2SMaharaja Kennadyrajan 	.open = simple_open,
5769556dfa2SMaharaja Kennadyrajan 	.owner = THIS_MODULE,
5779556dfa2SMaharaja Kennadyrajan 	.llseek = default_llseek,
5789556dfa2SMaharaja Kennadyrajan };
5799556dfa2SMaharaja Kennadyrajan 
ath11k_dbg_sta_write_addba(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)5809556dfa2SMaharaja Kennadyrajan static ssize_t ath11k_dbg_sta_write_addba(struct file *file,
5819556dfa2SMaharaja Kennadyrajan 					  const char __user *user_buf,
5829556dfa2SMaharaja Kennadyrajan 					  size_t count, loff_t *ppos)
5839556dfa2SMaharaja Kennadyrajan {
5849556dfa2SMaharaja Kennadyrajan 	struct ieee80211_sta *sta = file->private_data;
5859556dfa2SMaharaja Kennadyrajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
5869556dfa2SMaharaja Kennadyrajan 	struct ath11k *ar = arsta->arvif->ar;
5879556dfa2SMaharaja Kennadyrajan 	u32 tid, buf_size;
5889556dfa2SMaharaja Kennadyrajan 	int ret;
5899556dfa2SMaharaja Kennadyrajan 	char buf[64] = {0};
5909556dfa2SMaharaja Kennadyrajan 
5919556dfa2SMaharaja Kennadyrajan 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
5929556dfa2SMaharaja Kennadyrajan 				     user_buf, count);
5939556dfa2SMaharaja Kennadyrajan 	if (ret <= 0)
5949556dfa2SMaharaja Kennadyrajan 		return ret;
5959556dfa2SMaharaja Kennadyrajan 
5969556dfa2SMaharaja Kennadyrajan 	ret = sscanf(buf, "%u %u", &tid, &buf_size);
5979556dfa2SMaharaja Kennadyrajan 	if (ret != 2)
5989556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
5999556dfa2SMaharaja Kennadyrajan 
6009556dfa2SMaharaja Kennadyrajan 	/* Valid TID values are 0 through 15 */
6019556dfa2SMaharaja Kennadyrajan 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
6029556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
6039556dfa2SMaharaja Kennadyrajan 
6049556dfa2SMaharaja Kennadyrajan 	mutex_lock(&ar->conf_mutex);
6059556dfa2SMaharaja Kennadyrajan 	if (ar->state != ATH11K_STATE_ON ||
6069556dfa2SMaharaja Kennadyrajan 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
6079556dfa2SMaharaja Kennadyrajan 		ret = count;
6089556dfa2SMaharaja Kennadyrajan 		goto out;
6099556dfa2SMaharaja Kennadyrajan 	}
6109556dfa2SMaharaja Kennadyrajan 
6119556dfa2SMaharaja Kennadyrajan 	ret = ath11k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
6129556dfa2SMaharaja Kennadyrajan 				    tid, buf_size);
6139556dfa2SMaharaja Kennadyrajan 	if (ret) {
6149556dfa2SMaharaja Kennadyrajan 		ath11k_warn(ar->ab, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
6159556dfa2SMaharaja Kennadyrajan 			    arsta->arvif->vdev_id, sta->addr, tid, buf_size);
6169556dfa2SMaharaja Kennadyrajan 	}
6179556dfa2SMaharaja Kennadyrajan 
6189556dfa2SMaharaja Kennadyrajan 	ret = count;
6199556dfa2SMaharaja Kennadyrajan out:
6209556dfa2SMaharaja Kennadyrajan 	mutex_unlock(&ar->conf_mutex);
6219556dfa2SMaharaja Kennadyrajan 	return ret;
6229556dfa2SMaharaja Kennadyrajan }
6239556dfa2SMaharaja Kennadyrajan 
6249556dfa2SMaharaja Kennadyrajan static const struct file_operations fops_addba = {
6259556dfa2SMaharaja Kennadyrajan 	.write = ath11k_dbg_sta_write_addba,
6269556dfa2SMaharaja Kennadyrajan 	.open = simple_open,
6279556dfa2SMaharaja Kennadyrajan 	.owner = THIS_MODULE,
6289556dfa2SMaharaja Kennadyrajan 	.llseek = default_llseek,
6299556dfa2SMaharaja Kennadyrajan };
6309556dfa2SMaharaja Kennadyrajan 
ath11k_dbg_sta_read_aggr_mode(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)6319556dfa2SMaharaja Kennadyrajan static ssize_t ath11k_dbg_sta_read_aggr_mode(struct file *file,
6329556dfa2SMaharaja Kennadyrajan 					     char __user *user_buf,
6339556dfa2SMaharaja Kennadyrajan 					     size_t count, loff_t *ppos)
6349556dfa2SMaharaja Kennadyrajan {
6359556dfa2SMaharaja Kennadyrajan 	struct ieee80211_sta *sta = file->private_data;
6369556dfa2SMaharaja Kennadyrajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
6379556dfa2SMaharaja Kennadyrajan 	struct ath11k *ar = arsta->arvif->ar;
6389556dfa2SMaharaja Kennadyrajan 	char buf[64];
6399556dfa2SMaharaja Kennadyrajan 	int len = 0;
6409556dfa2SMaharaja Kennadyrajan 
6419556dfa2SMaharaja Kennadyrajan 	mutex_lock(&ar->conf_mutex);
6429556dfa2SMaharaja Kennadyrajan 	len = scnprintf(buf, sizeof(buf) - len,
6439556dfa2SMaharaja Kennadyrajan 			"aggregation mode: %s\n\n%s\n%s\n",
6449556dfa2SMaharaja Kennadyrajan 			(arsta->aggr_mode == ATH11K_DBG_AGGR_MODE_AUTO) ?
6459556dfa2SMaharaja Kennadyrajan 			"auto" : "manual", "auto = 0", "manual = 1");
6469556dfa2SMaharaja Kennadyrajan 	mutex_unlock(&ar->conf_mutex);
6479556dfa2SMaharaja Kennadyrajan 
6489556dfa2SMaharaja Kennadyrajan 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
6499556dfa2SMaharaja Kennadyrajan }
6509556dfa2SMaharaja Kennadyrajan 
ath11k_dbg_sta_write_aggr_mode(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)6519556dfa2SMaharaja Kennadyrajan static ssize_t ath11k_dbg_sta_write_aggr_mode(struct file *file,
6529556dfa2SMaharaja Kennadyrajan 					      const char __user *user_buf,
6539556dfa2SMaharaja Kennadyrajan 					      size_t count, loff_t *ppos)
6549556dfa2SMaharaja Kennadyrajan {
6559556dfa2SMaharaja Kennadyrajan 	struct ieee80211_sta *sta = file->private_data;
6569556dfa2SMaharaja Kennadyrajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
6579556dfa2SMaharaja Kennadyrajan 	struct ath11k *ar = arsta->arvif->ar;
6589556dfa2SMaharaja Kennadyrajan 	u32 aggr_mode;
6599556dfa2SMaharaja Kennadyrajan 	int ret;
6609556dfa2SMaharaja Kennadyrajan 
6619556dfa2SMaharaja Kennadyrajan 	if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
6629556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
6639556dfa2SMaharaja Kennadyrajan 
6649556dfa2SMaharaja Kennadyrajan 	if (aggr_mode >= ATH11K_DBG_AGGR_MODE_MAX)
6659556dfa2SMaharaja Kennadyrajan 		return -EINVAL;
6669556dfa2SMaharaja Kennadyrajan 
6679556dfa2SMaharaja Kennadyrajan 	mutex_lock(&ar->conf_mutex);
6689556dfa2SMaharaja Kennadyrajan 	if (ar->state != ATH11K_STATE_ON ||
6699556dfa2SMaharaja Kennadyrajan 	    aggr_mode == arsta->aggr_mode) {
6709556dfa2SMaharaja Kennadyrajan 		ret = count;
6719556dfa2SMaharaja Kennadyrajan 		goto out;
6729556dfa2SMaharaja Kennadyrajan 	}
6739556dfa2SMaharaja Kennadyrajan 
6749556dfa2SMaharaja Kennadyrajan 	ret = ath11k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
6759556dfa2SMaharaja Kennadyrajan 	if (ret) {
6769556dfa2SMaharaja Kennadyrajan 		ath11k_warn(ar->ab, "failed to clear addba session ret: %d\n",
6779556dfa2SMaharaja Kennadyrajan 			    ret);
6789556dfa2SMaharaja Kennadyrajan 		goto out;
6799556dfa2SMaharaja Kennadyrajan 	}
6809556dfa2SMaharaja Kennadyrajan 
6819556dfa2SMaharaja Kennadyrajan 	arsta->aggr_mode = aggr_mode;
6829556dfa2SMaharaja Kennadyrajan out:
6839556dfa2SMaharaja Kennadyrajan 	mutex_unlock(&ar->conf_mutex);
6849556dfa2SMaharaja Kennadyrajan 	return ret;
6859556dfa2SMaharaja Kennadyrajan }
6869556dfa2SMaharaja Kennadyrajan 
6879556dfa2SMaharaja Kennadyrajan static const struct file_operations fops_aggr_mode = {
6889556dfa2SMaharaja Kennadyrajan 	.read = ath11k_dbg_sta_read_aggr_mode,
6899556dfa2SMaharaja Kennadyrajan 	.write = ath11k_dbg_sta_write_aggr_mode,
6909556dfa2SMaharaja Kennadyrajan 	.open = simple_open,
6919556dfa2SMaharaja Kennadyrajan 	.owner = THIS_MODULE,
6929556dfa2SMaharaja Kennadyrajan 	.llseek = default_llseek,
6939556dfa2SMaharaja Kennadyrajan };
6949556dfa2SMaharaja Kennadyrajan 
695559ef68fSAshok Raj Nagarajan static ssize_t
ath11k_write_htt_peer_stats_reset(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)696559ef68fSAshok Raj Nagarajan ath11k_write_htt_peer_stats_reset(struct file *file,
697559ef68fSAshok Raj Nagarajan 				  const char __user *user_buf,
698559ef68fSAshok Raj Nagarajan 				  size_t count, loff_t *ppos)
699559ef68fSAshok Raj Nagarajan {
700559ef68fSAshok Raj Nagarajan 	struct ieee80211_sta *sta = file->private_data;
701559ef68fSAshok Raj Nagarajan 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
702559ef68fSAshok Raj Nagarajan 	struct ath11k *ar = arsta->arvif->ar;
703559ef68fSAshok Raj Nagarajan 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
704559ef68fSAshok Raj Nagarajan 	int ret;
705559ef68fSAshok Raj Nagarajan 	u8 type;
706559ef68fSAshok Raj Nagarajan 
707559ef68fSAshok Raj Nagarajan 	ret = kstrtou8_from_user(user_buf, count, 0, &type);
708559ef68fSAshok Raj Nagarajan 	if (ret)
709559ef68fSAshok Raj Nagarajan 		return ret;
710559ef68fSAshok Raj Nagarajan 
711559ef68fSAshok Raj Nagarajan 	if (!type)
712559ef68fSAshok Raj Nagarajan 		return ret;
713559ef68fSAshok Raj Nagarajan 
714559ef68fSAshok Raj Nagarajan 	mutex_lock(&ar->conf_mutex);
715559ef68fSAshok Raj Nagarajan 	cfg_params.cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR;
716559ef68fSAshok Raj Nagarajan 	cfg_params.cfg0 |= FIELD_PREP(GENMASK(15, 1),
717559ef68fSAshok Raj Nagarajan 				HTT_PEER_STATS_REQ_MODE_FLUSH_TQM);
718559ef68fSAshok Raj Nagarajan 
719559ef68fSAshok Raj Nagarajan 	cfg_params.cfg1 = HTT_STAT_DEFAULT_PEER_REQ_TYPE;
720559ef68fSAshok Raj Nagarajan 
721559ef68fSAshok Raj Nagarajan 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(7, 0), sta->addr[0]);
722559ef68fSAshok Raj Nagarajan 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(15, 8), sta->addr[1]);
723559ef68fSAshok Raj Nagarajan 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(23, 16), sta->addr[2]);
724559ef68fSAshok Raj Nagarajan 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(31, 24), sta->addr[3]);
725559ef68fSAshok Raj Nagarajan 
726559ef68fSAshok Raj Nagarajan 	cfg_params.cfg3 |= FIELD_PREP(GENMASK(7, 0), sta->addr[4]);
727559ef68fSAshok Raj Nagarajan 	cfg_params.cfg3 |= FIELD_PREP(GENMASK(15, 8), sta->addr[5]);
728559ef68fSAshok Raj Nagarajan 
729559ef68fSAshok Raj Nagarajan 	cfg_params.cfg3 |= ATH11K_HTT_PEER_STATS_RESET;
730559ef68fSAshok Raj Nagarajan 
731559ef68fSAshok Raj Nagarajan 	ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar,
732559ef68fSAshok Raj Nagarajan 						 ATH11K_DBG_HTT_EXT_STATS_PEER_INFO,
733559ef68fSAshok Raj Nagarajan 						 &cfg_params,
734559ef68fSAshok Raj Nagarajan 						 0ULL);
735559ef68fSAshok Raj Nagarajan 	if (ret) {
736559ef68fSAshok Raj Nagarajan 		ath11k_warn(ar->ab, "failed to send htt peer stats request: %d\n", ret);
737559ef68fSAshok Raj Nagarajan 		mutex_unlock(&ar->conf_mutex);
738559ef68fSAshok Raj Nagarajan 		return ret;
739559ef68fSAshok Raj Nagarajan 	}
740559ef68fSAshok Raj Nagarajan 
741559ef68fSAshok Raj Nagarajan 	mutex_unlock(&ar->conf_mutex);
742559ef68fSAshok Raj Nagarajan 
743559ef68fSAshok Raj Nagarajan 	ret = count;
744559ef68fSAshok Raj Nagarajan 
745559ef68fSAshok Raj Nagarajan 	return ret;
746559ef68fSAshok Raj Nagarajan }
747559ef68fSAshok Raj Nagarajan 
748559ef68fSAshok Raj Nagarajan static const struct file_operations fops_htt_peer_stats_reset = {
749559ef68fSAshok Raj Nagarajan 	.write = ath11k_write_htt_peer_stats_reset,
750559ef68fSAshok Raj Nagarajan 	.open = simple_open,
751559ef68fSAshok Raj Nagarajan 	.owner = THIS_MODULE,
752559ef68fSAshok Raj Nagarajan 	.llseek = default_llseek,
753559ef68fSAshok Raj Nagarajan };
754559ef68fSAshok Raj Nagarajan 
ath11k_dbg_sta_read_peer_ps_state(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)755710a95f9SVenkateswara Naralasetty static ssize_t ath11k_dbg_sta_read_peer_ps_state(struct file *file,
756710a95f9SVenkateswara Naralasetty 						 char __user *user_buf,
757710a95f9SVenkateswara Naralasetty 						 size_t count, loff_t *ppos)
758710a95f9SVenkateswara Naralasetty {
759710a95f9SVenkateswara Naralasetty 	struct ieee80211_sta *sta = file->private_data;
760710a95f9SVenkateswara Naralasetty 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
761710a95f9SVenkateswara Naralasetty 	struct ath11k *ar = arsta->arvif->ar;
762710a95f9SVenkateswara Naralasetty 	char buf[20];
763710a95f9SVenkateswara Naralasetty 	int len;
764710a95f9SVenkateswara Naralasetty 
765710a95f9SVenkateswara Naralasetty 	spin_lock_bh(&ar->data_lock);
766710a95f9SVenkateswara Naralasetty 
767710a95f9SVenkateswara Naralasetty 	len = scnprintf(buf, sizeof(buf), "%d\n", arsta->peer_ps_state);
768710a95f9SVenkateswara Naralasetty 
769710a95f9SVenkateswara Naralasetty 	spin_unlock_bh(&ar->data_lock);
770710a95f9SVenkateswara Naralasetty 
771710a95f9SVenkateswara Naralasetty 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
772710a95f9SVenkateswara Naralasetty }
773710a95f9SVenkateswara Naralasetty 
774710a95f9SVenkateswara Naralasetty static const struct file_operations fops_peer_ps_state = {
775710a95f9SVenkateswara Naralasetty 	.open = simple_open,
776710a95f9SVenkateswara Naralasetty 	.read = ath11k_dbg_sta_read_peer_ps_state,
777710a95f9SVenkateswara Naralasetty 	.owner = THIS_MODULE,
778710a95f9SVenkateswara Naralasetty 	.llseek = default_llseek,
779710a95f9SVenkateswara Naralasetty };
780710a95f9SVenkateswara Naralasetty 
ath11k_dbg_sta_read_current_ps_duration(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)781710a95f9SVenkateswara Naralasetty static ssize_t ath11k_dbg_sta_read_current_ps_duration(struct file *file,
782710a95f9SVenkateswara Naralasetty 						       char __user *user_buf,
783710a95f9SVenkateswara Naralasetty 						       size_t count,
784710a95f9SVenkateswara Naralasetty 						       loff_t *ppos)
785710a95f9SVenkateswara Naralasetty {
786710a95f9SVenkateswara Naralasetty 	struct ieee80211_sta *sta = file->private_data;
787710a95f9SVenkateswara Naralasetty 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
788710a95f9SVenkateswara Naralasetty 	struct ath11k *ar = arsta->arvif->ar;
789710a95f9SVenkateswara Naralasetty 	u64 time_since_station_in_power_save;
790710a95f9SVenkateswara Naralasetty 	char buf[20];
791710a95f9SVenkateswara Naralasetty 	int len;
792710a95f9SVenkateswara Naralasetty 
793710a95f9SVenkateswara Naralasetty 	spin_lock_bh(&ar->data_lock);
794710a95f9SVenkateswara Naralasetty 
795710a95f9SVenkateswara Naralasetty 	if (arsta->peer_ps_state == WMI_PEER_PS_STATE_ON &&
796710a95f9SVenkateswara Naralasetty 	    arsta->peer_current_ps_valid)
797710a95f9SVenkateswara Naralasetty 		time_since_station_in_power_save = jiffies_to_msecs(jiffies
798710a95f9SVenkateswara Naralasetty 						- arsta->ps_start_jiffies);
799710a95f9SVenkateswara Naralasetty 	else
800710a95f9SVenkateswara Naralasetty 		time_since_station_in_power_save = 0;
801710a95f9SVenkateswara Naralasetty 
802710a95f9SVenkateswara Naralasetty 	len = scnprintf(buf, sizeof(buf), "%llu\n",
803710a95f9SVenkateswara Naralasetty 			time_since_station_in_power_save);
804710a95f9SVenkateswara Naralasetty 	spin_unlock_bh(&ar->data_lock);
805710a95f9SVenkateswara Naralasetty 
806710a95f9SVenkateswara Naralasetty 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
807710a95f9SVenkateswara Naralasetty }
808710a95f9SVenkateswara Naralasetty 
809710a95f9SVenkateswara Naralasetty static const struct file_operations fops_current_ps_duration = {
810710a95f9SVenkateswara Naralasetty 	.open = simple_open,
811710a95f9SVenkateswara Naralasetty 	.read = ath11k_dbg_sta_read_current_ps_duration,
812710a95f9SVenkateswara Naralasetty 	.owner = THIS_MODULE,
813710a95f9SVenkateswara Naralasetty 	.llseek = default_llseek,
814710a95f9SVenkateswara Naralasetty };
815710a95f9SVenkateswara Naralasetty 
ath11k_dbg_sta_read_total_ps_duration(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)816710a95f9SVenkateswara Naralasetty static ssize_t ath11k_dbg_sta_read_total_ps_duration(struct file *file,
817710a95f9SVenkateswara Naralasetty 						     char __user *user_buf,
818710a95f9SVenkateswara Naralasetty 						     size_t count, loff_t *ppos)
819710a95f9SVenkateswara Naralasetty {
820710a95f9SVenkateswara Naralasetty 	struct ieee80211_sta *sta = file->private_data;
821710a95f9SVenkateswara Naralasetty 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
822710a95f9SVenkateswara Naralasetty 	struct ath11k *ar = arsta->arvif->ar;
823710a95f9SVenkateswara Naralasetty 	char buf[20];
824710a95f9SVenkateswara Naralasetty 	u64 power_save_duration;
825710a95f9SVenkateswara Naralasetty 	int len;
826710a95f9SVenkateswara Naralasetty 
827710a95f9SVenkateswara Naralasetty 	spin_lock_bh(&ar->data_lock);
828710a95f9SVenkateswara Naralasetty 
829710a95f9SVenkateswara Naralasetty 	if (arsta->peer_ps_state == WMI_PEER_PS_STATE_ON &&
830710a95f9SVenkateswara Naralasetty 	    arsta->peer_current_ps_valid)
831710a95f9SVenkateswara Naralasetty 		power_save_duration = jiffies_to_msecs(jiffies
832710a95f9SVenkateswara Naralasetty 						- arsta->ps_start_jiffies)
833710a95f9SVenkateswara Naralasetty 						+ arsta->ps_total_duration;
834710a95f9SVenkateswara Naralasetty 	else
835710a95f9SVenkateswara Naralasetty 		power_save_duration = arsta->ps_total_duration;
836710a95f9SVenkateswara Naralasetty 
837710a95f9SVenkateswara Naralasetty 	len = scnprintf(buf, sizeof(buf), "%llu\n", power_save_duration);
838710a95f9SVenkateswara Naralasetty 
839710a95f9SVenkateswara Naralasetty 	spin_unlock_bh(&ar->data_lock);
840710a95f9SVenkateswara Naralasetty 
841710a95f9SVenkateswara Naralasetty 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
842710a95f9SVenkateswara Naralasetty }
843710a95f9SVenkateswara Naralasetty 
844710a95f9SVenkateswara Naralasetty static const struct file_operations fops_total_ps_duration = {
845710a95f9SVenkateswara Naralasetty 	.open = simple_open,
846710a95f9SVenkateswara Naralasetty 	.read = ath11k_dbg_sta_read_total_ps_duration,
847710a95f9SVenkateswara Naralasetty 	.owner = THIS_MODULE,
848710a95f9SVenkateswara Naralasetty 	.llseek = default_llseek,
849710a95f9SVenkateswara Naralasetty };
850710a95f9SVenkateswara Naralasetty 
ath11k_debugfs_sta_op_add(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct dentry * dir)851568f0603SKalle Valo void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
852d5c65159SKalle Valo 			       struct ieee80211_sta *sta, struct dentry *dir)
853d5c65159SKalle Valo {
854d5c65159SKalle Valo 	struct ath11k *ar = hw->priv;
855d5c65159SKalle Valo 
856cb4e57dbSKalle Valo 	if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))
857d5c65159SKalle Valo 		debugfs_create_file("tx_stats", 0400, dir, sta,
858d5c65159SKalle Valo 				    &fops_tx_stats);
859cb4e57dbSKalle Valo 	if (ath11k_debugfs_is_extd_rx_stats_enabled(ar))
860d5c65159SKalle Valo 		debugfs_create_file("rx_stats", 0400, dir, sta,
861d5c65159SKalle Valo 				    &fops_rx_stats);
862d5c65159SKalle Valo 
863d5c65159SKalle Valo 	debugfs_create_file("htt_peer_stats", 0400, dir, sta,
864d5c65159SKalle Valo 			    &fops_htt_peer_stats);
865d5c65159SKalle Valo 
866d5c65159SKalle Valo 	debugfs_create_file("peer_pktlog", 0644, dir, sta,
867d5c65159SKalle Valo 			    &fops_peer_pktlog);
8689556dfa2SMaharaja Kennadyrajan 
8699556dfa2SMaharaja Kennadyrajan 	debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
8709556dfa2SMaharaja Kennadyrajan 	debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
8719556dfa2SMaharaja Kennadyrajan 	debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
8729556dfa2SMaharaja Kennadyrajan 	debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
873559ef68fSAshok Raj Nagarajan 
874559ef68fSAshok Raj Nagarajan 	if (test_bit(WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET,
875559ef68fSAshok Raj Nagarajan 		     ar->ab->wmi_ab.svc_map))
876559ef68fSAshok Raj Nagarajan 		debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta,
877559ef68fSAshok Raj Nagarajan 				    &fops_htt_peer_stats_reset);
878710a95f9SVenkateswara Naralasetty 
879710a95f9SVenkateswara Naralasetty 	debugfs_create_file("peer_ps_state", 0400, dir, sta,
880710a95f9SVenkateswara Naralasetty 			    &fops_peer_ps_state);
881710a95f9SVenkateswara Naralasetty 
882710a95f9SVenkateswara Naralasetty 	if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
883710a95f9SVenkateswara Naralasetty 		     ar->ab->wmi_ab.svc_map)) {
884710a95f9SVenkateswara Naralasetty 		debugfs_create_file("current_ps_duration", 0440, dir, sta,
885710a95f9SVenkateswara Naralasetty 				    &fops_current_ps_duration);
886710a95f9SVenkateswara Naralasetty 		debugfs_create_file("total_ps_duration", 0440, dir, sta,
887710a95f9SVenkateswara Naralasetty 				    &fops_total_ps_duration);
888710a95f9SVenkateswara Naralasetty 	}
889d5c65159SKalle Valo }
890