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