1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  */
5 
6 #include <linux/vmalloc.h>
7 
8 #include "debugfs_sta.h"
9 #include "core.h"
10 #include "peer.h"
11 #include "debug.h"
12 #include "dp_tx.h"
13 #include "debugfs_htt_stats.h"
14 
15 void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta,
16 				     struct ath11k_per_peer_tx_stats *peer_stats,
17 				     u8 legacy_rate_idx)
18 {
19 	struct rate_info *txrate = &arsta->txrate;
20 	struct ath11k_htt_tx_stats *tx_stats;
21 	int gi, mcs, bw, nss;
22 
23 	if (!arsta->tx_stats)
24 		return;
25 
26 	tx_stats = arsta->tx_stats;
27 	gi = FIELD_GET(RATE_INFO_FLAGS_SHORT_GI, arsta->txrate.flags);
28 	mcs = txrate->mcs;
29 	bw = ath11k_mac_mac80211_bw_to_ath11k_bw(txrate->bw);
30 	nss = txrate->nss - 1;
31 
32 #define STATS_OP_FMT(name) tx_stats->stats[ATH11K_STATS_TYPE_##name]
33 
34 	if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
35 		STATS_OP_FMT(SUCC).he[0][mcs] += peer_stats->succ_bytes;
36 		STATS_OP_FMT(SUCC).he[1][mcs] += peer_stats->succ_pkts;
37 		STATS_OP_FMT(FAIL).he[0][mcs] += peer_stats->failed_bytes;
38 		STATS_OP_FMT(FAIL).he[1][mcs] += peer_stats->failed_pkts;
39 		STATS_OP_FMT(RETRY).he[0][mcs] += peer_stats->retry_bytes;
40 		STATS_OP_FMT(RETRY).he[1][mcs] += peer_stats->retry_pkts;
41 	} else if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) {
42 		STATS_OP_FMT(SUCC).vht[0][mcs] += peer_stats->succ_bytes;
43 		STATS_OP_FMT(SUCC).vht[1][mcs] += peer_stats->succ_pkts;
44 		STATS_OP_FMT(FAIL).vht[0][mcs] += peer_stats->failed_bytes;
45 		STATS_OP_FMT(FAIL).vht[1][mcs] += peer_stats->failed_pkts;
46 		STATS_OP_FMT(RETRY).vht[0][mcs] += peer_stats->retry_bytes;
47 		STATS_OP_FMT(RETRY).vht[1][mcs] += peer_stats->retry_pkts;
48 	} else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
49 		STATS_OP_FMT(SUCC).ht[0][mcs] += peer_stats->succ_bytes;
50 		STATS_OP_FMT(SUCC).ht[1][mcs] += peer_stats->succ_pkts;
51 		STATS_OP_FMT(FAIL).ht[0][mcs] += peer_stats->failed_bytes;
52 		STATS_OP_FMT(FAIL).ht[1][mcs] += peer_stats->failed_pkts;
53 		STATS_OP_FMT(RETRY).ht[0][mcs] += peer_stats->retry_bytes;
54 		STATS_OP_FMT(RETRY).ht[1][mcs] += peer_stats->retry_pkts;
55 	} else {
56 		mcs = legacy_rate_idx;
57 
58 		STATS_OP_FMT(SUCC).legacy[0][mcs] += peer_stats->succ_bytes;
59 		STATS_OP_FMT(SUCC).legacy[1][mcs] += peer_stats->succ_pkts;
60 		STATS_OP_FMT(FAIL).legacy[0][mcs] += peer_stats->failed_bytes;
61 		STATS_OP_FMT(FAIL).legacy[1][mcs] += peer_stats->failed_pkts;
62 		STATS_OP_FMT(RETRY).legacy[0][mcs] += peer_stats->retry_bytes;
63 		STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts;
64 	}
65 
66 	if (peer_stats->is_ampdu) {
67 		tx_stats->ba_fails += peer_stats->ba_fails;
68 
69 		if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) {
70 			STATS_OP_FMT(AMPDU).he[0][mcs] +=
71 			peer_stats->succ_bytes + peer_stats->retry_bytes;
72 			STATS_OP_FMT(AMPDU).he[1][mcs] +=
73 			peer_stats->succ_pkts + peer_stats->retry_pkts;
74 		} else if (txrate->flags & RATE_INFO_FLAGS_MCS) {
75 			STATS_OP_FMT(AMPDU).ht[0][mcs] +=
76 			peer_stats->succ_bytes + peer_stats->retry_bytes;
77 			STATS_OP_FMT(AMPDU).ht[1][mcs] +=
78 			peer_stats->succ_pkts + peer_stats->retry_pkts;
79 		} else {
80 			STATS_OP_FMT(AMPDU).vht[0][mcs] +=
81 			peer_stats->succ_bytes + peer_stats->retry_bytes;
82 			STATS_OP_FMT(AMPDU).vht[1][mcs] +=
83 			peer_stats->succ_pkts + peer_stats->retry_pkts;
84 		}
85 		STATS_OP_FMT(AMPDU).bw[0][bw] +=
86 			peer_stats->succ_bytes + peer_stats->retry_bytes;
87 		STATS_OP_FMT(AMPDU).nss[0][nss] +=
88 			peer_stats->succ_bytes + peer_stats->retry_bytes;
89 		STATS_OP_FMT(AMPDU).gi[0][gi] +=
90 			peer_stats->succ_bytes + peer_stats->retry_bytes;
91 		STATS_OP_FMT(AMPDU).bw[1][bw] +=
92 			peer_stats->succ_pkts + peer_stats->retry_pkts;
93 		STATS_OP_FMT(AMPDU).nss[1][nss] +=
94 			peer_stats->succ_pkts + peer_stats->retry_pkts;
95 		STATS_OP_FMT(AMPDU).gi[1][gi] +=
96 			peer_stats->succ_pkts + peer_stats->retry_pkts;
97 	} else {
98 		tx_stats->ack_fails += peer_stats->ba_fails;
99 	}
100 
101 	STATS_OP_FMT(SUCC).bw[0][bw] += peer_stats->succ_bytes;
102 	STATS_OP_FMT(SUCC).nss[0][nss] += peer_stats->succ_bytes;
103 	STATS_OP_FMT(SUCC).gi[0][gi] += peer_stats->succ_bytes;
104 
105 	STATS_OP_FMT(SUCC).bw[1][bw] += peer_stats->succ_pkts;
106 	STATS_OP_FMT(SUCC).nss[1][nss] += peer_stats->succ_pkts;
107 	STATS_OP_FMT(SUCC).gi[1][gi] += peer_stats->succ_pkts;
108 
109 	STATS_OP_FMT(FAIL).bw[0][bw] += peer_stats->failed_bytes;
110 	STATS_OP_FMT(FAIL).nss[0][nss] += peer_stats->failed_bytes;
111 	STATS_OP_FMT(FAIL).gi[0][gi] += peer_stats->failed_bytes;
112 
113 	STATS_OP_FMT(FAIL).bw[1][bw] += peer_stats->failed_pkts;
114 	STATS_OP_FMT(FAIL).nss[1][nss] += peer_stats->failed_pkts;
115 	STATS_OP_FMT(FAIL).gi[1][gi] += peer_stats->failed_pkts;
116 
117 	STATS_OP_FMT(RETRY).bw[0][bw] += peer_stats->retry_bytes;
118 	STATS_OP_FMT(RETRY).nss[0][nss] += peer_stats->retry_bytes;
119 	STATS_OP_FMT(RETRY).gi[0][gi] += peer_stats->retry_bytes;
120 
121 	STATS_OP_FMT(RETRY).bw[1][bw] += peer_stats->retry_pkts;
122 	STATS_OP_FMT(RETRY).nss[1][nss] += peer_stats->retry_pkts;
123 	STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts;
124 
125 	tx_stats->tx_duration += peer_stats->duration;
126 }
127 
128 void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar,
129 				       struct sk_buff *msdu,
130 				       struct hal_tx_status *ts)
131 {
132 	struct ath11k_base *ab = ar->ab;
133 	struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats;
134 	enum hal_tx_rate_stats_pkt_type pkt_type;
135 	enum hal_tx_rate_stats_sgi sgi;
136 	enum hal_tx_rate_stats_bw bw;
137 	struct ath11k_peer *peer;
138 	struct ath11k_sta *arsta;
139 	struct ieee80211_sta *sta;
140 	u16 rate;
141 	u8 rate_idx = 0;
142 	int ret;
143 	u8 mcs;
144 
145 	rcu_read_lock();
146 	spin_lock_bh(&ab->base_lock);
147 	peer = ath11k_peer_find_by_id(ab, ts->peer_id);
148 	if (!peer || !peer->sta) {
149 		ath11k_warn(ab, "failed to find the peer\n");
150 		spin_unlock_bh(&ab->base_lock);
151 		rcu_read_unlock();
152 		return;
153 	}
154 
155 	sta = peer->sta;
156 	arsta = (struct ath11k_sta *)sta->drv_priv;
157 
158 	memset(&arsta->txrate, 0, sizeof(arsta->txrate));
159 	pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
160 			     ts->rate_stats);
161 	mcs = FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS,
162 			ts->rate_stats);
163 	sgi = FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI,
164 			ts->rate_stats);
165 	bw = FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW, ts->rate_stats);
166 
167 	if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11A ||
168 	    pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11B) {
169 		ret = ath11k_mac_hw_ratecode_to_legacy_rate(mcs,
170 							    pkt_type,
171 							    &rate_idx,
172 							    &rate);
173 		if (ret < 0)
174 			goto err_out;
175 		arsta->txrate.legacy = rate;
176 	} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11N) {
177 		if (mcs > 7) {
178 			ath11k_warn(ab, "Invalid HT mcs index %d\n", mcs);
179 			goto err_out;
180 		}
181 
182 		arsta->txrate.mcs = mcs + 8 * (arsta->last_txrate.nss - 1);
183 		arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
184 		if (sgi)
185 			arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
186 	} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AC) {
187 		if (mcs > 9) {
188 			ath11k_warn(ab, "Invalid VHT mcs index %d\n", mcs);
189 			goto err_out;
190 		}
191 
192 		arsta->txrate.mcs = mcs;
193 		arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
194 		if (sgi)
195 			arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
196 	} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
197 		/* TODO */
198 	}
199 
200 	arsta->txrate.nss = arsta->last_txrate.nss;
201 	arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
202 
203 	ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx);
204 
205 err_out:
206 	spin_unlock_bh(&ab->base_lock);
207 	rcu_read_unlock();
208 }
209 
210 static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file,
211 					    char __user *user_buf,
212 					    size_t count, loff_t *ppos)
213 {
214 	struct ieee80211_sta *sta = file->private_data;
215 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
216 	struct ath11k *ar = arsta->arvif->ar;
217 	struct ath11k_htt_data_stats *stats;
218 	static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail",
219 							      "retry", "ampdu"};
220 	static const char *str[ATH11K_COUNTER_TYPE_MAX] = {"bytes", "packets"};
221 	int len = 0, i, j, k, retval = 0;
222 	const int size = 2 * 4096;
223 	char *buf;
224 
225 	if (!arsta->tx_stats)
226 		return -ENOENT;
227 
228 	buf = kzalloc(size, GFP_KERNEL);
229 	if (!buf)
230 		return -ENOMEM;
231 
232 	mutex_lock(&ar->conf_mutex);
233 
234 	spin_lock_bh(&ar->data_lock);
235 	for (k = 0; k < ATH11K_STATS_TYPE_MAX; k++) {
236 		for (j = 0; j < ATH11K_COUNTER_TYPE_MAX; j++) {
237 			stats = &arsta->tx_stats->stats[k];
238 			len += scnprintf(buf + len, size - len, "%s_%s\n",
239 					 str_name[k],
240 					 str[j]);
241 			len += scnprintf(buf + len, size - len,
242 					 " HE MCS %s\n",
243 					 str[j]);
244 			for (i = 0; i < ATH11K_HE_MCS_NUM; i++)
245 				len += scnprintf(buf + len, size - len,
246 						 "  %llu ",
247 						 stats->he[j][i]);
248 			len += scnprintf(buf + len, size - len, "\n");
249 			len += scnprintf(buf + len, size - len,
250 					 " VHT MCS %s\n",
251 					 str[j]);
252 			for (i = 0; i < ATH11K_VHT_MCS_NUM; i++)
253 				len += scnprintf(buf + len, size - len,
254 						 "  %llu ",
255 						 stats->vht[j][i]);
256 			len += scnprintf(buf + len, size - len, "\n");
257 			len += scnprintf(buf + len, size - len, " HT MCS %s\n",
258 					 str[j]);
259 			for (i = 0; i < ATH11K_HT_MCS_NUM; i++)
260 				len += scnprintf(buf + len, size - len,
261 						 "  %llu ", stats->ht[j][i]);
262 			len += scnprintf(buf + len, size - len, "\n");
263 			len += scnprintf(buf + len, size - len,
264 					" BW %s (20,40,80,160 MHz)\n", str[j]);
265 			len += scnprintf(buf + len, size - len,
266 					 "  %llu %llu %llu %llu\n",
267 					 stats->bw[j][0], stats->bw[j][1],
268 					 stats->bw[j][2], stats->bw[j][3]);
269 			len += scnprintf(buf + len, size - len,
270 					 " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]);
271 			len += scnprintf(buf + len, size - len,
272 					 "  %llu %llu %llu %llu\n",
273 					 stats->nss[j][0], stats->nss[j][1],
274 					 stats->nss[j][2], stats->nss[j][3]);
275 			len += scnprintf(buf + len, size - len,
276 					 " GI %s (0.4us,0.8us,1.6us,3.2us)\n",
277 					 str[j]);
278 			len += scnprintf(buf + len, size - len,
279 					 "  %llu %llu %llu %llu\n",
280 					 stats->gi[j][0], stats->gi[j][1],
281 					 stats->gi[j][2], stats->gi[j][3]);
282 			len += scnprintf(buf + len, size - len,
283 					 " legacy rate %s (1,2 ... Mbps)\n  ",
284 					 str[j]);
285 			for (i = 0; i < ATH11K_LEGACY_NUM; i++)
286 				len += scnprintf(buf + len, size - len, "%llu ",
287 						 stats->legacy[j][i]);
288 			len += scnprintf(buf + len, size - len, "\n");
289 		}
290 	}
291 
292 	len += scnprintf(buf + len, size - len,
293 			 "\nTX duration\n %llu usecs\n",
294 			 arsta->tx_stats->tx_duration);
295 	len += scnprintf(buf + len, size - len,
296 			"BA fails\n %llu\n", arsta->tx_stats->ba_fails);
297 	len += scnprintf(buf + len, size - len,
298 			"ack fails\n %llu\n", arsta->tx_stats->ack_fails);
299 	spin_unlock_bh(&ar->data_lock);
300 
301 	if (len > size)
302 		len = size;
303 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
304 	kfree(buf);
305 
306 	mutex_unlock(&ar->conf_mutex);
307 	return retval;
308 }
309 
310 static const struct file_operations fops_tx_stats = {
311 	.read = ath11k_dbg_sta_dump_tx_stats,
312 	.open = simple_open,
313 	.owner = THIS_MODULE,
314 	.llseek = default_llseek,
315 };
316 
317 static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file,
318 					    char __user *user_buf,
319 					    size_t count, loff_t *ppos)
320 {
321 	struct ieee80211_sta *sta = file->private_data;
322 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
323 	struct ath11k *ar = arsta->arvif->ar;
324 	struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
325 	int len = 0, i, retval = 0;
326 	const int size = 4096;
327 	char *buf;
328 
329 	if (!rx_stats)
330 		return -ENOENT;
331 
332 	buf = kzalloc(size, GFP_KERNEL);
333 	if (!buf)
334 		return -ENOMEM;
335 
336 	mutex_lock(&ar->conf_mutex);
337 	spin_lock_bh(&ar->ab->base_lock);
338 
339 	len += scnprintf(buf + len, size - len, "RX peer stats:\n");
340 	len += scnprintf(buf + len, size - len, "Num of MSDUs: %llu\n",
341 			 rx_stats->num_msdu);
342 	len += scnprintf(buf + len, size - len, "Num of MSDUs with TCP L4: %llu\n",
343 			 rx_stats->tcp_msdu_count);
344 	len += scnprintf(buf + len, size - len, "Num of MSDUs with UDP L4: %llu\n",
345 			 rx_stats->udp_msdu_count);
346 	len += scnprintf(buf + len, size - len, "Num of MSDUs part of AMPDU: %llu\n",
347 			 rx_stats->ampdu_msdu_count);
348 	len += scnprintf(buf + len, size - len, "Num of MSDUs not part of AMPDU: %llu\n",
349 			 rx_stats->non_ampdu_msdu_count);
350 	len += scnprintf(buf + len, size - len, "Num of MSDUs using STBC: %llu\n",
351 			 rx_stats->stbc_count);
352 	len += scnprintf(buf + len, size - len, "Num of MSDUs beamformed: %llu\n",
353 			 rx_stats->beamformed_count);
354 	len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS ok: %llu\n",
355 			 rx_stats->num_mpdu_fcs_ok);
356 	len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS error: %llu\n",
357 			 rx_stats->num_mpdu_fcs_err);
358 	len += scnprintf(buf + len, size - len,
359 			 "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n",
360 			 rx_stats->gi_count[0], rx_stats->gi_count[1],
361 			 rx_stats->gi_count[2], rx_stats->gi_count[3]);
362 	len += scnprintf(buf + len, size - len,
363 			 "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n",
364 			 rx_stats->bw_count[0], rx_stats->bw_count[1],
365 			 rx_stats->bw_count[2], rx_stats->bw_count[3]);
366 	len += scnprintf(buf + len, size - len, "BCC %llu LDPC %llu\n",
367 			 rx_stats->coding_count[0], rx_stats->coding_count[1]);
368 	len += scnprintf(buf + len, size - len,
369 			 "preamble: 11A %llu 11B %llu 11N %llu 11AC %llu 11AX %llu\n",
370 			 rx_stats->pream_cnt[0], rx_stats->pream_cnt[1],
371 			 rx_stats->pream_cnt[2], rx_stats->pream_cnt[3],
372 			 rx_stats->pream_cnt[4]);
373 	len += scnprintf(buf + len, size - len,
374 			 "reception type: SU %llu MU_MIMO %llu MU_OFDMA %llu MU_OFDMA_MIMO %llu\n",
375 			 rx_stats->reception_type[0], rx_stats->reception_type[1],
376 			 rx_stats->reception_type[2], rx_stats->reception_type[3]);
377 	len += scnprintf(buf + len, size - len, "TID(0-15) Legacy TID(16):");
378 	for (i = 0; i <= IEEE80211_NUM_TIDS; i++)
379 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->tid_count[i]);
380 	len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):");
381 	for (i = 0; i < HAL_RX_MAX_MCS + 1; i++)
382 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]);
383 	len += scnprintf(buf + len, size - len, "\nNSS(1-8):");
384 	for (i = 0; i < HAL_RX_MAX_NSS; i++)
385 		len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]);
386 	len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ",
387 			 rx_stats->rx_duration);
388 	len += scnprintf(buf + len, size - len,
389 			 "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n",
390 			 rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
391 			 rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2],
392 			 rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4],
393 			 rx_stats->ru_alloc_cnt[5]);
394 
395 	len += scnprintf(buf + len, size - len, "\n");
396 
397 	spin_unlock_bh(&ar->ab->base_lock);
398 
399 	if (len > size)
400 		len = size;
401 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
402 	kfree(buf);
403 
404 	mutex_unlock(&ar->conf_mutex);
405 	return retval;
406 }
407 
408 static const struct file_operations fops_rx_stats = {
409 	.read = ath11k_dbg_sta_dump_rx_stats,
410 	.open = simple_open,
411 	.owner = THIS_MODULE,
412 	.llseek = default_llseek,
413 };
414 
415 static int
416 ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file)
417 {
418 	struct ieee80211_sta *sta = inode->i_private;
419 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
420 	struct ath11k *ar = arsta->arvif->ar;
421 	struct debug_htt_stats_req *stats_req;
422 	int ret;
423 
424 	stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE);
425 	if (!stats_req)
426 		return -ENOMEM;
427 
428 	mutex_lock(&ar->conf_mutex);
429 	ar->debug.htt_stats.stats_req = stats_req;
430 	stats_req->type = ATH11K_DBG_HTT_EXT_STATS_PEER_INFO;
431 	memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN);
432 	ret = ath11k_debugfs_htt_stats_req(ar);
433 	mutex_unlock(&ar->conf_mutex);
434 	if (ret < 0)
435 		goto out;
436 
437 	file->private_data = stats_req;
438 	return 0;
439 out:
440 	vfree(stats_req);
441 	ar->debug.htt_stats.stats_req = NULL;
442 	return ret;
443 }
444 
445 static int
446 ath11k_dbg_sta_release_htt_peer_stats(struct inode *inode, struct file *file)
447 {
448 	struct ieee80211_sta *sta = inode->i_private;
449 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
450 	struct ath11k *ar = arsta->arvif->ar;
451 
452 	mutex_lock(&ar->conf_mutex);
453 	vfree(file->private_data);
454 	ar->debug.htt_stats.stats_req = NULL;
455 	mutex_unlock(&ar->conf_mutex);
456 
457 	return 0;
458 }
459 
460 static ssize_t ath11k_dbg_sta_read_htt_peer_stats(struct file *file,
461 						  char __user *user_buf,
462 						  size_t count, loff_t *ppos)
463 {
464 	struct debug_htt_stats_req *stats_req = file->private_data;
465 	char *buf;
466 	u32 length = 0;
467 
468 	buf = stats_req->buf;
469 	length = min_t(u32, stats_req->buf_len, ATH11K_HTT_STATS_BUF_SIZE);
470 	return simple_read_from_buffer(user_buf, count, ppos, buf, length);
471 }
472 
473 static const struct file_operations fops_htt_peer_stats = {
474 	.open = ath11k_dbg_sta_open_htt_peer_stats,
475 	.release = ath11k_dbg_sta_release_htt_peer_stats,
476 	.read = ath11k_dbg_sta_read_htt_peer_stats,
477 	.owner = THIS_MODULE,
478 	.llseek = default_llseek,
479 };
480 
481 static ssize_t ath11k_dbg_sta_write_peer_pktlog(struct file *file,
482 						const char __user *buf,
483 						size_t count, loff_t *ppos)
484 {
485 	struct ieee80211_sta *sta = file->private_data;
486 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
487 	struct ath11k *ar = arsta->arvif->ar;
488 	int ret, enable;
489 
490 	mutex_lock(&ar->conf_mutex);
491 
492 	if (ar->state != ATH11K_STATE_ON) {
493 		ret = -ENETDOWN;
494 		goto out;
495 	}
496 
497 	ret = kstrtoint_from_user(buf, count, 0, &enable);
498 	if (ret)
499 		goto out;
500 
501 	ar->debug.pktlog_peer_valid = enable;
502 	memcpy(ar->debug.pktlog_peer_addr, sta->addr, ETH_ALEN);
503 
504 	/* Send peer based pktlog enable/disable */
505 	ret = ath11k_wmi_pdev_peer_pktlog_filter(ar, sta->addr, enable);
506 	if (ret) {
507 		ath11k_warn(ar->ab, "failed to set peer pktlog filter %pM: %d\n",
508 			    sta->addr, ret);
509 		goto out;
510 	}
511 
512 	ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "peer pktlog filter set to %d\n",
513 		   enable);
514 	ret = count;
515 
516 out:
517 	mutex_unlock(&ar->conf_mutex);
518 	return ret;
519 }
520 
521 static ssize_t ath11k_dbg_sta_read_peer_pktlog(struct file *file,
522 					       char __user *ubuf,
523 					       size_t count, loff_t *ppos)
524 {
525 	struct ieee80211_sta *sta = file->private_data;
526 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
527 	struct ath11k *ar = arsta->arvif->ar;
528 	char buf[32] = {0};
529 	int len;
530 
531 	mutex_lock(&ar->conf_mutex);
532 	len = scnprintf(buf, sizeof(buf), "%08x %pM\n",
533 			ar->debug.pktlog_peer_valid,
534 			ar->debug.pktlog_peer_addr);
535 	mutex_unlock(&ar->conf_mutex);
536 
537 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
538 }
539 
540 static const struct file_operations fops_peer_pktlog = {
541 	.write = ath11k_dbg_sta_write_peer_pktlog,
542 	.read = ath11k_dbg_sta_read_peer_pktlog,
543 	.open = simple_open,
544 	.owner = THIS_MODULE,
545 	.llseek = default_llseek,
546 };
547 
548 static ssize_t ath11k_dbg_sta_write_delba(struct file *file,
549 					  const char __user *user_buf,
550 					  size_t count, loff_t *ppos)
551 {
552 	struct ieee80211_sta *sta = file->private_data;
553 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
554 	struct ath11k *ar = arsta->arvif->ar;
555 	u32 tid, initiator, reason;
556 	int ret;
557 	char buf[64] = {0};
558 
559 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
560 				     user_buf, count);
561 	if (ret <= 0)
562 		return ret;
563 
564 	ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
565 	if (ret != 3)
566 		return -EINVAL;
567 
568 	/* Valid TID values are 0 through 15 */
569 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
570 		return -EINVAL;
571 
572 	mutex_lock(&ar->conf_mutex);
573 	if (ar->state != ATH11K_STATE_ON ||
574 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
575 		ret = count;
576 		goto out;
577 	}
578 
579 	ret = ath11k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
580 				    tid, initiator, reason);
581 	if (ret) {
582 		ath11k_warn(ar->ab, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
583 			    arsta->arvif->vdev_id, sta->addr, tid, initiator,
584 			    reason);
585 	}
586 	ret = count;
587 out:
588 	mutex_unlock(&ar->conf_mutex);
589 	return ret;
590 }
591 
592 static const struct file_operations fops_delba = {
593 	.write = ath11k_dbg_sta_write_delba,
594 	.open = simple_open,
595 	.owner = THIS_MODULE,
596 	.llseek = default_llseek,
597 };
598 
599 static ssize_t ath11k_dbg_sta_write_addba_resp(struct file *file,
600 					       const char __user *user_buf,
601 					       size_t count, loff_t *ppos)
602 {
603 	struct ieee80211_sta *sta = file->private_data;
604 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
605 	struct ath11k *ar = arsta->arvif->ar;
606 	u32 tid, status;
607 	int ret;
608 	char buf[64] = {0};
609 
610 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
611 				     user_buf, count);
612 	if (ret <= 0)
613 		return ret;
614 
615 	ret = sscanf(buf, "%u %u", &tid, &status);
616 	if (ret != 2)
617 		return -EINVAL;
618 
619 	/* Valid TID values are 0 through 15 */
620 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
621 		return -EINVAL;
622 
623 	mutex_lock(&ar->conf_mutex);
624 	if (ar->state != ATH11K_STATE_ON ||
625 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
626 		ret = count;
627 		goto out;
628 	}
629 
630 	ret = ath11k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
631 					tid, status);
632 	if (ret) {
633 		ath11k_warn(ar->ab, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
634 			    arsta->arvif->vdev_id, sta->addr, tid, status);
635 	}
636 	ret = count;
637 out:
638 	mutex_unlock(&ar->conf_mutex);
639 	return ret;
640 }
641 
642 static const struct file_operations fops_addba_resp = {
643 	.write = ath11k_dbg_sta_write_addba_resp,
644 	.open = simple_open,
645 	.owner = THIS_MODULE,
646 	.llseek = default_llseek,
647 };
648 
649 static ssize_t ath11k_dbg_sta_write_addba(struct file *file,
650 					  const char __user *user_buf,
651 					  size_t count, loff_t *ppos)
652 {
653 	struct ieee80211_sta *sta = file->private_data;
654 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
655 	struct ath11k *ar = arsta->arvif->ar;
656 	u32 tid, buf_size;
657 	int ret;
658 	char buf[64] = {0};
659 
660 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
661 				     user_buf, count);
662 	if (ret <= 0)
663 		return ret;
664 
665 	ret = sscanf(buf, "%u %u", &tid, &buf_size);
666 	if (ret != 2)
667 		return -EINVAL;
668 
669 	/* Valid TID values are 0 through 15 */
670 	if (tid > HAL_DESC_REO_NON_QOS_TID - 1)
671 		return -EINVAL;
672 
673 	mutex_lock(&ar->conf_mutex);
674 	if (ar->state != ATH11K_STATE_ON ||
675 	    arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) {
676 		ret = count;
677 		goto out;
678 	}
679 
680 	ret = ath11k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
681 				    tid, buf_size);
682 	if (ret) {
683 		ath11k_warn(ar->ab, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
684 			    arsta->arvif->vdev_id, sta->addr, tid, buf_size);
685 	}
686 
687 	ret = count;
688 out:
689 	mutex_unlock(&ar->conf_mutex);
690 	return ret;
691 }
692 
693 static const struct file_operations fops_addba = {
694 	.write = ath11k_dbg_sta_write_addba,
695 	.open = simple_open,
696 	.owner = THIS_MODULE,
697 	.llseek = default_llseek,
698 };
699 
700 static ssize_t ath11k_dbg_sta_read_aggr_mode(struct file *file,
701 					     char __user *user_buf,
702 					     size_t count, loff_t *ppos)
703 {
704 	struct ieee80211_sta *sta = file->private_data;
705 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
706 	struct ath11k *ar = arsta->arvif->ar;
707 	char buf[64];
708 	int len = 0;
709 
710 	mutex_lock(&ar->conf_mutex);
711 	len = scnprintf(buf, sizeof(buf) - len,
712 			"aggregation mode: %s\n\n%s\n%s\n",
713 			(arsta->aggr_mode == ATH11K_DBG_AGGR_MODE_AUTO) ?
714 			"auto" : "manual", "auto = 0", "manual = 1");
715 	mutex_unlock(&ar->conf_mutex);
716 
717 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
718 }
719 
720 static ssize_t ath11k_dbg_sta_write_aggr_mode(struct file *file,
721 					      const char __user *user_buf,
722 					      size_t count, loff_t *ppos)
723 {
724 	struct ieee80211_sta *sta = file->private_data;
725 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
726 	struct ath11k *ar = arsta->arvif->ar;
727 	u32 aggr_mode;
728 	int ret;
729 
730 	if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
731 		return -EINVAL;
732 
733 	if (aggr_mode >= ATH11K_DBG_AGGR_MODE_MAX)
734 		return -EINVAL;
735 
736 	mutex_lock(&ar->conf_mutex);
737 	if (ar->state != ATH11K_STATE_ON ||
738 	    aggr_mode == arsta->aggr_mode) {
739 		ret = count;
740 		goto out;
741 	}
742 
743 	ret = ath11k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
744 	if (ret) {
745 		ath11k_warn(ar->ab, "failed to clear addba session ret: %d\n",
746 			    ret);
747 		goto out;
748 	}
749 
750 	arsta->aggr_mode = aggr_mode;
751 out:
752 	mutex_unlock(&ar->conf_mutex);
753 	return ret;
754 }
755 
756 static const struct file_operations fops_aggr_mode = {
757 	.read = ath11k_dbg_sta_read_aggr_mode,
758 	.write = ath11k_dbg_sta_write_aggr_mode,
759 	.open = simple_open,
760 	.owner = THIS_MODULE,
761 	.llseek = default_llseek,
762 };
763 
764 static ssize_t
765 ath11k_write_htt_peer_stats_reset(struct file *file,
766 				  const char __user *user_buf,
767 				  size_t count, loff_t *ppos)
768 {
769 	struct ieee80211_sta *sta = file->private_data;
770 	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
771 	struct ath11k *ar = arsta->arvif->ar;
772 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
773 	int ret;
774 	u8 type;
775 
776 	ret = kstrtou8_from_user(user_buf, count, 0, &type);
777 	if (ret)
778 		return ret;
779 
780 	if (!type)
781 		return ret;
782 
783 	mutex_lock(&ar->conf_mutex);
784 	cfg_params.cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR;
785 	cfg_params.cfg0 |= FIELD_PREP(GENMASK(15, 1),
786 				HTT_PEER_STATS_REQ_MODE_FLUSH_TQM);
787 
788 	cfg_params.cfg1 = HTT_STAT_DEFAULT_PEER_REQ_TYPE;
789 
790 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(7, 0), sta->addr[0]);
791 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(15, 8), sta->addr[1]);
792 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(23, 16), sta->addr[2]);
793 	cfg_params.cfg2 |= FIELD_PREP(GENMASK(31, 24), sta->addr[3]);
794 
795 	cfg_params.cfg3 |= FIELD_PREP(GENMASK(7, 0), sta->addr[4]);
796 	cfg_params.cfg3 |= FIELD_PREP(GENMASK(15, 8), sta->addr[5]);
797 
798 	cfg_params.cfg3 |= ATH11K_HTT_PEER_STATS_RESET;
799 
800 	ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar,
801 						 ATH11K_DBG_HTT_EXT_STATS_PEER_INFO,
802 						 &cfg_params,
803 						 0ULL);
804 	if (ret) {
805 		ath11k_warn(ar->ab, "failed to send htt peer stats request: %d\n", ret);
806 		mutex_unlock(&ar->conf_mutex);
807 		return ret;
808 	}
809 
810 	mutex_unlock(&ar->conf_mutex);
811 
812 	ret = count;
813 
814 	return ret;
815 }
816 
817 static const struct file_operations fops_htt_peer_stats_reset = {
818 	.write = ath11k_write_htt_peer_stats_reset,
819 	.open = simple_open,
820 	.owner = THIS_MODULE,
821 	.llseek = default_llseek,
822 };
823 
824 void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
825 			       struct ieee80211_sta *sta, struct dentry *dir)
826 {
827 	struct ath11k *ar = hw->priv;
828 
829 	if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))
830 		debugfs_create_file("tx_stats", 0400, dir, sta,
831 				    &fops_tx_stats);
832 	if (ath11k_debugfs_is_extd_rx_stats_enabled(ar))
833 		debugfs_create_file("rx_stats", 0400, dir, sta,
834 				    &fops_rx_stats);
835 
836 	debugfs_create_file("htt_peer_stats", 0400, dir, sta,
837 			    &fops_htt_peer_stats);
838 
839 	debugfs_create_file("peer_pktlog", 0644, dir, sta,
840 			    &fops_peer_pktlog);
841 
842 	debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode);
843 	debugfs_create_file("addba", 0200, dir, sta, &fops_addba);
844 	debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp);
845 	debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
846 
847 	if (test_bit(WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET,
848 		     ar->ab->wmi_ab.svc_map))
849 		debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta,
850 				    &fops_htt_peer_stats_reset);
851 }
852