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 
ath12k_write_simulate_radar(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)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 
ath12k_write_tpc_stats_type(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)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 
ath12k_debug_tpc_stats_request(struct ath12k * ar)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 
ath12k_get_tpc_ctl_mode_idx(struct wmi_tpc_stats_arg * tpc_stats,enum wmi_tpc_pream_bw pream_bw,int * mode_idx)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_6G_FREQ) ? NL80211_BAND_6GHZ :
92 		((chan_freq > ATH12K_MIN_5G_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 
ath12k_tpc_get_rate(struct ath12k * ar,struct wmi_tpc_stats_arg * tpc_stats,u32 rate_idx,u32 num_chains,u32 rate_code,enum wmi_tpc_pream_bw pream_bw,enum wmi_halphy_ctrl_path_stats_id type,u32 eht_rate_idx)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 
ath12k_get_ratecode(u16 pream_idx,u16 nss,u16 mcs_rate)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 
ath12k_he_supports_extra_mcs(struct ath12k * ar,int freq)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 
ath12k_tpc_fill_pream(struct ath12k * ar,char * buf,int buf_len,int len,enum wmi_tpc_pream_bw pream_bw,u32 max_rix,int max_nss,int max_rates,int pream_type,enum wmi_halphy_ctrl_path_stats_id tpc_type,int rate_idx,int eht_rate_idx)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 
ath12k_tpc_stats_print(struct ath12k * ar,struct wmi_tpc_stats_arg * tpc_stats,char * buf,size_t len,enum wmi_halphy_ctrl_path_stats_id type)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 
ath12k_tpc_stats_fill(struct ath12k * ar,struct wmi_tpc_stats_arg * tpc_stats,char * buf)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 
ath12k_open_tpc_stats(struct inode * inode,struct file * file)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 
ath12k_read_tpc_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)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 
ath12k_release_tpc_stats(struct inode * inode,struct file * file)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 
ath12k_write_extd_rx_stats(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)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 
ath12k_read_extd_rx_stats(struct file * file,char __user * ubuf,size_t count,loff_t * ppos)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 
ath12k_debugfs_soc_create(struct ath12k_base * ab)836 void ath12k_debugfs_soc_create(struct ath12k_base *ab)
837 {
838 	bool dput_needed;
839 	char soc_name[64] = { 0 };
840 	struct dentry *debugfs_ath12k;
841 
842 	debugfs_ath12k = debugfs_lookup("ath12k", NULL);
843 	if (debugfs_ath12k) {
844 		/* a dentry from lookup() needs dput() after we don't use it */
845 		dput_needed = true;
846 	} else {
847 		debugfs_ath12k = debugfs_create_dir("ath12k", NULL);
848 		if (IS_ERR_OR_NULL(debugfs_ath12k))
849 			return;
850 		dput_needed = false;
851 	}
852 
853 	scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus),
854 		  dev_name(ab->dev));
855 
856 	ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k);
857 
858 	if (dput_needed)
859 		dput(debugfs_ath12k);
860 }
861 
ath12k_debugfs_soc_destroy(struct ath12k_base * ab)862 void ath12k_debugfs_soc_destroy(struct ath12k_base *ab)
863 {
864 	debugfs_remove_recursive(ab->debugfs_soc);
865 	ab->debugfs_soc = NULL;
866 	/* We are not removing ath12k directory on purpose, even if it
867 	 * would be empty. This simplifies the directory handling and it's
868 	 * a minor cosmetic issue to leave an empty ath12k directory to
869 	 * debugfs.
870 	 */
871 }
872 
ath12k_fw_stats_pdevs_free(struct list_head * head)873 static void ath12k_fw_stats_pdevs_free(struct list_head *head)
874 {
875 	struct ath12k_fw_stats_pdev *i, *tmp;
876 
877 	list_for_each_entry_safe(i, tmp, head, list) {
878 		list_del(&i->list);
879 		kfree(i);
880 	}
881 }
882 
ath12k_fw_stats_bcn_free(struct list_head * head)883 static void ath12k_fw_stats_bcn_free(struct list_head *head)
884 {
885 	struct ath12k_fw_stats_bcn *i, *tmp;
886 
887 	list_for_each_entry_safe(i, tmp, head, list) {
888 		list_del(&i->list);
889 		kfree(i);
890 	}
891 }
892 
ath12k_fw_stats_vdevs_free(struct list_head * head)893 static void ath12k_fw_stats_vdevs_free(struct list_head *head)
894 {
895 	struct ath12k_fw_stats_vdev *i, *tmp;
896 
897 	list_for_each_entry_safe(i, tmp, head, list) {
898 		list_del(&i->list);
899 		kfree(i);
900 	}
901 }
902 
ath12k_debugfs_fw_stats_reset(struct ath12k * ar)903 void ath12k_debugfs_fw_stats_reset(struct ath12k *ar)
904 {
905 	spin_lock_bh(&ar->data_lock);
906 	ar->fw_stats.fw_stats_done = false;
907 	ath12k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
908 	ath12k_fw_stats_bcn_free(&ar->fw_stats.bcn);
909 	ath12k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
910 	spin_unlock_bh(&ar->data_lock);
911 }
912 
ath12k_debugfs_fw_stats_request(struct ath12k * ar,struct ath12k_fw_stats_req_params * param)913 static int ath12k_debugfs_fw_stats_request(struct ath12k *ar,
914 					   struct ath12k_fw_stats_req_params *param)
915 {
916 	struct ath12k_base *ab = ar->ab;
917 	unsigned long timeout, time_left;
918 	int ret;
919 
920 	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
921 
922 	/* FW stats can get split when exceeding the stats data buffer limit.
923 	 * In that case, since there is no end marking for the back-to-back
924 	 * received 'update stats' event, we keep a 3 seconds timeout in case,
925 	 * fw_stats_done is not marked yet
926 	 */
927 	timeout = jiffies + msecs_to_jiffies(3 * 1000);
928 
929 	ath12k_debugfs_fw_stats_reset(ar);
930 
931 	reinit_completion(&ar->fw_stats_complete);
932 
933 	ret = ath12k_wmi_send_stats_request_cmd(ar, param->stats_id,
934 						param->vdev_id, param->pdev_id);
935 
936 	if (ret) {
937 		ath12k_warn(ab, "could not request fw stats (%d)\n",
938 			    ret);
939 		return ret;
940 	}
941 
942 	time_left = wait_for_completion_timeout(&ar->fw_stats_complete,
943 						1 * HZ);
944 	/* If the wait timed out, return -ETIMEDOUT */
945 	if (!time_left)
946 		return -ETIMEDOUT;
947 
948 	/* Firmware sends WMI_UPDATE_STATS_EVENTID back-to-back
949 	 * when stats data buffer limit is reached. fw_stats_complete
950 	 * is completed once host receives first event from firmware, but
951 	 * still end might not be marked in the TLV.
952 	 * Below loop is to confirm that firmware completed sending all the event
953 	 * and fw_stats_done is marked true when end is marked in the TLV
954 	 */
955 	for (;;) {
956 		if (time_after(jiffies, timeout))
957 			break;
958 
959 		spin_lock_bh(&ar->data_lock);
960 		if (ar->fw_stats.fw_stats_done) {
961 			spin_unlock_bh(&ar->data_lock);
962 			break;
963 		}
964 		spin_unlock_bh(&ar->data_lock);
965 	}
966 	return 0;
967 }
968 
969 void
ath12k_debugfs_fw_stats_process(struct ath12k * ar,struct ath12k_fw_stats * stats)970 ath12k_debugfs_fw_stats_process(struct ath12k *ar,
971 				struct ath12k_fw_stats *stats)
972 {
973 	struct ath12k_base *ab = ar->ab;
974 	struct ath12k_pdev *pdev;
975 	bool is_end;
976 	static unsigned int num_vdev, num_bcn;
977 	size_t total_vdevs_started = 0;
978 	int i;
979 
980 	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
981 		if (list_empty(&stats->vdevs)) {
982 			ath12k_warn(ab, "empty vdev stats");
983 			return;
984 		}
985 		/* FW sends all the active VDEV stats irrespective of PDEV,
986 		 * hence limit until the count of all VDEVs started
987 		 */
988 		rcu_read_lock();
989 		for (i = 0; i < ab->num_radios; i++) {
990 			pdev = rcu_dereference(ab->pdevs_active[i]);
991 			if (pdev && pdev->ar)
992 				total_vdevs_started += pdev->ar->num_started_vdevs;
993 		}
994 		rcu_read_unlock();
995 
996 		is_end = ((++num_vdev) == total_vdevs_started);
997 
998 		list_splice_tail_init(&stats->vdevs,
999 				      &ar->fw_stats.vdevs);
1000 
1001 		if (is_end) {
1002 			ar->fw_stats.fw_stats_done = true;
1003 			num_vdev = 0;
1004 		}
1005 		return;
1006 	}
1007 	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
1008 		if (list_empty(&stats->bcn)) {
1009 			ath12k_warn(ab, "empty beacon stats");
1010 			return;
1011 		}
1012 		/* Mark end until we reached the count of all started VDEVs
1013 		 * within the PDEV
1014 		 */
1015 		is_end = ((++num_bcn) == ar->num_started_vdevs);
1016 
1017 		list_splice_tail_init(&stats->bcn,
1018 				      &ar->fw_stats.bcn);
1019 
1020 		if (is_end) {
1021 			ar->fw_stats.fw_stats_done = true;
1022 			num_bcn = 0;
1023 		}
1024 	}
1025 	if (stats->stats_id == WMI_REQUEST_PDEV_STAT) {
1026 		list_splice_tail_init(&stats->pdevs, &ar->fw_stats.pdevs);
1027 		ar->fw_stats.fw_stats_done = true;
1028 	}
1029 }
1030 
ath12k_open_vdev_stats(struct inode * inode,struct file * file)1031 static int ath12k_open_vdev_stats(struct inode *inode, struct file *file)
1032 {
1033 	struct ath12k *ar = inode->i_private;
1034 	struct ath12k_fw_stats_req_params param;
1035 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1036 	int ret;
1037 
1038 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1039 
1040 	if (!ah)
1041 		return -ENETDOWN;
1042 
1043 	if (ah->state != ATH12K_HW_STATE_ON)
1044 		return -ENETDOWN;
1045 
1046 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1047 	if (!buf)
1048 		return -ENOMEM;
1049 
1050 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1051 	/* VDEV stats is always sent for all active VDEVs from FW */
1052 	param.vdev_id = 0;
1053 	param.stats_id = WMI_REQUEST_VDEV_STAT;
1054 
1055 	ret = ath12k_debugfs_fw_stats_request(ar, &param);
1056 	if (ret) {
1057 		ath12k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
1058 		return ret;
1059 	}
1060 
1061 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1062 				 buf);
1063 
1064 	file->private_data = no_free_ptr(buf);
1065 
1066 	return 0;
1067 }
1068 
ath12k_release_vdev_stats(struct inode * inode,struct file * file)1069 static int ath12k_release_vdev_stats(struct inode *inode, struct file *file)
1070 {
1071 	kfree(file->private_data);
1072 
1073 	return 0;
1074 }
1075 
ath12k_read_vdev_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1076 static ssize_t ath12k_read_vdev_stats(struct file *file,
1077 				      char __user *user_buf,
1078 				      size_t count, loff_t *ppos)
1079 {
1080 	const char *buf = file->private_data;
1081 	size_t len = strlen(buf);
1082 
1083 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1084 }
1085 
1086 static const struct file_operations fops_vdev_stats = {
1087 	.open = ath12k_open_vdev_stats,
1088 	.release = ath12k_release_vdev_stats,
1089 	.read = ath12k_read_vdev_stats,
1090 	.owner = THIS_MODULE,
1091 	.llseek = default_llseek,
1092 };
1093 
ath12k_open_bcn_stats(struct inode * inode,struct file * file)1094 static int ath12k_open_bcn_stats(struct inode *inode, struct file *file)
1095 {
1096 	struct ath12k *ar = inode->i_private;
1097 	struct ath12k_link_vif *arvif;
1098 	struct ath12k_fw_stats_req_params param;
1099 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1100 	int ret;
1101 
1102 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1103 
1104 	if (ah && ah->state != ATH12K_HW_STATE_ON)
1105 		return -ENETDOWN;
1106 
1107 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1108 	if (!buf)
1109 		return -ENOMEM;
1110 
1111 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1112 	param.stats_id = WMI_REQUEST_BCN_STAT;
1113 
1114 	/* loop all active VDEVs for bcn stats */
1115 	list_for_each_entry(arvif, &ar->arvifs, list) {
1116 		if (!arvif->is_up)
1117 			continue;
1118 
1119 		param.vdev_id = arvif->vdev_id;
1120 		ret = ath12k_debugfs_fw_stats_request(ar, &param);
1121 		if (ret) {
1122 			ath12k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
1123 			return ret;
1124 		}
1125 	}
1126 
1127 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1128 				 buf);
1129 	/* since beacon stats request is looped for all active VDEVs, saved fw
1130 	 * stats is not freed for each request until done for all active VDEVs
1131 	 */
1132 	spin_lock_bh(&ar->data_lock);
1133 	ath12k_fw_stats_bcn_free(&ar->fw_stats.bcn);
1134 	spin_unlock_bh(&ar->data_lock);
1135 
1136 	file->private_data = no_free_ptr(buf);
1137 
1138 	return 0;
1139 }
1140 
ath12k_release_bcn_stats(struct inode * inode,struct file * file)1141 static int ath12k_release_bcn_stats(struct inode *inode, struct file *file)
1142 {
1143 	kfree(file->private_data);
1144 
1145 	return 0;
1146 }
1147 
ath12k_read_bcn_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1148 static ssize_t ath12k_read_bcn_stats(struct file *file,
1149 				     char __user *user_buf,
1150 				     size_t count, loff_t *ppos)
1151 {
1152 	const char *buf = file->private_data;
1153 	size_t len = strlen(buf);
1154 
1155 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1156 }
1157 
1158 static const struct file_operations fops_bcn_stats = {
1159 	.open = ath12k_open_bcn_stats,
1160 	.release = ath12k_release_bcn_stats,
1161 	.read = ath12k_read_bcn_stats,
1162 	.owner = THIS_MODULE,
1163 	.llseek = default_llseek,
1164 };
1165 
ath12k_open_pdev_stats(struct inode * inode,struct file * file)1166 static int ath12k_open_pdev_stats(struct inode *inode, struct file *file)
1167 {
1168 	struct ath12k *ar = inode->i_private;
1169 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1170 	struct ath12k_base *ab = ar->ab;
1171 	struct ath12k_fw_stats_req_params param;
1172 	int ret;
1173 
1174 	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1175 
1176 	if (ah && ah->state != ATH12K_HW_STATE_ON)
1177 		return -ENETDOWN;
1178 
1179 	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1180 	if (!buf)
1181 		return -ENOMEM;
1182 
1183 	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1184 	param.vdev_id = 0;
1185 	param.stats_id = WMI_REQUEST_PDEV_STAT;
1186 
1187 	ret = ath12k_debugfs_fw_stats_request(ar, &param);
1188 	if (ret) {
1189 		ath12k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
1190 		return ret;
1191 	}
1192 
1193 	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1194 				 buf);
1195 
1196 	file->private_data = no_free_ptr(buf);
1197 
1198 	return 0;
1199 }
1200 
ath12k_release_pdev_stats(struct inode * inode,struct file * file)1201 static int ath12k_release_pdev_stats(struct inode *inode, struct file *file)
1202 {
1203 	kfree(file->private_data);
1204 
1205 	return 0;
1206 }
1207 
ath12k_read_pdev_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1208 static ssize_t ath12k_read_pdev_stats(struct file *file,
1209 				      char __user *user_buf,
1210 				      size_t count, loff_t *ppos)
1211 {
1212 	const char *buf = file->private_data;
1213 	size_t len = strlen(buf);
1214 
1215 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1216 }
1217 
1218 static const struct file_operations fops_pdev_stats = {
1219 	.open = ath12k_open_pdev_stats,
1220 	.release = ath12k_release_pdev_stats,
1221 	.read = ath12k_read_pdev_stats,
1222 	.owner = THIS_MODULE,
1223 	.llseek = default_llseek,
1224 };
1225 
1226 static
ath12k_debugfs_fw_stats_register(struct ath12k * ar)1227 void ath12k_debugfs_fw_stats_register(struct ath12k *ar)
1228 {
1229 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1230 							ar->debug.debugfs_pdev);
1231 
1232 	/* all stats debugfs files created are under "fw_stats" directory
1233 	 * created per PDEV
1234 	 */
1235 	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1236 			    &fops_vdev_stats);
1237 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1238 			    &fops_bcn_stats);
1239 	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1240 			    &fops_pdev_stats);
1241 
1242 	INIT_LIST_HEAD(&ar->fw_stats.vdevs);
1243 	INIT_LIST_HEAD(&ar->fw_stats.bcn);
1244 	INIT_LIST_HEAD(&ar->fw_stats.pdevs);
1245 
1246 	init_completion(&ar->fw_stats_complete);
1247 }
1248 
ath12k_debugfs_register(struct ath12k * ar)1249 void ath12k_debugfs_register(struct ath12k *ar)
1250 {
1251 	struct ath12k_base *ab = ar->ab;
1252 	struct ieee80211_hw *hw = ar->ah->hw;
1253 	char pdev_name[5];
1254 	char buf[100] = {0};
1255 
1256 	scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1257 
1258 	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1259 
1260 	/* Create a symlink under ieee80211/phy* */
1261 	scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev);
1262 	ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k",
1263 								hw->wiphy->debugfsdir,
1264 								buf);
1265 
1266 	if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) {
1267 		debugfs_create_file("dfs_simulate_radar", 0200,
1268 				    ar->debug.debugfs_pdev, ar,
1269 				    &fops_simulate_radar);
1270 	}
1271 
1272 	debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_pdev, ar,
1273 			    &fops_tpc_stats);
1274 	debugfs_create_file("tpc_stats_type", 0200, ar->debug.debugfs_pdev,
1275 			    ar, &fops_tpc_stats_type);
1276 	init_completion(&ar->debug.tpc_complete);
1277 
1278 	ath12k_debugfs_htt_stats_register(ar);
1279 	ath12k_debugfs_fw_stats_register(ar);
1280 
1281 	debugfs_create_file("ext_rx_stats", 0644,
1282 			    ar->debug.debugfs_pdev, ar,
1283 			    &fops_extd_rx_stats);
1284 }
1285 
ath12k_debugfs_unregister(struct ath12k * ar)1286 void ath12k_debugfs_unregister(struct ath12k *ar)
1287 {
1288 	if (!ar->debug.debugfs_pdev)
1289 		return;
1290 
1291 	/* Remove symlink under ieee80211/phy* */
1292 	debugfs_remove(ar->debug.debugfs_pdev_symlink);
1293 	debugfs_remove_recursive(ar->debug.debugfs_pdev);
1294 	ar->debug.debugfs_pdev_symlink = NULL;
1295 	ar->debug.debugfs_pdev = NULL;
1296 }
1297