xref: /linux/drivers/net/wireless/ath/ath12k/debugfs.c (revision b803c4a4f78834b31ebfbbcea350473333760559)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include "core.h"
8 #include "dp_tx.h"
9 #include "debug.h"
10 #include "debugfs.h"
11 #include "debugfs_htt_stats.h"
12 
13 static ssize_t ath12k_write_simulate_radar(struct file *file,
14 					   const char __user *user_buf,
15 					   size_t count, loff_t *ppos)
16 {
17 	struct ath12k *ar = file->private_data;
18 	int ret;
19 
20 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
21 	ret = ath12k_wmi_simulate_radar(ar);
22 	if (ret)
23 		goto exit;
24 
25 	ret = count;
26 exit:
27 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
28 	return ret;
29 }
30 
31 static const struct file_operations fops_simulate_radar = {
32 	.write = ath12k_write_simulate_radar,
33 	.open = simple_open
34 };
35 
36 static ssize_t ath12k_write_tpc_stats_type(struct file *file,
37 					   const char __user *user_buf,
38 					   size_t count, loff_t *ppos)
39 {
40 	struct ath12k *ar = file->private_data;
41 	u8 type;
42 	int ret;
43 
44 	ret = kstrtou8_from_user(user_buf, count, 0, &type);
45 	if (ret)
46 		return ret;
47 
48 	if (type >= WMI_HALPHY_PDEV_TX_STATS_MAX)
49 		return -EINVAL;
50 
51 	spin_lock_bh(&ar->data_lock);
52 	ar->debug.tpc_stats_type = type;
53 	spin_unlock_bh(&ar->data_lock);
54 
55 	return count;
56 }
57 
58 static int ath12k_debug_tpc_stats_request(struct ath12k *ar)
59 {
60 	enum wmi_halphy_ctrl_path_stats_id tpc_stats_sub_id;
61 	struct ath12k_base *ab = ar->ab;
62 	int ret;
63 
64 	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
65 
66 	reinit_completion(&ar->debug.tpc_complete);
67 
68 	spin_lock_bh(&ar->data_lock);
69 	ar->debug.tpc_request = true;
70 	tpc_stats_sub_id = ar->debug.tpc_stats_type;
71 	spin_unlock_bh(&ar->data_lock);
72 
73 	ret = ath12k_wmi_send_tpc_stats_request(ar, tpc_stats_sub_id);
74 	if (ret) {
75 		ath12k_warn(ab, "failed to request pdev tpc stats: %d\n", ret);
76 		spin_lock_bh(&ar->data_lock);
77 		ar->debug.tpc_request = false;
78 		spin_unlock_bh(&ar->data_lock);
79 		return ret;
80 	}
81 
82 	return 0;
83 }
84 
85 static int ath12k_get_tpc_ctl_mode_idx(struct wmi_tpc_stats_arg *tpc_stats,
86 				       enum wmi_tpc_pream_bw pream_bw, int *mode_idx)
87 {
88 	u32 chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq);
89 	u8 band;
90 
91 	band = ((chan_freq > ATH12K_MIN_6GHZ_FREQ) ? NL80211_BAND_6GHZ :
92 		((chan_freq > ATH12K_MIN_5GHZ_FREQ) ? NL80211_BAND_5GHZ :
93 		NL80211_BAND_2GHZ));
94 
95 	if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
96 		switch (pream_bw) {
97 		case WMI_TPC_PREAM_HT20:
98 		case WMI_TPC_PREAM_VHT20:
99 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT20_5GHZ_6GHZ;
100 			break;
101 		case WMI_TPC_PREAM_HE20:
102 		case WMI_TPC_PREAM_EHT20:
103 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT20_5GHZ_6GHZ;
104 			break;
105 		case WMI_TPC_PREAM_HT40:
106 		case WMI_TPC_PREAM_VHT40:
107 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT40_5GHZ_6GHZ;
108 			break;
109 		case WMI_TPC_PREAM_HE40:
110 		case WMI_TPC_PREAM_EHT40:
111 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT40_5GHZ_6GHZ;
112 			break;
113 		case WMI_TPC_PREAM_VHT80:
114 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT80_5GHZ_6GHZ;
115 			break;
116 		case WMI_TPC_PREAM_EHT60:
117 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT80_SU_PUNC20;
118 			break;
119 		case WMI_TPC_PREAM_HE80:
120 		case WMI_TPC_PREAM_EHT80:
121 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT80_5GHZ_6GHZ;
122 			break;
123 		case WMI_TPC_PREAM_VHT160:
124 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT160_5GHZ_6GHZ;
125 			break;
126 		case WMI_TPC_PREAM_EHT120:
127 		case WMI_TPC_PREAM_EHT140:
128 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT160_SU_PUNC20;
129 			break;
130 		case WMI_TPC_PREAM_HE160:
131 		case WMI_TPC_PREAM_EHT160:
132 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT160_5GHZ_6GHZ;
133 			break;
134 		case WMI_TPC_PREAM_EHT200:
135 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC120;
136 			break;
137 		case WMI_TPC_PREAM_EHT240:
138 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC80;
139 			break;
140 		case WMI_TPC_PREAM_EHT280:
141 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC40;
142 			break;
143 		case WMI_TPC_PREAM_EHT320:
144 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT320_5GHZ_6GHZ;
145 			break;
146 		default:
147 			/* for 5GHZ and 6GHZ, default case will be for OFDM */
148 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_5GHZ_6GHZ;
149 			break;
150 		}
151 	} else {
152 		switch (pream_bw) {
153 		case WMI_TPC_PREAM_OFDM:
154 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_2GHZ;
155 			break;
156 		case WMI_TPC_PREAM_HT20:
157 		case WMI_TPC_PREAM_VHT20:
158 		case WMI_TPC_PREAM_HE20:
159 		case WMI_TPC_PREAM_EHT20:
160 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT20_2GHZ;
161 			break;
162 		case WMI_TPC_PREAM_HT40:
163 		case WMI_TPC_PREAM_VHT40:
164 		case WMI_TPC_PREAM_HE40:
165 		case WMI_TPC_PREAM_EHT40:
166 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT40_2GHZ;
167 			break;
168 		default:
169 			/* for 2GHZ, default case will be CCK */
170 			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_CCK_2GHZ;
171 			break;
172 		}
173 	}
174 
175 	return 0;
176 }
177 
178 static s16 ath12k_tpc_get_rate(struct ath12k *ar,
179 			       struct wmi_tpc_stats_arg *tpc_stats,
180 			       u32 rate_idx, u32 num_chains, u32 rate_code,
181 			       enum wmi_tpc_pream_bw pream_bw,
182 			       enum wmi_halphy_ctrl_path_stats_id type,
183 			       u32 eht_rate_idx)
184 {
185 	u32 tot_nss, tot_modes, txbf_on_off, index_offset1, index_offset2, index_offset3;
186 	u8 chain_idx, stm_idx, num_streams;
187 	bool is_mu, txbf_enabled = 0;
188 	s8 rates_ctl_min, tpc_ctl;
189 	s16 rates, tpc, reg_pwr;
190 	u16 rate1, rate2;
191 	int mode, ret;
192 
193 	num_streams = 1 + ATH12K_HW_NSS(rate_code);
194 	chain_idx = num_chains - 1;
195 	stm_idx = num_streams - 1;
196 	mode = -1;
197 
198 	ret = ath12k_get_tpc_ctl_mode_idx(tpc_stats, pream_bw, &mode);
199 	if (ret) {
200 		ath12k_warn(ar->ab, "Invalid mode index received\n");
201 		tpc = TPC_INVAL;
202 		goto out;
203 	}
204 
205 	if (num_chains < num_streams) {
206 		tpc = TPC_INVAL;
207 		goto out;
208 	}
209 
210 	if (le32_to_cpu(tpc_stats->tpc_config.num_tx_chain) <= 1) {
211 		tpc = TPC_INVAL;
212 		goto out;
213 	}
214 
215 	if (type == WMI_HALPHY_PDEV_TX_SUTXBF_STATS ||
216 	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS)
217 		txbf_enabled = 1;
218 
219 	if (type == WMI_HALPHY_PDEV_TX_MU_STATS ||
220 	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) {
221 		is_mu = true;
222 	} else {
223 		is_mu = false;
224 	}
225 
226 	/* Below is the min calculation of ctl array, rates array and
227 	 * regulator power table. tpc is minimum of all 3
228 	 */
229 	if (pream_bw >= WMI_TPC_PREAM_EHT20 && pream_bw <= WMI_TPC_PREAM_EHT320) {
230 		rate2 = tpc_stats->rates_array2.rate_array[eht_rate_idx];
231 		if (is_mu)
232 			rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_MU);
233 		else
234 			rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_SU);
235 	} else {
236 		rate1 = tpc_stats->rates_array1.rate_array[rate_idx];
237 		if (is_mu)
238 			rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_MU);
239 		else
240 			rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_SU);
241 	}
242 
243 	if (tpc_stats->tlvs_rcvd & WMI_TPC_CTL_PWR_ARRAY) {
244 		tot_nss = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d1);
245 		tot_modes = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d2);
246 		txbf_on_off = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d3);
247 		index_offset1 = txbf_on_off * tot_modes * tot_nss;
248 		index_offset2 = tot_modes * tot_nss;
249 		index_offset3 = tot_nss;
250 
251 		tpc_ctl = *(tpc_stats->ctl_array.ctl_pwr_table +
252 			    chain_idx * index_offset1 + txbf_enabled * index_offset2
253 			    + mode * index_offset3 + stm_idx);
254 	} else {
255 		tpc_ctl = TPC_MAX;
256 		ath12k_warn(ar->ab,
257 			    "ctl array for tpc stats not received from fw\n");
258 	}
259 
260 	rates_ctl_min = min_t(s16, rates, tpc_ctl);
261 
262 	reg_pwr = tpc_stats->max_reg_allowed_power.reg_pwr_array[chain_idx];
263 
264 	if (reg_pwr < 0)
265 		reg_pwr = TPC_INVAL;
266 
267 	tpc = min_t(s16, rates_ctl_min, reg_pwr);
268 
269 	/* MODULATION_LIMIT is the maximum power limit,tpc should not exceed
270 	 * modulation limit even if min tpc of all three array is greater
271 	 * modulation limit
272 	 */
273 	tpc = min_t(s16, tpc, MODULATION_LIMIT);
274 
275 out:
276 	return tpc;
277 }
278 
279 static u16 ath12k_get_ratecode(u16 pream_idx, u16 nss, u16 mcs_rate)
280 {
281 	u16 mode_type = ~0;
282 
283 	/* Below assignments are just for printing purpose only */
284 	switch (pream_idx) {
285 	case WMI_TPC_PREAM_CCK:
286 		mode_type = WMI_RATE_PREAMBLE_CCK;
287 		break;
288 	case WMI_TPC_PREAM_OFDM:
289 		mode_type = WMI_RATE_PREAMBLE_OFDM;
290 		break;
291 	case WMI_TPC_PREAM_HT20:
292 	case WMI_TPC_PREAM_HT40:
293 		mode_type = WMI_RATE_PREAMBLE_HT;
294 		break;
295 	case WMI_TPC_PREAM_VHT20:
296 	case WMI_TPC_PREAM_VHT40:
297 	case WMI_TPC_PREAM_VHT80:
298 	case WMI_TPC_PREAM_VHT160:
299 		mode_type = WMI_RATE_PREAMBLE_VHT;
300 		break;
301 	case WMI_TPC_PREAM_HE20:
302 	case WMI_TPC_PREAM_HE40:
303 	case WMI_TPC_PREAM_HE80:
304 	case WMI_TPC_PREAM_HE160:
305 		mode_type = WMI_RATE_PREAMBLE_HE;
306 		break;
307 	case WMI_TPC_PREAM_EHT20:
308 	case WMI_TPC_PREAM_EHT40:
309 	case WMI_TPC_PREAM_EHT60:
310 	case WMI_TPC_PREAM_EHT80:
311 	case WMI_TPC_PREAM_EHT120:
312 	case WMI_TPC_PREAM_EHT140:
313 	case WMI_TPC_PREAM_EHT160:
314 	case WMI_TPC_PREAM_EHT200:
315 	case WMI_TPC_PREAM_EHT240:
316 	case WMI_TPC_PREAM_EHT280:
317 	case WMI_TPC_PREAM_EHT320:
318 		mode_type = WMI_RATE_PREAMBLE_EHT;
319 		if (mcs_rate == 0 || mcs_rate == 1)
320 			mcs_rate += 14;
321 		else
322 			mcs_rate -= 2;
323 		break;
324 	default:
325 		return mode_type;
326 	}
327 	return ((mode_type << 8) | ((nss & 0x7) << 5) | (mcs_rate & 0x1F));
328 }
329 
330 static bool ath12k_he_supports_extra_mcs(struct ath12k *ar, int freq)
331 {
332 	struct ath12k_pdev_cap *cap = &ar->pdev->cap;
333 	struct ath12k_band_cap *cap_band;
334 	bool extra_mcs_supported;
335 
336 	if (freq <= ATH12K_2GHZ_MAX_FREQUENCY)
337 		cap_band = &cap->band[NL80211_BAND_2GHZ];
338 	else if (freq <= ATH12K_5GHZ_MAX_FREQUENCY)
339 		cap_band = &cap->band[NL80211_BAND_5GHZ];
340 	else
341 		cap_band = &cap->band[NL80211_BAND_6GHZ];
342 
343 	extra_mcs_supported = u32_get_bits(cap_band->he_cap_info[1],
344 					   HE_EXTRA_MCS_SUPPORT);
345 	return extra_mcs_supported;
346 }
347 
348 static int ath12k_tpc_fill_pream(struct ath12k *ar, char *buf, int buf_len, int len,
349 				 enum wmi_tpc_pream_bw pream_bw, u32 max_rix,
350 				 int max_nss, int max_rates, int pream_type,
351 				 enum wmi_halphy_ctrl_path_stats_id tpc_type,
352 				 int rate_idx, int eht_rate_idx)
353 {
354 	struct wmi_tpc_stats_arg *tpc_stats = ar->debug.tpc_stats;
355 	int nss, rates, chains;
356 	u8 active_tx_chains;
357 	u16 rate_code;
358 	s16 tpc;
359 
360 	static const char *const pream_str[] = {
361 		[WMI_TPC_PREAM_CCK]     = "CCK",
362 		[WMI_TPC_PREAM_OFDM]    = "OFDM",
363 		[WMI_TPC_PREAM_HT20]    = "HT20",
364 		[WMI_TPC_PREAM_HT40]    = "HT40",
365 		[WMI_TPC_PREAM_VHT20]   = "VHT20",
366 		[WMI_TPC_PREAM_VHT40]   = "VHT40",
367 		[WMI_TPC_PREAM_VHT80]   = "VHT80",
368 		[WMI_TPC_PREAM_VHT160]  = "VHT160",
369 		[WMI_TPC_PREAM_HE20]    = "HE20",
370 		[WMI_TPC_PREAM_HE40]    = "HE40",
371 		[WMI_TPC_PREAM_HE80]    = "HE80",
372 		[WMI_TPC_PREAM_HE160]   = "HE160",
373 		[WMI_TPC_PREAM_EHT20]   = "EHT20",
374 		[WMI_TPC_PREAM_EHT40]   = "EHT40",
375 		[WMI_TPC_PREAM_EHT60]   = "EHT60",
376 		[WMI_TPC_PREAM_EHT80]   = "EHT80",
377 		[WMI_TPC_PREAM_EHT120]   = "EHT120",
378 		[WMI_TPC_PREAM_EHT140]   = "EHT140",
379 		[WMI_TPC_PREAM_EHT160]   = "EHT160",
380 		[WMI_TPC_PREAM_EHT200]   = "EHT200",
381 		[WMI_TPC_PREAM_EHT240]   = "EHT240",
382 		[WMI_TPC_PREAM_EHT280]   = "EHT280",
383 		[WMI_TPC_PREAM_EHT320]   = "EHT320"};
384 
385 	active_tx_chains = ar->num_tx_chains;
386 
387 	for (nss = 0; nss < max_nss; nss++) {
388 		for (rates = 0; rates < max_rates; rates++, rate_idx++, max_rix++) {
389 			/* FW send extra MCS(10&11) for VHT and HE rates,
390 			 *  this is not used. Hence skipping it here
391 			 */
392 			if (pream_type == WMI_RATE_PREAMBLE_VHT &&
393 			    rates > ATH12K_VHT_MCS_MAX)
394 				continue;
395 
396 			if (pream_type == WMI_RATE_PREAMBLE_HE &&
397 			    rates > ATH12K_HE_MCS_MAX)
398 				continue;
399 
400 			if (pream_type == WMI_RATE_PREAMBLE_EHT &&
401 			    rates > ATH12K_EHT_MCS_MAX)
402 				continue;
403 
404 			rate_code = ath12k_get_ratecode(pream_bw, nss, rates);
405 			len += scnprintf(buf + len, buf_len - len,
406 					 "%d\t %s\t 0x%03x\t", max_rix,
407 					 pream_str[pream_bw], rate_code);
408 
409 			for (chains = 0; chains < active_tx_chains; chains++) {
410 				if (nss > chains) {
411 					len += scnprintf(buf + len,
412 							 buf_len - len,
413 							 "\t%s", "NA");
414 				} else {
415 					tpc = ath12k_tpc_get_rate(ar, tpc_stats,
416 								  rate_idx, chains + 1,
417 								  rate_code, pream_bw,
418 								  tpc_type,
419 								  eht_rate_idx);
420 
421 					if (tpc == TPC_INVAL) {
422 						len += scnprintf(buf + len,
423 								 buf_len - len, "\tNA");
424 					} else {
425 						len += scnprintf(buf + len,
426 								 buf_len - len, "\t%d",
427 								 tpc);
428 					}
429 				}
430 			}
431 			len += scnprintf(buf + len, buf_len - len, "\n");
432 
433 			if (pream_type == WMI_RATE_PREAMBLE_EHT)
434 				/*For fetching the next eht rates pwr from rates array2*/
435 				++eht_rate_idx;
436 		}
437 	}
438 
439 	return len;
440 }
441 
442 static int ath12k_tpc_stats_print(struct ath12k *ar,
443 				  struct wmi_tpc_stats_arg *tpc_stats,
444 				  char *buf, size_t len,
445 				  enum wmi_halphy_ctrl_path_stats_id type)
446 {
447 	u32 eht_idx = 0, pream_idx = 0, rate_pream_idx = 0, total_rates = 0, max_rix = 0;
448 	u32 chan_freq, num_tx_chain, caps, i, j = 1;
449 	size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE;
450 	u8 nss, active_tx_chains;
451 	bool he_ext_mcs;
452 	static const char *const type_str[WMI_HALPHY_PDEV_TX_STATS_MAX] = {
453 		[WMI_HALPHY_PDEV_TX_SU_STATS]		= "SU",
454 		[WMI_HALPHY_PDEV_TX_SUTXBF_STATS]	= "SU WITH TXBF",
455 		[WMI_HALPHY_PDEV_TX_MU_STATS]		= "MU",
456 		[WMI_HALPHY_PDEV_TX_MUTXBF_STATS]	= "MU WITH TXBF"};
457 
458 	u8 max_rates[WMI_TPC_PREAM_MAX] = {
459 		[WMI_TPC_PREAM_CCK]     = ATH12K_CCK_RATES,
460 		[WMI_TPC_PREAM_OFDM]    = ATH12K_OFDM_RATES,
461 		[WMI_TPC_PREAM_HT20]    = ATH12K_HT_RATES,
462 		[WMI_TPC_PREAM_HT40]    = ATH12K_HT_RATES,
463 		[WMI_TPC_PREAM_VHT20]   = ATH12K_VHT_RATES,
464 		[WMI_TPC_PREAM_VHT40]   = ATH12K_VHT_RATES,
465 		[WMI_TPC_PREAM_VHT80]   = ATH12K_VHT_RATES,
466 		[WMI_TPC_PREAM_VHT160]  = ATH12K_VHT_RATES,
467 		[WMI_TPC_PREAM_HE20]    = ATH12K_HE_RATES,
468 		[WMI_TPC_PREAM_HE40]    = ATH12K_HE_RATES,
469 		[WMI_TPC_PREAM_HE80]    = ATH12K_HE_RATES,
470 		[WMI_TPC_PREAM_HE160]   = ATH12K_HE_RATES,
471 		[WMI_TPC_PREAM_EHT20]   = ATH12K_EHT_RATES,
472 		[WMI_TPC_PREAM_EHT40]   = ATH12K_EHT_RATES,
473 		[WMI_TPC_PREAM_EHT60]   = ATH12K_EHT_RATES,
474 		[WMI_TPC_PREAM_EHT80]   = ATH12K_EHT_RATES,
475 		[WMI_TPC_PREAM_EHT120]  = ATH12K_EHT_RATES,
476 		[WMI_TPC_PREAM_EHT140]  = ATH12K_EHT_RATES,
477 		[WMI_TPC_PREAM_EHT160]  = ATH12K_EHT_RATES,
478 		[WMI_TPC_PREAM_EHT200]  = ATH12K_EHT_RATES,
479 		[WMI_TPC_PREAM_EHT240]  = ATH12K_EHT_RATES,
480 		[WMI_TPC_PREAM_EHT280]  = ATH12K_EHT_RATES,
481 		[WMI_TPC_PREAM_EHT320]  = ATH12K_EHT_RATES};
482 	static const u8 max_nss[WMI_TPC_PREAM_MAX] = {
483 		[WMI_TPC_PREAM_CCK]     = ATH12K_NSS_1,
484 		[WMI_TPC_PREAM_OFDM]    = ATH12K_NSS_1,
485 		[WMI_TPC_PREAM_HT20]    = ATH12K_NSS_4,
486 		[WMI_TPC_PREAM_HT40]    = ATH12K_NSS_4,
487 		[WMI_TPC_PREAM_VHT20]   = ATH12K_NSS_8,
488 		[WMI_TPC_PREAM_VHT40]   = ATH12K_NSS_8,
489 		[WMI_TPC_PREAM_VHT80]   = ATH12K_NSS_8,
490 		[WMI_TPC_PREAM_VHT160]  = ATH12K_NSS_4,
491 		[WMI_TPC_PREAM_HE20]    = ATH12K_NSS_8,
492 		[WMI_TPC_PREAM_HE40]    = ATH12K_NSS_8,
493 		[WMI_TPC_PREAM_HE80]    = ATH12K_NSS_8,
494 		[WMI_TPC_PREAM_HE160]   = ATH12K_NSS_4,
495 		[WMI_TPC_PREAM_EHT20]   = ATH12K_NSS_4,
496 		[WMI_TPC_PREAM_EHT40]   = ATH12K_NSS_4,
497 		[WMI_TPC_PREAM_EHT60]   = ATH12K_NSS_4,
498 		[WMI_TPC_PREAM_EHT80]   = ATH12K_NSS_4,
499 		[WMI_TPC_PREAM_EHT120]  = ATH12K_NSS_4,
500 		[WMI_TPC_PREAM_EHT140]  = ATH12K_NSS_4,
501 		[WMI_TPC_PREAM_EHT160]  = ATH12K_NSS_4,
502 		[WMI_TPC_PREAM_EHT200]  = ATH12K_NSS_4,
503 		[WMI_TPC_PREAM_EHT240]  = ATH12K_NSS_4,
504 		[WMI_TPC_PREAM_EHT280]  = ATH12K_NSS_4,
505 		[WMI_TPC_PREAM_EHT320]  = ATH12K_NSS_4};
506 
507 	u16 rate_idx[WMI_TPC_PREAM_MAX] = {}, eht_rate_idx[WMI_TPC_PREAM_MAX] = {};
508 	static const u8 pream_type[WMI_TPC_PREAM_MAX] = {
509 		[WMI_TPC_PREAM_CCK]     = WMI_RATE_PREAMBLE_CCK,
510 		[WMI_TPC_PREAM_OFDM]    = WMI_RATE_PREAMBLE_OFDM,
511 		[WMI_TPC_PREAM_HT20]    = WMI_RATE_PREAMBLE_HT,
512 		[WMI_TPC_PREAM_HT40]    = WMI_RATE_PREAMBLE_HT,
513 		[WMI_TPC_PREAM_VHT20]   = WMI_RATE_PREAMBLE_VHT,
514 		[WMI_TPC_PREAM_VHT40]   = WMI_RATE_PREAMBLE_VHT,
515 		[WMI_TPC_PREAM_VHT80]   = WMI_RATE_PREAMBLE_VHT,
516 		[WMI_TPC_PREAM_VHT160]  = WMI_RATE_PREAMBLE_VHT,
517 		[WMI_TPC_PREAM_HE20]    = WMI_RATE_PREAMBLE_HE,
518 		[WMI_TPC_PREAM_HE40]    = WMI_RATE_PREAMBLE_HE,
519 		[WMI_TPC_PREAM_HE80]    = WMI_RATE_PREAMBLE_HE,
520 		[WMI_TPC_PREAM_HE160]   = WMI_RATE_PREAMBLE_HE,
521 		[WMI_TPC_PREAM_EHT20]   = WMI_RATE_PREAMBLE_EHT,
522 		[WMI_TPC_PREAM_EHT40]   = WMI_RATE_PREAMBLE_EHT,
523 		[WMI_TPC_PREAM_EHT60]   = WMI_RATE_PREAMBLE_EHT,
524 		[WMI_TPC_PREAM_EHT80]   = WMI_RATE_PREAMBLE_EHT,
525 		[WMI_TPC_PREAM_EHT120]  = WMI_RATE_PREAMBLE_EHT,
526 		[WMI_TPC_PREAM_EHT140]  = WMI_RATE_PREAMBLE_EHT,
527 		[WMI_TPC_PREAM_EHT160]  = WMI_RATE_PREAMBLE_EHT,
528 		[WMI_TPC_PREAM_EHT200]  = WMI_RATE_PREAMBLE_EHT,
529 		[WMI_TPC_PREAM_EHT240]  = WMI_RATE_PREAMBLE_EHT,
530 		[WMI_TPC_PREAM_EHT280]  = WMI_RATE_PREAMBLE_EHT,
531 		[WMI_TPC_PREAM_EHT320]  = WMI_RATE_PREAMBLE_EHT};
532 
533 	chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq);
534 	num_tx_chain = le32_to_cpu(tpc_stats->tpc_config.num_tx_chain);
535 	caps = le32_to_cpu(tpc_stats->tpc_config.caps);
536 
537 	active_tx_chains = ar->num_tx_chains;
538 	he_ext_mcs = ath12k_he_supports_extra_mcs(ar, chan_freq);
539 
540 	/* mcs 12&13 is sent by FW for certain HWs in rate array, skipping it as
541 	 * it is not supported
542 	 */
543 	if (he_ext_mcs) {
544 		for (i = WMI_TPC_PREAM_HE20; i <= WMI_TPC_PREAM_HE160; ++i)
545 			max_rates[i] = ATH12K_HE_RATES;
546 	}
547 
548 	if (type == WMI_HALPHY_PDEV_TX_MU_STATS ||
549 	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) {
550 		pream_idx = WMI_TPC_PREAM_VHT20;
551 
552 		for (i = WMI_TPC_PREAM_CCK; i <= WMI_TPC_PREAM_HT40; ++i)
553 			max_rix += max_nss[i] * max_rates[i];
554 	}
555 	/* Enumerate all the rate indices */
556 	for (i = rate_pream_idx + 1; i < WMI_TPC_PREAM_MAX; i++) {
557 		nss = (max_nss[i - 1] < num_tx_chain ?
558 		       max_nss[i - 1] : num_tx_chain);
559 
560 		rate_idx[i] = rate_idx[i - 1] + max_rates[i - 1] * nss;
561 
562 		if (pream_type[i] == WMI_RATE_PREAMBLE_EHT) {
563 			eht_rate_idx[j] = eht_rate_idx[j - 1] + max_rates[i] * nss;
564 			++j;
565 		}
566 	}
567 
568 	for (i = 0; i < WMI_TPC_PREAM_MAX; i++) {
569 		nss = (max_nss[i] < num_tx_chain ?
570 		       max_nss[i] : num_tx_chain);
571 		total_rates += max_rates[i] * nss;
572 	}
573 
574 	len += scnprintf(buf + len, buf_len - len,
575 			 "No.of rates-%d\n", total_rates);
576 
577 	len += scnprintf(buf + len, buf_len - len,
578 			 "**************** %s ****************\n",
579 			 type_str[type]);
580 	len += scnprintf(buf + len, buf_len - len,
581 			 "\t\t\t\tTPC values for Active chains\n");
582 	len += scnprintf(buf + len, buf_len - len,
583 			 "Rate idx Preamble Rate code");
584 
585 	for (i = 1; i <= active_tx_chains; ++i) {
586 		len += scnprintf(buf + len, buf_len - len,
587 				 "\t%d-Chain", i);
588 	}
589 
590 	len += scnprintf(buf + len, buf_len - len, "\n");
591 	for (i = pream_idx; i < WMI_TPC_PREAM_MAX; i++) {
592 		if (chan_freq <= 2483) {
593 			if (i == WMI_TPC_PREAM_VHT80 ||
594 			    i == WMI_TPC_PREAM_VHT160 ||
595 			    i == WMI_TPC_PREAM_HE80 ||
596 			    i == WMI_TPC_PREAM_HE160 ||
597 			    (i >= WMI_TPC_PREAM_EHT60 &&
598 			     i <= WMI_TPC_PREAM_EHT320)) {
599 				max_rix += max_nss[i] * max_rates[i];
600 				continue;
601 			}
602 		} else {
603 			if (i == WMI_TPC_PREAM_CCK) {
604 				max_rix += max_rates[i];
605 				continue;
606 			}
607 		}
608 
609 		nss = (max_nss[i] < ar->num_tx_chains ? max_nss[i] : ar->num_tx_chains);
610 
611 		if (!(caps &
612 		    (1 << ATH12K_TPC_STATS_SUPPORT_BE_PUNC))) {
613 			if (i == WMI_TPC_PREAM_EHT60 || i == WMI_TPC_PREAM_EHT120 ||
614 			    i == WMI_TPC_PREAM_EHT140 || i == WMI_TPC_PREAM_EHT200 ||
615 			    i == WMI_TPC_PREAM_EHT240 || i == WMI_TPC_PREAM_EHT280) {
616 				max_rix += max_nss[i] * max_rates[i];
617 				continue;
618 			}
619 		}
620 
621 		len = ath12k_tpc_fill_pream(ar, buf, buf_len, len, i, max_rix, nss,
622 					    max_rates[i], pream_type[i],
623 					    type, rate_idx[i], eht_rate_idx[eht_idx]);
624 
625 		if (pream_type[i] == WMI_RATE_PREAMBLE_EHT)
626 			/*For fetch the next index eht rates from rates array2*/
627 			++eht_idx;
628 
629 		max_rix += max_nss[i] * max_rates[i];
630 	}
631 	return len;
632 }
633 
634 static void ath12k_tpc_stats_fill(struct ath12k *ar,
635 				  struct wmi_tpc_stats_arg *tpc_stats,
636 				  char *buf)
637 {
638 	size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE;
639 	struct wmi_tpc_config_params *tpc;
640 	size_t len = 0;
641 
642 	if (!tpc_stats) {
643 		ath12k_warn(ar->ab, "failed to find tpc stats\n");
644 		return;
645 	}
646 
647 	spin_lock_bh(&ar->data_lock);
648 
649 	tpc = &tpc_stats->tpc_config;
650 	len += scnprintf(buf + len, buf_len - len, "\n");
651 	len += scnprintf(buf + len, buf_len - len,
652 			 "*************** TPC config **************\n");
653 	len += scnprintf(buf + len, buf_len - len,
654 			 "* powers are in 0.25 dBm steps\n");
655 	len += scnprintf(buf + len, buf_len - len,
656 			 "reg domain-%d\t\tchan freq-%d\n",
657 			 tpc->reg_domain, tpc->chan_freq);
658 	len += scnprintf(buf + len, buf_len - len,
659 			 "power limit-%d\t\tmax reg-domain Power-%d\n",
660 			 le32_to_cpu(tpc->twice_max_reg_power) / 2, tpc->power_limit);
661 	len += scnprintf(buf + len, buf_len - len,
662 			 "No.of tx chain-%d\t",
663 			 ar->num_tx_chains);
664 
665 	ath12k_tpc_stats_print(ar, tpc_stats, buf, len,
666 			       ar->debug.tpc_stats_type);
667 
668 	spin_unlock_bh(&ar->data_lock);
669 }
670 
671 static int ath12k_open_tpc_stats(struct inode *inode, struct file *file)
672 {
673 	struct ath12k *ar = inode->i_private;
674 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
675 	int ret;
676 
677 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
678 
679 	if (ah->state != ATH12K_HW_STATE_ON) {
680 		ath12k_warn(ar->ab, "Interface not up\n");
681 		return -ENETDOWN;
682 	}
683 
684 	void *buf __free(kfree) = kzalloc(ATH12K_TPC_STATS_BUF_SIZE, GFP_KERNEL);
685 	if (!buf)
686 		return -ENOMEM;
687 
688 	ret = ath12k_debug_tpc_stats_request(ar);
689 	if (ret) {
690 		ath12k_warn(ar->ab, "failed to request tpc stats: %d\n",
691 			    ret);
692 		return ret;
693 	}
694 
695 	if (!wait_for_completion_timeout(&ar->debug.tpc_complete, TPC_STATS_WAIT_TIME)) {
696 		spin_lock_bh(&ar->data_lock);
697 		ath12k_wmi_free_tpc_stats_mem(ar);
698 		ar->debug.tpc_request = false;
699 		spin_unlock_bh(&ar->data_lock);
700 		return -ETIMEDOUT;
701 	}
702 
703 	ath12k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
704 	file->private_data = no_free_ptr(buf);
705 
706 	spin_lock_bh(&ar->data_lock);
707 	ath12k_wmi_free_tpc_stats_mem(ar);
708 	spin_unlock_bh(&ar->data_lock);
709 
710 	return 0;
711 }
712 
713 static ssize_t ath12k_read_tpc_stats(struct file *file,
714 				     char __user *user_buf,
715 				     size_t count, loff_t *ppos)
716 {
717 	const char *buf = file->private_data;
718 	size_t len = strlen(buf);
719 
720 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
721 }
722 
723 static int ath12k_release_tpc_stats(struct inode *inode,
724 				    struct file *file)
725 {
726 	kfree(file->private_data);
727 	return 0;
728 }
729 
730 static const struct file_operations fops_tpc_stats = {
731 	.open = ath12k_open_tpc_stats,
732 	.release = ath12k_release_tpc_stats,
733 	.read = ath12k_read_tpc_stats,
734 	.owner = THIS_MODULE,
735 	.llseek = default_llseek,
736 };
737 
738 static const struct file_operations fops_tpc_stats_type = {
739 	.write = ath12k_write_tpc_stats_type,
740 	.open = simple_open,
741 	.llseek = default_llseek,
742 };
743 
744 static ssize_t ath12k_write_extd_rx_stats(struct file *file,
745 					  const char __user *ubuf,
746 					  size_t count, loff_t *ppos)
747 {
748 	struct ath12k *ar = file->private_data;
749 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
750 	u32 ring_id, rx_filter = 0;
751 	bool enable;
752 	int ret, i;
753 
754 	if (kstrtobool_from_user(ubuf, count, &enable))
755 		return -EINVAL;
756 
757 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
758 
759 	if (!ar->ab->hw_params->rxdma1_enable) {
760 		ret = count;
761 		goto exit;
762 	}
763 
764 	if (ar->ah->state != ATH12K_HW_STATE_ON) {
765 		ret = -ENETDOWN;
766 		goto exit;
767 	}
768 
769 	if (enable == ar->debug.extd_rx_stats) {
770 		ret = count;
771 		goto exit;
772 	}
773 
774 	if (enable) {
775 		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
776 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
777 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
778 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
779 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
780 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
781 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO;
782 
783 		tlv_filter.rx_filter = rx_filter;
784 		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
785 		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
786 		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
787 		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
788 			HTT_RX_FP_DATA_FILTER_FLASG3;
789 	} else {
790 		tlv_filter = ath12k_mac_mon_status_filter_default;
791 	}
792 
793 	ar->debug.rx_filter = tlv_filter.rx_filter;
794 
795 	for (i = 0; i < ar->ab->hw_params->num_rxdma_per_pdev; i++) {
796 		ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id;
797 		ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id + i,
798 						       HAL_RXDMA_MONITOR_DST,
799 						       DP_RXDMA_REFILL_RING_SIZE,
800 						       &tlv_filter);
801 		if (ret) {
802 			ath12k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
803 			goto exit;
804 		}
805 	}
806 
807 	ar->debug.extd_rx_stats = !!enable;
808 	ret = count;
809 exit:
810 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
811 	return ret;
812 }
813 
814 static ssize_t ath12k_read_extd_rx_stats(struct file *file,
815 					 char __user *ubuf,
816 					 size_t count, loff_t *ppos)
817 {
818 	struct ath12k *ar = file->private_data;
819 	char buf[32];
820 	int len = 0;
821 
822 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
823 	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
824 			ar->debug.extd_rx_stats);
825 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
826 
827 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
828 }
829 
830 static const struct file_operations fops_extd_rx_stats = {
831 	.read = ath12k_read_extd_rx_stats,
832 	.write = ath12k_write_extd_rx_stats,
833 	.open = simple_open,
834 };
835 
836 static int ath12k_open_link_stats(struct inode *inode, struct file *file)
837 {
838 	struct ath12k_vif *ahvif = inode->i_private;
839 	size_t len = 0, buf_len = (PAGE_SIZE * 2);
840 	struct ath12k_link_stats linkstat;
841 	struct ath12k_link_vif *arvif;
842 	unsigned long links_map;
843 	struct wiphy *wiphy;
844 	int link_id, i;
845 	char *buf;
846 
847 	if (!ahvif)
848 		return -EINVAL;
849 
850 	buf = kzalloc(buf_len, GFP_KERNEL);
851 	if (!buf)
852 		return -ENOMEM;
853 
854 	wiphy = ahvif->ah->hw->wiphy;
855 	wiphy_lock(wiphy);
856 
857 	links_map = ahvif->links_map;
858 	for_each_set_bit(link_id, &links_map,
859 			 IEEE80211_MLD_MAX_NUM_LINKS) {
860 		arvif = rcu_dereference_protected(ahvif->link[link_id],
861 						  lockdep_is_held(&wiphy->mtx));
862 
863 		spin_lock_bh(&arvif->link_stats_lock);
864 		linkstat = arvif->link_stats;
865 		spin_unlock_bh(&arvif->link_stats_lock);
866 
867 		len += scnprintf(buf + len, buf_len - len,
868 				 "link[%d] Tx Unicast Frames Enqueued  = %d\n",
869 				 link_id, linkstat.tx_enqueued);
870 		len += scnprintf(buf + len, buf_len - len,
871 				 "link[%d] Tx Broadcast Frames Enqueued = %d\n",
872 				 link_id, linkstat.tx_bcast_mcast);
873 		len += scnprintf(buf + len, buf_len - len,
874 				 "link[%d] Tx Frames Completed = %d\n",
875 				 link_id, linkstat.tx_completed);
876 		len += scnprintf(buf + len, buf_len - len,
877 				 "link[%d] Tx Frames Dropped = %d\n",
878 				 link_id, linkstat.tx_dropped);
879 
880 		len += scnprintf(buf + len, buf_len - len,
881 				 "link[%d] Tx Frame descriptor Encap Type = ",
882 				 link_id);
883 
884 		len += scnprintf(buf + len, buf_len - len,
885 					 " raw:%d",
886 					 linkstat.tx_encap_type[0]);
887 
888 		len += scnprintf(buf + len, buf_len - len,
889 					 " native_wifi:%d",
890 					 linkstat.tx_encap_type[1]);
891 
892 		len += scnprintf(buf + len, buf_len - len,
893 					 " ethernet:%d",
894 					 linkstat.tx_encap_type[2]);
895 
896 		len += scnprintf(buf + len, buf_len - len,
897 				 "\nlink[%d] Tx Frame descriptor Encrypt Type = ",
898 				 link_id);
899 
900 		for (i = 0; i < HAL_ENCRYPT_TYPE_MAX; i++) {
901 			len += scnprintf(buf + len, buf_len - len,
902 					 " %d:%d", i,
903 					 linkstat.tx_encrypt_type[i]);
904 		}
905 		len += scnprintf(buf + len, buf_len - len,
906 				 "\nlink[%d] Tx Frame descriptor Type = buffer:%d extension:%d\n",
907 				 link_id, linkstat.tx_desc_type[0],
908 				 linkstat.tx_desc_type[1]);
909 
910 		len += scnprintf(buf + len, buf_len - len,
911 				"------------------------------------------------------\n");
912 	}
913 
914 	wiphy_unlock(wiphy);
915 
916 	file->private_data = buf;
917 
918 	return 0;
919 }
920 
921 static int ath12k_release_link_stats(struct inode *inode, struct file *file)
922 {
923 	kfree(file->private_data);
924 	return 0;
925 }
926 
927 static ssize_t ath12k_read_link_stats(struct file *file,
928 				      char __user *user_buf,
929 				      size_t count, loff_t *ppos)
930 {
931 	const char *buf = file->private_data;
932 	size_t len = strlen(buf);
933 
934 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
935 }
936 
937 static const struct file_operations ath12k_fops_link_stats = {
938 	.open = ath12k_open_link_stats,
939 	.release = ath12k_release_link_stats,
940 	.read = ath12k_read_link_stats,
941 	.owner = THIS_MODULE,
942 	.llseek = default_llseek,
943 };
944 
945 void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw,
946 			       struct ieee80211_vif *vif)
947 {
948 	struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
949 
950 	debugfs_create_file("link_stats", 0400, vif->debugfs_dir, ahvif,
951 			    &ath12k_fops_link_stats);
952 }
953 
954 void ath12k_debugfs_soc_create(struct ath12k_base *ab)
955 {
956 	bool dput_needed;
957 	char soc_name[64] = { 0 };
958 	struct dentry *debugfs_ath12k;
959 
960 	debugfs_ath12k = debugfs_lookup("ath12k", NULL);
961 	if (debugfs_ath12k) {
962 		/* a dentry from lookup() needs dput() after we don't use it */
963 		dput_needed = true;
964 	} else {
965 		debugfs_ath12k = debugfs_create_dir("ath12k", NULL);
966 		if (IS_ERR_OR_NULL(debugfs_ath12k))
967 			return;
968 		dput_needed = false;
969 	}
970 
971 	scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus),
972 		  dev_name(ab->dev));
973 
974 	ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k);
975 
976 	if (dput_needed)
977 		dput(debugfs_ath12k);
978 }
979 
980 void ath12k_debugfs_soc_destroy(struct ath12k_base *ab)
981 {
982 	debugfs_remove_recursive(ab->debugfs_soc);
983 	ab->debugfs_soc = NULL;
984 	/* We are not removing ath12k directory on purpose, even if it
985 	 * would be empty. This simplifies the directory handling and it's
986 	 * a minor cosmetic issue to leave an empty ath12k directory to
987 	 * debugfs.
988 	 */
989 }
990 
991 void
992 ath12k_debugfs_fw_stats_process(struct ath12k *ar,
993 				struct ath12k_fw_stats *stats)
994 {
995 	struct ath12k_base *ab = ar->ab;
996 	struct ath12k_pdev *pdev;
997 	bool is_end;
998 	static unsigned int num_vdev, num_bcn;
999 	size_t total_vdevs_started = 0;
1000 	int i;
1001 
1002 	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
1003 		if (list_empty(&stats->vdevs)) {
1004 			ath12k_warn(ab, "empty vdev stats");
1005 			return;
1006 		}
1007 		/* FW sends all the active VDEV stats irrespective of PDEV,
1008 		 * hence limit until the count of all VDEVs started
1009 		 */
1010 		rcu_read_lock();
1011 		for (i = 0; i < ab->num_radios; i++) {
1012 			pdev = rcu_dereference(ab->pdevs_active[i]);
1013 			if (pdev && pdev->ar)
1014 				total_vdevs_started += pdev->ar->num_started_vdevs;
1015 		}
1016 		rcu_read_unlock();
1017 
1018 		is_end = ((++num_vdev) == total_vdevs_started);
1019 
1020 		list_splice_tail_init(&stats->vdevs,
1021 				      &ar->fw_stats.vdevs);
1022 
1023 		if (is_end) {
1024 			ar->fw_stats.fw_stats_done = true;
1025 			num_vdev = 0;
1026 		}
1027 		return;
1028 	}
1029 	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
1030 		if (list_empty(&stats->bcn)) {
1031 			ath12k_warn(ab, "empty beacon stats");
1032 			return;
1033 		}
1034 		/* Mark end until we reached the count of all started VDEVs
1035 		 * within the PDEV
1036 		 */
1037 		is_end = ((++num_bcn) == ar->num_started_vdevs);
1038 
1039 		list_splice_tail_init(&stats->bcn,
1040 				      &ar->fw_stats.bcn);
1041 
1042 		if (is_end) {
1043 			ar->fw_stats.fw_stats_done = true;
1044 			num_bcn = 0;
1045 		}
1046 	}
1047 }
1048 
1049 static int ath12k_open_vdev_stats(struct inode *inode, struct file *file)
1050 {
1051 	struct ath12k *ar = inode->i_private;
1052 	struct ath12k_fw_stats_req_params param;
1053 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1054 	int ret;
1055 
1056 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1057 
1058 	if (!ah)
1059 		return -ENETDOWN;
1060 
1061 	if (ah->state != ATH12K_HW_STATE_ON)
1062 		return -ENETDOWN;
1063 
1064 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1065 	if (!buf)
1066 		return -ENOMEM;
1067 
1068 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1069 	/* VDEV stats is always sent for all active VDEVs from FW */
1070 	param.vdev_id = 0;
1071 	param.stats_id = WMI_REQUEST_VDEV_STAT;
1072 
1073 	ret = ath12k_mac_get_fw_stats(ar, &param);
1074 	if (ret) {
1075 		ath12k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
1076 		return ret;
1077 	}
1078 
1079 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1080 				 buf);
1081 
1082 	file->private_data = no_free_ptr(buf);
1083 
1084 	return 0;
1085 }
1086 
1087 static int ath12k_release_vdev_stats(struct inode *inode, struct file *file)
1088 {
1089 	kfree(file->private_data);
1090 
1091 	return 0;
1092 }
1093 
1094 static ssize_t ath12k_read_vdev_stats(struct file *file,
1095 				      char __user *user_buf,
1096 				      size_t count, loff_t *ppos)
1097 {
1098 	const char *buf = file->private_data;
1099 	size_t len = strlen(buf);
1100 
1101 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1102 }
1103 
1104 static const struct file_operations fops_vdev_stats = {
1105 	.open = ath12k_open_vdev_stats,
1106 	.release = ath12k_release_vdev_stats,
1107 	.read = ath12k_read_vdev_stats,
1108 	.owner = THIS_MODULE,
1109 	.llseek = default_llseek,
1110 };
1111 
1112 static int ath12k_open_bcn_stats(struct inode *inode, struct file *file)
1113 {
1114 	struct ath12k *ar = inode->i_private;
1115 	struct ath12k_link_vif *arvif;
1116 	struct ath12k_fw_stats_req_params param;
1117 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1118 	int ret;
1119 
1120 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1121 
1122 	if (ah && ah->state != ATH12K_HW_STATE_ON)
1123 		return -ENETDOWN;
1124 
1125 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1126 	if (!buf)
1127 		return -ENOMEM;
1128 
1129 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1130 	param.stats_id = WMI_REQUEST_BCN_STAT;
1131 
1132 	/* loop all active VDEVs for bcn stats */
1133 	list_for_each_entry(arvif, &ar->arvifs, list) {
1134 		if (!arvif->is_up)
1135 			continue;
1136 
1137 		param.vdev_id = arvif->vdev_id;
1138 		ret = ath12k_mac_get_fw_stats(ar, &param);
1139 		if (ret) {
1140 			ath12k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
1141 			return ret;
1142 		}
1143 	}
1144 
1145 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1146 				 buf);
1147 	/* since beacon stats request is looped for all active VDEVs, saved fw
1148 	 * stats is not freed for each request until done for all active VDEVs
1149 	 */
1150 	spin_lock_bh(&ar->data_lock);
1151 	ath12k_fw_stats_bcn_free(&ar->fw_stats.bcn);
1152 	spin_unlock_bh(&ar->data_lock);
1153 
1154 	file->private_data = no_free_ptr(buf);
1155 
1156 	return 0;
1157 }
1158 
1159 static int ath12k_release_bcn_stats(struct inode *inode, struct file *file)
1160 {
1161 	kfree(file->private_data);
1162 
1163 	return 0;
1164 }
1165 
1166 static ssize_t ath12k_read_bcn_stats(struct file *file,
1167 				     char __user *user_buf,
1168 				     size_t count, loff_t *ppos)
1169 {
1170 	const char *buf = file->private_data;
1171 	size_t len = strlen(buf);
1172 
1173 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1174 }
1175 
1176 static const struct file_operations fops_bcn_stats = {
1177 	.open = ath12k_open_bcn_stats,
1178 	.release = ath12k_release_bcn_stats,
1179 	.read = ath12k_read_bcn_stats,
1180 	.owner = THIS_MODULE,
1181 	.llseek = default_llseek,
1182 };
1183 
1184 static int ath12k_open_pdev_stats(struct inode *inode, struct file *file)
1185 {
1186 	struct ath12k *ar = inode->i_private;
1187 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1188 	struct ath12k_base *ab = ar->ab;
1189 	struct ath12k_fw_stats_req_params param;
1190 	int ret;
1191 
1192 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1193 
1194 	if (ah && ah->state != ATH12K_HW_STATE_ON)
1195 		return -ENETDOWN;
1196 
1197 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1198 	if (!buf)
1199 		return -ENOMEM;
1200 
1201 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1202 	param.vdev_id = 0;
1203 	param.stats_id = WMI_REQUEST_PDEV_STAT;
1204 
1205 	ret = ath12k_mac_get_fw_stats(ar, &param);
1206 	if (ret) {
1207 		ath12k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
1208 		return ret;
1209 	}
1210 
1211 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1212 				 buf);
1213 
1214 	file->private_data = no_free_ptr(buf);
1215 
1216 	return 0;
1217 }
1218 
1219 static int ath12k_release_pdev_stats(struct inode *inode, struct file *file)
1220 {
1221 	kfree(file->private_data);
1222 
1223 	return 0;
1224 }
1225 
1226 static ssize_t ath12k_read_pdev_stats(struct file *file,
1227 				      char __user *user_buf,
1228 				      size_t count, loff_t *ppos)
1229 {
1230 	const char *buf = file->private_data;
1231 	size_t len = strlen(buf);
1232 
1233 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1234 }
1235 
1236 static const struct file_operations fops_pdev_stats = {
1237 	.open = ath12k_open_pdev_stats,
1238 	.release = ath12k_release_pdev_stats,
1239 	.read = ath12k_read_pdev_stats,
1240 	.owner = THIS_MODULE,
1241 	.llseek = default_llseek,
1242 };
1243 
1244 static
1245 void ath12k_debugfs_fw_stats_register(struct ath12k *ar)
1246 {
1247 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1248 							ar->debug.debugfs_pdev);
1249 
1250 	/* all stats debugfs files created are under "fw_stats" directory
1251 	 * created per PDEV
1252 	 */
1253 	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1254 			    &fops_vdev_stats);
1255 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1256 			    &fops_bcn_stats);
1257 	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1258 			    &fops_pdev_stats);
1259 
1260 	ath12k_fw_stats_init(ar);
1261 }
1262 
1263 void ath12k_debugfs_register(struct ath12k *ar)
1264 {
1265 	struct ath12k_base *ab = ar->ab;
1266 	struct ieee80211_hw *hw = ar->ah->hw;
1267 	char pdev_name[5];
1268 	char buf[100] = {0};
1269 
1270 	scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1271 
1272 	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1273 
1274 	/* Create a symlink under ieee80211/phy* */
1275 	scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev);
1276 	ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k",
1277 								hw->wiphy->debugfsdir,
1278 								buf);
1279 
1280 	if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) {
1281 		debugfs_create_file("dfs_simulate_radar", 0200,
1282 				    ar->debug.debugfs_pdev, ar,
1283 				    &fops_simulate_radar);
1284 	}
1285 
1286 	debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_pdev, ar,
1287 			    &fops_tpc_stats);
1288 	debugfs_create_file("tpc_stats_type", 0200, ar->debug.debugfs_pdev,
1289 			    ar, &fops_tpc_stats_type);
1290 	init_completion(&ar->debug.tpc_complete);
1291 
1292 	ath12k_debugfs_htt_stats_register(ar);
1293 	ath12k_debugfs_fw_stats_register(ar);
1294 
1295 	debugfs_create_file("ext_rx_stats", 0644,
1296 			    ar->debug.debugfs_pdev, ar,
1297 			    &fops_extd_rx_stats);
1298 }
1299 
1300 void ath12k_debugfs_unregister(struct ath12k *ar)
1301 {
1302 	if (!ar->debug.debugfs_pdev)
1303 		return;
1304 
1305 	/* Remove symlink under ieee80211/phy* */
1306 	debugfs_remove(ar->debug.debugfs_pdev_symlink);
1307 	debugfs_remove_recursive(ar->debug.debugfs_pdev);
1308 	ar->debug.debugfs_pdev_symlink = NULL;
1309 	ar->debug.debugfs_pdev = NULL;
1310 }
1311