1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/vmalloc.h>
8 #include "core.h"
9 #include "debug.h"
10 #include "debugfs_htt_stats.h"
11 #include "dp_tx.h"
12 #include "dp_rx.h"
13 
14 static u32
print_array_to_buf_index(u8 * buf,u32 offset,const char * header,u32 stats_index,const __le32 * array,u32 array_len,const char * footer)15 print_array_to_buf_index(u8 *buf, u32 offset, const char *header, u32 stats_index,
16 			 const __le32 *array, u32 array_len, const char *footer)
17 {
18 	int index = 0;
19 	u8 i;
20 
21 	if (header) {
22 		index += scnprintf(buf + offset,
23 				   ATH12K_HTT_STATS_BUF_SIZE - offset,
24 				   "%s = ", header);
25 	}
26 	for (i = 0; i < array_len; i++) {
27 		index += scnprintf(buf + offset + index,
28 				   (ATH12K_HTT_STATS_BUF_SIZE - offset) - index,
29 				   " %u:%u,", stats_index++, le32_to_cpu(array[i]));
30 	}
31 	/* To overwrite the last trailing comma */
32 	index--;
33 	*(buf + offset + index) = '\0';
34 
35 	if (footer) {
36 		index += scnprintf(buf + offset + index,
37 				   (ATH12K_HTT_STATS_BUF_SIZE - offset) - index,
38 				   "%s", footer);
39 	}
40 	return index;
41 }
42 
43 static u32
print_array_to_buf(u8 * buf,u32 offset,const char * header,const __le32 * array,u32 array_len,const char * footer)44 print_array_to_buf(u8 *buf, u32 offset, const char *header,
45 		   const __le32 *array, u32 array_len, const char *footer)
46 {
47 	return print_array_to_buf_index(buf, offset, header, 0, array, array_len,
48 					footer);
49 }
50 
ath12k_htt_ax_tx_rx_ru_size_to_str(u8 ru_size)51 static const char *ath12k_htt_ax_tx_rx_ru_size_to_str(u8 ru_size)
52 {
53 	switch (ru_size) {
54 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_26:
55 		return "26";
56 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_52:
57 		return "52";
58 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_106:
59 		return "106";
60 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_242:
61 		return "242";
62 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_484:
63 		return "484";
64 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_996:
65 		return "996";
66 	case ATH12K_HTT_TX_RX_PDEV_STATS_AX_RU_SIZE_996x2:
67 		return "996x2";
68 	default:
69 		return "unknown";
70 	}
71 }
72 
ath12k_htt_be_tx_rx_ru_size_to_str(u8 ru_size)73 static const char *ath12k_htt_be_tx_rx_ru_size_to_str(u8 ru_size)
74 {
75 	switch (ru_size) {
76 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_26:
77 		return "26";
78 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_52:
79 		return "52";
80 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_52_26:
81 		return "52+26";
82 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_106:
83 		return "106";
84 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_106_26:
85 		return "106+26";
86 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_242:
87 		return "242";
88 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_484:
89 		return "484";
90 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_484_242:
91 		return "484+242";
92 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996:
93 		return "996";
94 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996_484:
95 		return "996+484";
96 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996_484_242:
97 		return "996+484+242";
98 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x2:
99 		return "996x2";
100 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x2_484:
101 		return "996x2+484";
102 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x3:
103 		return "996x3";
104 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x3_484:
105 		return "996x3+484";
106 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x4:
107 		return "996x4";
108 	default:
109 		return "unknown";
110 	}
111 }
112 
113 static const char*
ath12k_tx_ru_size_to_str(enum ath12k_htt_stats_ru_type ru_type,u8 ru_size)114 ath12k_tx_ru_size_to_str(enum ath12k_htt_stats_ru_type ru_type, u8 ru_size)
115 {
116 	if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
117 		return ath12k_htt_ax_tx_rx_ru_size_to_str(ru_size);
118 	else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
119 		return ath12k_htt_be_tx_rx_ru_size_to_str(ru_size);
120 	else
121 		return "unknown";
122 }
123 
124 static void
htt_print_tx_pdev_stats_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)125 htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
126 				struct debug_htt_stats_req *stats_req)
127 {
128 	const struct ath12k_htt_tx_pdev_stats_cmn_tlv *htt_stats_buf = tag_buf;
129 	u8 *buf = stats_req->buf;
130 	u32 len = stats_req->buf_len;
131 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
132 	u32 mac_id_word;
133 
134 	if (tag_len < sizeof(*htt_stats_buf))
135 		return;
136 
137 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
138 
139 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n");
140 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
141 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
142 	len += scnprintf(buf + len, buf_len - len, "comp_delivered = %u\n",
143 			 le32_to_cpu(htt_stats_buf->comp_delivered));
144 	len += scnprintf(buf + len, buf_len - len, "self_triggers = %u\n",
145 			 le32_to_cpu(htt_stats_buf->self_triggers));
146 	len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
147 			 le32_to_cpu(htt_stats_buf->hw_queued));
148 	len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
149 			 le32_to_cpu(htt_stats_buf->hw_reaped));
150 	len += scnprintf(buf + len, buf_len - len, "underrun = %u\n",
151 			 le32_to_cpu(htt_stats_buf->underrun));
152 	len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n",
153 			 le32_to_cpu(htt_stats_buf->hw_paused));
154 	len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n",
155 			 le32_to_cpu(htt_stats_buf->hw_flush));
156 	len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n",
157 			 le32_to_cpu(htt_stats_buf->hw_filt));
158 	len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
159 			 le32_to_cpu(htt_stats_buf->tx_abort));
160 	len += scnprintf(buf + len, buf_len - len, "ppdu_ok = %u\n",
161 			 le32_to_cpu(htt_stats_buf->ppdu_ok));
162 	len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n",
163 			 le32_to_cpu(htt_stats_buf->mpdu_requed));
164 	len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n",
165 			 le32_to_cpu(htt_stats_buf->tx_xretry));
166 	len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n",
167 			 le32_to_cpu(htt_stats_buf->data_rc));
168 	len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n",
169 			 le32_to_cpu(htt_stats_buf->mpdu_dropped_xretry));
170 	len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n",
171 			 le32_to_cpu(htt_stats_buf->illgl_rate_phy_err));
172 	len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n",
173 			 le32_to_cpu(htt_stats_buf->cont_xretry));
174 	len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n",
175 			 le32_to_cpu(htt_stats_buf->tx_timeout));
176 	len += scnprintf(buf + len, buf_len - len, "tx_time_dur_data = %u\n",
177 			 le32_to_cpu(htt_stats_buf->tx_time_dur_data));
178 	len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n",
179 			 le32_to_cpu(htt_stats_buf->pdev_resets));
180 	len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n",
181 			 le32_to_cpu(htt_stats_buf->phy_underrun));
182 	len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n",
183 			 le32_to_cpu(htt_stats_buf->txop_ovf));
184 	len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n",
185 			 le32_to_cpu(htt_stats_buf->seq_posted));
186 	len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n",
187 			 le32_to_cpu(htt_stats_buf->seq_failed_queueing));
188 	len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n",
189 			 le32_to_cpu(htt_stats_buf->seq_completed));
190 	len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n",
191 			 le32_to_cpu(htt_stats_buf->seq_restarted));
192 	len += scnprintf(buf + len, buf_len - len, "seq_txop_repost_stop = %u\n",
193 			 le32_to_cpu(htt_stats_buf->seq_txop_repost_stop));
194 	len += scnprintf(buf + len, buf_len - len, "next_seq_cancel = %u\n",
195 			 le32_to_cpu(htt_stats_buf->next_seq_cancel));
196 	len += scnprintf(buf + len, buf_len - len, "dl_mu_mimo_seq_posted = %u\n",
197 			 le32_to_cpu(htt_stats_buf->mu_seq_posted));
198 	len += scnprintf(buf + len, buf_len - len, "dl_mu_ofdma_seq_posted = %u\n",
199 			 le32_to_cpu(htt_stats_buf->mu_ofdma_seq_posted));
200 	len += scnprintf(buf + len, buf_len - len, "ul_mu_mimo_seq_posted = %u\n",
201 			 le32_to_cpu(htt_stats_buf->ul_mumimo_seq_posted));
202 	len += scnprintf(buf + len, buf_len - len, "ul_mu_ofdma_seq_posted = %u\n",
203 			 le32_to_cpu(htt_stats_buf->ul_ofdma_seq_posted));
204 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_peer_blacklisted = %u\n",
205 			 le32_to_cpu(htt_stats_buf->num_mu_peer_blacklisted));
206 	len += scnprintf(buf + len, buf_len - len, "seq_qdepth_repost_stop = %u\n",
207 			 le32_to_cpu(htt_stats_buf->seq_qdepth_repost_stop));
208 	len += scnprintf(buf + len, buf_len - len, "seq_min_msdu_repost_stop = %u\n",
209 			 le32_to_cpu(htt_stats_buf->seq_min_msdu_repost_stop));
210 	len += scnprintf(buf + len, buf_len - len, "mu_seq_min_msdu_repost_stop = %u\n",
211 			 le32_to_cpu(htt_stats_buf->mu_seq_min_msdu_repost_stop));
212 	len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n",
213 			 le32_to_cpu(htt_stats_buf->seq_switch_hw_paused));
214 	len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n",
215 			 le32_to_cpu(htt_stats_buf->next_seq_posted_dsr));
216 	len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n",
217 			 le32_to_cpu(htt_stats_buf->seq_posted_isr));
218 	len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n",
219 			 le32_to_cpu(htt_stats_buf->seq_ctrl_cached));
220 	len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n",
221 			 le32_to_cpu(htt_stats_buf->mpdu_count_tqm));
222 	len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n",
223 			 le32_to_cpu(htt_stats_buf->msdu_count_tqm));
224 	len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n",
225 			 le32_to_cpu(htt_stats_buf->mpdu_removed_tqm));
226 	len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n",
227 			 le32_to_cpu(htt_stats_buf->msdu_removed_tqm));
228 	len += scnprintf(buf + len, buf_len - len, "remove_mpdus_max_retries = %u\n",
229 			 le32_to_cpu(htt_stats_buf->remove_mpdus_max_retries));
230 	len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n",
231 			 le32_to_cpu(htt_stats_buf->mpdus_sw_flush));
232 	len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
233 			 le32_to_cpu(htt_stats_buf->mpdus_hw_filter));
234 	len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n",
235 			 le32_to_cpu(htt_stats_buf->mpdus_truncated));
236 	len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n",
237 			 le32_to_cpu(htt_stats_buf->mpdus_ack_failed));
238 	len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n",
239 			 le32_to_cpu(htt_stats_buf->mpdus_expired));
240 	len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n",
241 			 le32_to_cpu(htt_stats_buf->mpdus_seq_hw_retry));
242 	len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
243 			 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
244 	len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n",
245 			 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt_valid));
246 	len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n",
247 			 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt));
248 	len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n",
249 			 le32_to_cpu(htt_stats_buf->num_total_ppdus_tried_ota));
250 	len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n",
251 			 le32_to_cpu(htt_stats_buf->num_data_ppdus_tried_ota));
252 	len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n",
253 			 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_enqued));
254 	len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n",
255 			 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_freed));
256 	len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n",
257 			 le32_to_cpu(htt_stats_buf->local_data_enqued));
258 	len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n",
259 			 le32_to_cpu(htt_stats_buf->local_data_freed));
260 	len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n",
261 			 le32_to_cpu(htt_stats_buf->mpdu_tried));
262 	len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n",
263 			 le32_to_cpu(htt_stats_buf->isr_wait_seq_posted));
264 	len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n",
265 			 le32_to_cpu(htt_stats_buf->tx_active_dur_us_low));
266 	len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n",
267 			 le32_to_cpu(htt_stats_buf->tx_active_dur_us_high));
268 	len += scnprintf(buf + len, buf_len - len, "fes_offsets_err_cnt = %u\n\n",
269 			 le32_to_cpu(htt_stats_buf->fes_offsets_err_cnt));
270 
271 	stats_req->buf_len = len;
272 }
273 
274 static void
htt_print_tx_pdev_stats_urrn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)275 htt_print_tx_pdev_stats_urrn_tlv(const void *tag_buf,
276 				 u16 tag_len,
277 				 struct debug_htt_stats_req *stats_req)
278 {
279 	const struct ath12k_htt_tx_pdev_stats_urrn_tlv *htt_stats_buf = tag_buf;
280 	u8 *buf = stats_req->buf;
281 	u32 len = stats_req->buf_len;
282 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
283 	u16 num_elems = min_t(u16, (tag_len >> 2),
284 			      HTT_TX_PDEV_MAX_URRN_STATS);
285 
286 	len += scnprintf(buf + len, buf_len - len,
287 			"HTT_TX_PDEV_STATS_URRN_TLV:\n");
288 
289 	len += print_array_to_buf(buf, len, "urrn_stats", htt_stats_buf->urrn_stats,
290 				  num_elems, "\n\n");
291 
292 	stats_req->buf_len = len;
293 }
294 
295 static void
htt_print_tx_pdev_stats_flush_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)296 htt_print_tx_pdev_stats_flush_tlv(const void *tag_buf,
297 				  u16 tag_len,
298 				  struct debug_htt_stats_req *stats_req)
299 {
300 	const struct ath12k_htt_tx_pdev_stats_flush_tlv *htt_stats_buf = tag_buf;
301 	u8 *buf = stats_req->buf;
302 	u32 len = stats_req->buf_len;
303 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
304 	u16 num_elems = min_t(u16, (tag_len >> 2),
305 			      ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS);
306 
307 	len += scnprintf(buf + len, buf_len - len,
308 			 "HTT_TX_PDEV_STATS_FLUSH_TLV:\n");
309 
310 	len += print_array_to_buf(buf, len, "flush_errs", htt_stats_buf->flush_errs,
311 				  num_elems, "\n\n");
312 
313 	stats_req->buf_len = len;
314 }
315 
316 static void
htt_print_tx_pdev_stats_sifs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)317 htt_print_tx_pdev_stats_sifs_tlv(const void *tag_buf,
318 				 u16 tag_len,
319 				 struct debug_htt_stats_req *stats_req)
320 {
321 	const struct ath12k_htt_tx_pdev_stats_sifs_tlv *htt_stats_buf = tag_buf;
322 	u8 *buf = stats_req->buf;
323 	u32 len = stats_req->buf_len;
324 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
325 	u16 num_elems = min_t(u16, (tag_len >> 2),
326 			      ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS);
327 
328 	len += scnprintf(buf + len, buf_len - len,
329 			 "HTT_TX_PDEV_STATS_SIFS_TLV:\n");
330 
331 	len += print_array_to_buf(buf, len, "sifs_status", htt_stats_buf->sifs_status,
332 				  num_elems, "\n\n");
333 
334 	stats_req->buf_len = len;
335 }
336 
337 static void
htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)338 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void *tag_buf, u16 tag_len,
339 					 struct debug_htt_stats_req *stats_req)
340 {
341 	const struct ath12k_htt_tx_pdev_mu_ppdu_dist_stats_tlv *htt_stats_buf = tag_buf;
342 	char *mode;
343 	u8 j, hw_mode, i, str_buf_len;
344 	u8 *buf = stats_req->buf;
345 	u32 len = stats_req->buf_len;
346 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
347 	u32 stats_value;
348 	u8 max_ppdu = ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST;
349 	u8 max_sched = ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS;
350 	char str_buf[ATH12K_HTT_MAX_STRING_LEN];
351 
352 	if (tag_len < sizeof(*htt_stats_buf))
353 		return;
354 
355 	hw_mode = le32_to_cpu(htt_stats_buf->hw_mode);
356 
357 	switch (hw_mode) {
358 	case ATH12K_HTT_STATS_HWMODE_AC:
359 		len += scnprintf(buf + len, buf_len - len,
360 				 "HTT_TX_PDEV_AC_MU_PPDU_DISTRIBUTION_STATS:\n");
361 		mode = "ac";
362 		break;
363 	case ATH12K_HTT_STATS_HWMODE_AX:
364 		len += scnprintf(buf + len, buf_len - len,
365 				 "HTT_TX_PDEV_AX_MU_PPDU_DISTRIBUTION_STATS:\n");
366 		mode = "ax";
367 		break;
368 	case ATH12K_HTT_STATS_HWMODE_BE:
369 		len += scnprintf(buf + len, buf_len - len,
370 				 "HTT_TX_PDEV_BE_MU_PPDU_DISTRIBUTION_STATS:\n");
371 		mode = "be";
372 		break;
373 	default:
374 		return;
375 	}
376 
377 	for (i = 0; i < ATH12K_HTT_STATS_NUM_NR_BINS ; i++) {
378 		len += scnprintf(buf + len, buf_len - len,
379 				 "%s_mu_mimo_num_seq_posted_nr%u = %u\n", mode,
380 				 ((i + 1) * 4), htt_stats_buf->num_seq_posted[i]);
381 		str_buf_len = 0;
382 		memset(str_buf, 0x0, sizeof(str_buf));
383 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
384 			stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_posted_per_burst
385 						  [i * max_ppdu + j]);
386 			str_buf_len += scnprintf(&str_buf[str_buf_len],
387 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
388 						" %u:%u,", j, stats_value);
389 		}
390 		/* To overwrite the last trailing comma */
391 		str_buf[str_buf_len - 1] = '\0';
392 		len += scnprintf(buf + len, buf_len - len,
393 				 "%s_mu_mimo_num_ppdu_posted_per_burst_nr%u = %s\n",
394 				 mode, ((i + 1) * 4), str_buf);
395 		str_buf_len = 0;
396 		memset(str_buf, 0x0, sizeof(str_buf));
397 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
398 			stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_cmpl_per_burst
399 						  [i * max_ppdu + j]);
400 			str_buf_len += scnprintf(&str_buf[str_buf_len],
401 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
402 						" %u:%u,", j, stats_value);
403 		}
404 		/* To overwrite the last trailing comma */
405 		str_buf[str_buf_len - 1] = '\0';
406 		len += scnprintf(buf + len, buf_len - len,
407 				 "%s_mu_mimo_num_ppdu_completed_per_burst_nr%u = %s\n",
408 				 mode, ((i + 1) * 4), str_buf);
409 		str_buf_len = 0;
410 		memset(str_buf, 0x0, sizeof(str_buf));
411 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS ; j++) {
412 			stats_value = le32_to_cpu(htt_stats_buf->num_seq_term_status
413 						  [i * max_sched + j]);
414 			str_buf_len += scnprintf(&str_buf[str_buf_len],
415 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
416 						" %u:%u,", j, stats_value);
417 		}
418 		/* To overwrite the last trailing comma */
419 		str_buf[str_buf_len - 1] = '\0';
420 		len += scnprintf(buf + len, buf_len - len,
421 				 "%s_mu_mimo_num_seq_term_status_nr%u = %s\n\n",
422 				 mode, ((i + 1) * 4), str_buf);
423 	}
424 
425 	stats_req->buf_len = len;
426 }
427 
428 static void
htt_print_tx_pdev_stats_sifs_hist_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)429 htt_print_tx_pdev_stats_sifs_hist_tlv(const void *tag_buf,
430 				      u16 tag_len,
431 				      struct debug_htt_stats_req *stats_req)
432 {
433 	const struct ath12k_htt_tx_pdev_stats_sifs_hist_tlv *htt_stats_buf = tag_buf;
434 	u8 *buf = stats_req->buf;
435 	u32 len = stats_req->buf_len;
436 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
437 	u16 num_elems = min_t(u16, (tag_len >> 2),
438 			      ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS);
439 
440 	len += scnprintf(buf + len, buf_len - len,
441 			 "HTT_TX_PDEV_STATS_SIFS_HIST_TLV:\n");
442 
443 	len += print_array_to_buf(buf, len, "sifs_hist_status",
444 				  htt_stats_buf->sifs_hist_status, num_elems, "\n\n");
445 
446 	stats_req->buf_len = len;
447 }
448 
449 static void
htt_print_pdev_ctrl_path_tx_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)450 htt_print_pdev_ctrl_path_tx_stats_tlv(const void *tag_buf, u16 tag_len,
451 				      struct debug_htt_stats_req *stats_req)
452 {
453 	const struct ath12k_htt_pdev_ctrl_path_tx_stats_tlv *htt_stats_buf = tag_buf;
454 	u8 *buf = stats_req->buf;
455 	u32 len = stats_req->buf_len;
456 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
457 
458 	if (len < sizeof(*htt_stats_buf))
459 		return;
460 
461 	len += scnprintf(buf + len, buf_len - len,
462 			 "HTT_TX_PDEV_STATS_CTRL_PATH_TX_STATS:\n");
463 	len += print_array_to_buf(buf, len, "fw_tx_mgmt_subtype",
464 				 htt_stats_buf->fw_tx_mgmt_subtype,
465 				 ATH12K_HTT_STATS_SUBTYPE_MAX, "\n\n");
466 
467 	stats_req->buf_len = len;
468 }
469 
470 static void
ath12k_htt_print_stats_tx_sched_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)471 ath12k_htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf,
472 					u16 tag_len,
473 					struct debug_htt_stats_req *stats_req)
474 {
475 	const struct ath12k_htt_stats_tx_sched_cmn_tlv *htt_stats_buf = tag_buf;
476 	u8 *buf = stats_req->buf;
477 	u32 len = stats_req->buf_len;
478 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
479 	u32 mac_id_word;
480 
481 	if (tag_len < sizeof(*htt_stats_buf))
482 		return;
483 
484 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
485 
486 	len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n");
487 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
488 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
489 	len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n",
490 			 le32_to_cpu(htt_stats_buf->current_timestamp));
491 
492 	stats_req->buf_len = len;
493 }
494 
495 static void
ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)496 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf,
497 						 u16 tag_len,
498 						 struct debug_htt_stats_req *stats_req)
499 {
500 	const struct ath12k_htt_tx_pdev_stats_sched_per_txq_tlv *htt_stats_buf = tag_buf;
501 	u8 *buf = stats_req->buf;
502 	u32 len = stats_req->buf_len;
503 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
504 	u32 mac_id_word;
505 
506 	if (tag_len < sizeof(*htt_stats_buf))
507 		return;
508 
509 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
510 
511 	len += scnprintf(buf + len, buf_len - len,
512 			 "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n");
513 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
514 			u32_get_bits(mac_id_word,
515 				     ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID));
516 	len += scnprintf(buf + len, buf_len - len, "txq_id = %u\n",
517 			 u32_get_bits(mac_id_word,
518 				      ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID));
519 	len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n",
520 			 le32_to_cpu(htt_stats_buf->sched_policy));
521 	len += scnprintf(buf + len, buf_len - len,
522 			 "last_sched_cmd_posted_timestamp = %u\n",
523 			 le32_to_cpu(htt_stats_buf->last_sched_cmd_posted_timestamp));
524 	len += scnprintf(buf + len, buf_len - len,
525 			 "last_sched_cmd_compl_timestamp = %u\n",
526 			 le32_to_cpu(htt_stats_buf->last_sched_cmd_compl_timestamp));
527 	len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n",
528 			 le32_to_cpu(htt_stats_buf->sched_2_tac_lwm_count));
529 	len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n",
530 			 le32_to_cpu(htt_stats_buf->sched_2_tac_ring_full));
531 	len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n",
532 			 le32_to_cpu(htt_stats_buf->sched_cmd_post_failure));
533 	len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n",
534 			 le32_to_cpu(htt_stats_buf->num_active_tids));
535 	len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n",
536 			 le32_to_cpu(htt_stats_buf->num_ps_schedules));
537 	len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n",
538 			 le32_to_cpu(htt_stats_buf->sched_cmds_pending));
539 	len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n",
540 			 le32_to_cpu(htt_stats_buf->num_tid_register));
541 	len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n",
542 			 le32_to_cpu(htt_stats_buf->num_tid_unregister));
543 	len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n",
544 			 le32_to_cpu(htt_stats_buf->num_qstats_queried));
545 	len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n",
546 			 le32_to_cpu(htt_stats_buf->qstats_update_pending));
547 	len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n",
548 			 le32_to_cpu(htt_stats_buf->last_qstats_query_timestamp));
549 	len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n",
550 			 le32_to_cpu(htt_stats_buf->num_tqm_cmdq_full));
551 	len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n",
552 			 le32_to_cpu(htt_stats_buf->num_de_sched_algo_trigger));
553 	len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n",
554 			 le32_to_cpu(htt_stats_buf->num_rt_sched_algo_trigger));
555 	len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n",
556 			 le32_to_cpu(htt_stats_buf->num_tqm_sched_algo_trigger));
557 	len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n",
558 			 le32_to_cpu(htt_stats_buf->notify_sched));
559 	len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n",
560 			 le32_to_cpu(htt_stats_buf->dur_based_sendn_term));
561 	len += scnprintf(buf + len, buf_len - len, "su_notify2_sched = %u\n",
562 			 le32_to_cpu(htt_stats_buf->su_notify2_sched));
563 	len += scnprintf(buf + len, buf_len - len, "su_optimal_queued_msdus_sched = %u\n",
564 			 le32_to_cpu(htt_stats_buf->su_optimal_queued_msdus_sched));
565 	len += scnprintf(buf + len, buf_len - len, "su_delay_timeout_sched = %u\n",
566 			 le32_to_cpu(htt_stats_buf->su_delay_timeout_sched));
567 	len += scnprintf(buf + len, buf_len - len, "su_min_txtime_sched_delay = %u\n",
568 			 le32_to_cpu(htt_stats_buf->su_min_txtime_sched_delay));
569 	len += scnprintf(buf + len, buf_len - len, "su_no_delay = %u\n",
570 			 le32_to_cpu(htt_stats_buf->su_no_delay));
571 	len += scnprintf(buf + len, buf_len - len, "num_supercycles = %u\n",
572 			 le32_to_cpu(htt_stats_buf->num_supercycles));
573 	len += scnprintf(buf + len, buf_len - len, "num_subcycles_with_sort = %u\n",
574 			 le32_to_cpu(htt_stats_buf->num_subcycles_with_sort));
575 	len += scnprintf(buf + len, buf_len - len, "num_subcycles_no_sort = %u\n\n",
576 			 le32_to_cpu(htt_stats_buf->num_subcycles_no_sort));
577 
578 	stats_req->buf_len = len;
579 }
580 
581 static void
ath12k_htt_print_sched_txq_cmd_posted_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)582 ath12k_htt_print_sched_txq_cmd_posted_tlv(const void *tag_buf,
583 					  u16 tag_len,
584 					  struct debug_htt_stats_req *stats_req)
585 {
586 	const struct ath12k_htt_sched_txq_cmd_posted_tlv *htt_stats_buf = tag_buf;
587 	u8 *buf = stats_req->buf;
588 	u32 len = stats_req->buf_len;
589 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
590 	u16 num_elements = tag_len >> 2;
591 
592 	len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV:\n");
593 	len += print_array_to_buf(buf, len, "sched_cmd_posted",
594 				  htt_stats_buf->sched_cmd_posted, num_elements, "\n\n");
595 
596 	stats_req->buf_len = len;
597 }
598 
599 static void
ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)600 ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void *tag_buf,
601 					  u16 tag_len,
602 					  struct debug_htt_stats_req *stats_req)
603 {
604 	const struct ath12k_htt_sched_txq_cmd_reaped_tlv *htt_stats_buf = tag_buf;
605 	u8 *buf = stats_req->buf;
606 	u32 len = stats_req->buf_len;
607 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
608 	u16 num_elements = tag_len >> 2;
609 
610 	len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV:\n");
611 	len += print_array_to_buf(buf, len, "sched_cmd_reaped",
612 				  htt_stats_buf->sched_cmd_reaped, num_elements, "\n\n");
613 
614 	stats_req->buf_len = len;
615 }
616 
617 static void
ath12k_htt_print_sched_txq_sched_order_su_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)618 ath12k_htt_print_sched_txq_sched_order_su_tlv(const void *tag_buf,
619 					      u16 tag_len,
620 					      struct debug_htt_stats_req *stats_req)
621 {
622 	const struct ath12k_htt_sched_txq_sched_order_su_tlv *htt_stats_buf = tag_buf;
623 	u8 *buf = stats_req->buf;
624 	u32 len = stats_req->buf_len;
625 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
626 	u32 sched_order_su_num_entries = min_t(u32, (tag_len >> 2),
627 					       ATH12K_HTT_TX_PDEV_NUM_SCHED_ORDER_LOG);
628 
629 	len += scnprintf(buf + len, buf_len - len,
630 			 "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV:\n");
631 	len += print_array_to_buf(buf, len, "sched_order_su",
632 				  htt_stats_buf->sched_order_su,
633 				  sched_order_su_num_entries, "\n\n");
634 
635 	stats_req->buf_len = len;
636 }
637 
638 static void
ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)639 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void *tag_buf,
640 						   u16 tag_len,
641 						   struct debug_htt_stats_req *stats_req)
642 {
643 	const struct ath12k_htt_sched_txq_sched_ineligibility_tlv *htt_stats_buf =
644 		     tag_buf;
645 	u8 *buf = stats_req->buf;
646 	u32 len = stats_req->buf_len;
647 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
648 	u32 sched_ineligibility_num_entries = tag_len >> 2;
649 
650 	len += scnprintf(buf + len, buf_len - len,
651 			 "HTT_SCHED_TXQ_SCHED_INELIGIBILITY:\n");
652 	len += print_array_to_buf(buf, len, "sched_ineligibility",
653 				  htt_stats_buf->sched_ineligibility,
654 				  sched_ineligibility_num_entries, "\n\n");
655 
656 	stats_req->buf_len = len;
657 }
658 
659 static void
ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)660 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void *tag_buf,
661 						  u16 tag_len,
662 						  struct debug_htt_stats_req *stats_req)
663 {
664 	const struct ath12k_htt_sched_txq_supercycle_triggers_tlv *htt_stats_buf =
665 		     tag_buf;
666 	u8 *buf = stats_req->buf;
667 	u32 len = stats_req->buf_len;
668 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
669 	u16 num_elems = min_t(u16, (tag_len >> 2),
670 			      ATH12K_HTT_SCHED_SUPERCYCLE_TRIGGER_MAX);
671 
672 	len += scnprintf(buf + len, buf_len - len,
673 			 "HTT_SCHED_TXQ_SUPERCYCLE_TRIGGER:\n");
674 	len += print_array_to_buf(buf, len, "supercycle_triggers",
675 				  htt_stats_buf->supercycle_triggers, num_elems, "\n\n");
676 
677 	stats_req->buf_len = len;
678 }
679 
680 static void
ath12k_htt_print_hw_stats_pdev_errs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)681 ath12k_htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf, u16 tag_len,
682 					struct debug_htt_stats_req *stats_req)
683 {
684 	const struct ath12k_htt_hw_stats_pdev_errs_tlv *htt_buf = tag_buf;
685 	u8 *buf = stats_req->buf;
686 	u32 len = stats_req->buf_len;
687 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
688 	u32 mac_id_word;
689 
690 	if (tag_len < sizeof(*htt_buf))
691 		return;
692 
693 	mac_id_word = le32_to_cpu(htt_buf->mac_id__word);
694 
695 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n");
696 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
697 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
698 	len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
699 			 le32_to_cpu(htt_buf->tx_abort));
700 	len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n",
701 			 le32_to_cpu(htt_buf->tx_abort_fail_count));
702 	len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n",
703 			 le32_to_cpu(htt_buf->rx_abort));
704 	len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n",
705 			 le32_to_cpu(htt_buf->rx_abort_fail_count));
706 	len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n",
707 			 le32_to_cpu(htt_buf->rx_flush_cnt));
708 	len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n",
709 			 le32_to_cpu(htt_buf->warm_reset));
710 	len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n",
711 			 le32_to_cpu(htt_buf->cold_reset));
712 	len += scnprintf(buf + len, buf_len - len, "mac_cold_reset_restore_cal = %u\n",
713 			 le32_to_cpu(htt_buf->mac_cold_reset_restore_cal));
714 	len += scnprintf(buf + len, buf_len - len, "mac_cold_reset = %u\n",
715 			 le32_to_cpu(htt_buf->mac_cold_reset));
716 	len += scnprintf(buf + len, buf_len - len, "mac_warm_reset = %u\n",
717 			 le32_to_cpu(htt_buf->mac_warm_reset));
718 	len += scnprintf(buf + len, buf_len - len, "mac_only_reset = %u\n",
719 			 le32_to_cpu(htt_buf->mac_only_reset));
720 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset = %u\n",
721 			 le32_to_cpu(htt_buf->phy_warm_reset));
722 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_ucode_trig = %u\n",
723 			 le32_to_cpu(htt_buf->phy_warm_reset_ucode_trig));
724 	len += scnprintf(buf + len, buf_len - len, "mac_warm_reset_restore_cal = %u\n",
725 			 le32_to_cpu(htt_buf->mac_warm_reset_restore_cal));
726 	len += scnprintf(buf + len, buf_len - len, "mac_sfm_reset = %u\n",
727 			 le32_to_cpu(htt_buf->mac_sfm_reset));
728 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_m3_ssr = %u\n",
729 			 le32_to_cpu(htt_buf->phy_warm_reset_m3_ssr));
730 	len += scnprintf(buf + len, buf_len - len, "fw_rx_rings_reset = %u\n",
731 			 le32_to_cpu(htt_buf->fw_rx_rings_reset));
732 	len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n",
733 			 le32_to_cpu(htt_buf->tx_flush));
734 	len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n",
735 			 le32_to_cpu(htt_buf->tx_glb_reset));
736 	len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n",
737 			 le32_to_cpu(htt_buf->tx_txq_reset));
738 	len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n",
739 			 le32_to_cpu(htt_buf->rx_timeout_reset));
740 
741 	len += scnprintf(buf + len, buf_len - len, "PDEV_PHY_WARM_RESET_REASONS:\n");
742 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_reason_phy_m3 = %u\n",
743 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_phy_m3));
744 	len += scnprintf(buf + len, buf_len - len,
745 			 "phy_warm_reset_reason_tx_hw_stuck = %u\n",
746 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hw_stuck));
747 	len += scnprintf(buf + len, buf_len - len,
748 			 "phy_warm_reset_reason_num_cca_rx_frame_stuck = %u\n",
749 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_num_rx_frame_stuck));
750 	len += scnprintf(buf + len, buf_len - len,
751 			 "phy_warm_reset_reason_wal_rx_recovery_rst_rx_busy = %u\n",
752 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_rx_busy));
753 	len += scnprintf(buf + len, buf_len - len,
754 			 "phy_warm_reset_reason_wal_rx_recovery_rst_mac_hang = %u\n",
755 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_mac_hng));
756 	len += scnprintf(buf + len, buf_len - len,
757 			 "phy_warm_reset_reason_mac_reset_converted_phy_reset = %u\n",
758 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_mac_conv_phy_reset));
759 	len += scnprintf(buf + len, buf_len - len,
760 			 "phy_warm_reset_reason_tx_lifetime_expiry_cca_stuck = %u\n",
761 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_exp_cca_stuck));
762 	len += scnprintf(buf + len, buf_len - len,
763 			 "phy_warm_reset_reason_tx_consecutive_flush9_war = %u\n",
764 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_consec_flsh_war));
765 	len += scnprintf(buf + len, buf_len - len,
766 			 "phy_warm_reset_reason_tx_hwsch_reset_war = %u\n",
767 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hwsch_reset_war));
768 	len += scnprintf(buf + len, buf_len - len,
769 			 "phy_warm_reset_reason_hwsch_wdog_or_cca_wdog_war = %u\n\n",
770 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_hwsch_cca_wdog_war));
771 
772 	len += scnprintf(buf + len, buf_len - len, "WAL_RX_RECOVERY_STATS:\n");
773 	len += scnprintf(buf + len, buf_len - len,
774 			 "wal_rx_recovery_rst_mac_hang_count = %u\n",
775 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_mac_hang_cnt));
776 	len += scnprintf(buf + len, buf_len - len,
777 			 "wal_rx_recovery_rst_known_sig_count = %u\n",
778 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_known_sig_cnt));
779 	len += scnprintf(buf + len, buf_len - len,
780 			 "wal_rx_recovery_rst_no_rx_count = %u\n",
781 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_cnt));
782 	len += scnprintf(buf + len, buf_len - len,
783 			 "wal_rx_recovery_rst_no_rx_consecutive_count = %u\n",
784 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_consec_cnt));
785 	len += scnprintf(buf + len, buf_len - len,
786 			 "wal_rx_recovery_rst_rx_busy_count = %u\n",
787 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_rx_busy_cnt));
788 	len += scnprintf(buf + len, buf_len - len,
789 			 "wal_rx_recovery_rst_phy_mac_hang_count = %u\n\n",
790 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_phy_mac_hang_cnt));
791 
792 	len += scnprintf(buf + len, buf_len - len, "HTT_RX_DEST_DRAIN_STATS:\n");
793 	len += scnprintf(buf + len, buf_len - len,
794 			 "rx_dest_drain_rx_descs_leak_prevention_done = %u\n",
795 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_leak_prevented));
796 	len += scnprintf(buf + len, buf_len - len,
797 			 "rx_dest_drain_rx_descs_saved_cnt = %u\n",
798 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_saved_cnt));
799 	len += scnprintf(buf + len, buf_len - len,
800 			 "rx_dest_drain_rxdma2reo_leak_detected = %u\n",
801 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2reo_leak_detected));
802 	len += scnprintf(buf + len, buf_len - len,
803 			 "rx_dest_drain_rxdma2fw_leak_detected = %u\n",
804 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2fw_leak_detected));
805 	len += scnprintf(buf + len, buf_len - len,
806 			 "rx_dest_drain_rxdma2wbm_leak_detected = %u\n",
807 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2wbm_leak_detected));
808 	len += scnprintf(buf + len, buf_len - len,
809 			 "rx_dest_drain_rxdma1_2sw_leak_detected = %u\n",
810 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma1_2sw_leak_detected));
811 	len += scnprintf(buf + len, buf_len - len,
812 			 "rx_dest_drain_rx_drain_ok_mac_idle = %u\n",
813 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_drain_ok_mac_idle));
814 	len += scnprintf(buf + len, buf_len - len,
815 			 "rx_dest_drain_ok_mac_not_idle = %u\n",
816 			 le32_to_cpu(htt_buf->rx_dest_drain_ok_mac_not_idle));
817 	len += scnprintf(buf + len, buf_len - len,
818 			 "rx_dest_drain_prerequisite_invld = %u\n",
819 			 le32_to_cpu(htt_buf->rx_dest_drain_prerequisite_invld));
820 	len += scnprintf(buf + len, buf_len - len,
821 			 "rx_dest_drain_skip_for_non_lmac_reset = %u\n",
822 			 le32_to_cpu(htt_buf->rx_dest_drain_skip_non_lmac_reset));
823 	len += scnprintf(buf + len, buf_len - len,
824 			 "rx_dest_drain_hw_fifo_not_empty_post_drain_wait = %u\n\n",
825 			 le32_to_cpu(htt_buf->rx_dest_drain_hw_fifo_notempty_post_wait));
826 
827 	stats_req->buf_len = len;
828 }
829 
830 static void
ath12k_htt_print_hw_stats_intr_misc_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)831 ath12k_htt_print_hw_stats_intr_misc_tlv(const void *tag_buf, u16 tag_len,
832 					struct debug_htt_stats_req *stats_req)
833 {
834 	const struct ath12k_htt_hw_stats_intr_misc_tlv *htt_stats_buf = tag_buf;
835 	u8 *buf = stats_req->buf;
836 	u32 len = stats_req->buf_len;
837 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
838 
839 	if (tag_len < sizeof(*htt_stats_buf))
840 		return;
841 
842 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n");
843 	len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n",
844 			 htt_stats_buf->hw_intr_name);
845 	len += scnprintf(buf + len, buf_len - len, "mask = %u\n",
846 			 le32_to_cpu(htt_stats_buf->mask));
847 	len += scnprintf(buf + len, buf_len - len, "count = %u\n\n",
848 			 le32_to_cpu(htt_stats_buf->count));
849 
850 	stats_req->buf_len = len;
851 }
852 
853 static void
ath12k_htt_print_hw_stats_whal_tx_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)854 ath12k_htt_print_hw_stats_whal_tx_tlv(const void *tag_buf, u16 tag_len,
855 				      struct debug_htt_stats_req *stats_req)
856 {
857 	const struct ath12k_htt_hw_stats_whal_tx_tlv *htt_stats_buf = tag_buf;
858 	u8 *buf = stats_req->buf;
859 	u32 len = stats_req->buf_len;
860 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
861 	u32 mac_id_word;
862 
863 	if (tag_len < sizeof(*htt_stats_buf))
864 		return;
865 
866 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
867 
868 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n");
869 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
870 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
871 	len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n",
872 			 le32_to_cpu(htt_stats_buf->last_unpause_ppdu_id));
873 	len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n",
874 			 le32_to_cpu(htt_stats_buf->hwsch_unpause_wait_tqm_write));
875 	len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n",
876 			 le32_to_cpu(htt_stats_buf->hwsch_dummy_tlv_skipped));
877 	len += scnprintf(buf + len, buf_len - len,
878 			 "hwsch_misaligned_offset_received = %u\n",
879 			 le32_to_cpu(htt_stats_buf->hwsch_misaligned_offset_received));
880 	len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n",
881 			 le32_to_cpu(htt_stats_buf->hwsch_reset_count));
882 	len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n",
883 			 le32_to_cpu(htt_stats_buf->hwsch_dev_reset_war));
884 	len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n",
885 			 le32_to_cpu(htt_stats_buf->hwsch_delayed_pause));
886 	len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n",
887 			 le32_to_cpu(htt_stats_buf->hwsch_long_delayed_pause));
888 	len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n",
889 			 le32_to_cpu(htt_stats_buf->sch_rx_ppdu_no_response));
890 	len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n",
891 			 le32_to_cpu(htt_stats_buf->sch_selfgen_response));
892 	len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n",
893 			 le32_to_cpu(htt_stats_buf->sch_rx_sifs_resp_trigger));
894 
895 	stats_req->buf_len = len;
896 }
897 
898 static void
ath12k_htt_print_hw_war_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)899 ath12k_htt_print_hw_war_tlv(const void *tag_buf, u16 tag_len,
900 			    struct debug_htt_stats_req *stats_req)
901 {
902 	const struct ath12k_htt_hw_war_stats_tlv *htt_stats_buf = tag_buf;
903 	u8 *buf = stats_req->buf;
904 	u32 len = stats_req->buf_len;
905 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
906 	u16 fixed_len, array_len;
907 	u8 i, array_words;
908 	u32 mac_id;
909 
910 	if (tag_len < sizeof(*htt_stats_buf))
911 		return;
912 
913 	mac_id = __le32_to_cpu(htt_stats_buf->mac_id__word);
914 	fixed_len = sizeof(*htt_stats_buf);
915 	array_len = tag_len - fixed_len;
916 	array_words = array_len >> 2;
917 
918 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_WAR_STATS_TLV:\n");
919 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
920 			 u32_get_bits(mac_id, ATH12K_HTT_STATS_MAC_ID));
921 
922 	for (i = 0; i < array_words; i++) {
923 		len += scnprintf(buf + len, buf_len - len, "hw_war %u = %u\n\n",
924 				 i, le32_to_cpu(htt_stats_buf->hw_wars[i]));
925 	}
926 
927 	stats_req->buf_len = len;
928 }
929 
930 static void
ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)931 ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
932 				      struct debug_htt_stats_req *stats_req)
933 {
934 	const struct ath12k_htt_tx_tqm_cmn_stats_tlv *htt_stats_buf = tag_buf;
935 	u8 *buf = stats_req->buf;
936 	u32 len = stats_req->buf_len;
937 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
938 	u32 mac_id_word;
939 
940 	if (tag_len < sizeof(*htt_stats_buf))
941 		return;
942 
943 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
944 
945 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n");
946 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
947 			u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
948 	len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n",
949 			 le32_to_cpu(htt_stats_buf->max_cmdq_id));
950 	len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n",
951 			 le32_to_cpu(htt_stats_buf->list_mpdu_cnt_hist_intvl));
952 	len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n",
953 			 le32_to_cpu(htt_stats_buf->add_msdu));
954 	len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n",
955 			 le32_to_cpu(htt_stats_buf->q_empty));
956 	len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n",
957 			 le32_to_cpu(htt_stats_buf->q_not_empty));
958 	len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n",
959 			 le32_to_cpu(htt_stats_buf->drop_notification));
960 	len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n",
961 			 le32_to_cpu(htt_stats_buf->desc_threshold));
962 	len += scnprintf(buf + len, buf_len - len, "hwsch_tqm_invalid_status = %u\n",
963 			 le32_to_cpu(htt_stats_buf->hwsch_tqm_invalid_status));
964 	len += scnprintf(buf + len, buf_len - len, "missed_tqm_gen_mpdus = %u\n",
965 			 le32_to_cpu(htt_stats_buf->missed_tqm_gen_mpdus));
966 	len += scnprintf(buf + len, buf_len - len,
967 			 "total_msduq_timestamp_updates = %u\n",
968 			 le32_to_cpu(htt_stats_buf->msduq_timestamp_updates));
969 	len += scnprintf(buf + len, buf_len - len,
970 			 "total_msduq_timestamp_updates_by_get_mpdu_head_info_cmd = %u\n",
971 			 le32_to_cpu(htt_stats_buf->msduq_updates_mpdu_head_info_cmd));
972 	len += scnprintf(buf + len, buf_len - len,
973 			 "total_msduq_timestamp_updates_by_emp_to_nonemp_status = %u\n",
974 			 le32_to_cpu(htt_stats_buf->msduq_updates_emp_to_nonemp_status));
975 	len += scnprintf(buf + len, buf_len - len,
976 			 "total_get_mpdu_head_info_cmds_by_sched_algo_la_query = %u\n",
977 			 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_query));
978 	len += scnprintf(buf + len, buf_len - len,
979 			 "total_get_mpdu_head_info_cmds_by_tac = %u\n",
980 			 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_tac));
981 	len += scnprintf(buf + len, buf_len - len,
982 			 "total_gen_mpdu_cmds_by_sched_algo_la_query = %u\n",
983 			 le32_to_cpu(htt_stats_buf->gen_mpdu_cmds_by_query));
984 	len += scnprintf(buf + len, buf_len - len, "active_tqm_tids = %u\n",
985 			 le32_to_cpu(htt_stats_buf->tqm_active_tids));
986 	len += scnprintf(buf + len, buf_len - len, "inactive_tqm_tids = %u\n",
987 			 le32_to_cpu(htt_stats_buf->tqm_inactive_tids));
988 	len += scnprintf(buf + len, buf_len - len, "tqm_active_msduq_flows = %u\n",
989 			 le32_to_cpu(htt_stats_buf->tqm_active_msduq_flows));
990 	len += scnprintf(buf + len, buf_len - len, "hi_prio_q_not_empty = %u\n\n",
991 			 le32_to_cpu(htt_stats_buf->high_prio_q_not_empty));
992 
993 	stats_req->buf_len = len;
994 }
995 
996 static void
ath12k_htt_print_tx_tqm_error_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)997 ath12k_htt_print_tx_tqm_error_stats_tlv(const void *tag_buf, u16 tag_len,
998 					struct debug_htt_stats_req *stats_req)
999 {
1000 	const struct ath12k_htt_tx_tqm_error_stats_tlv *htt_stats_buf = tag_buf;
1001 	u8 *buf = stats_req->buf;
1002 	u32 len = stats_req->buf_len;
1003 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1004 
1005 	if (tag_len < sizeof(*htt_stats_buf))
1006 		return;
1007 
1008 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n");
1009 	len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n",
1010 			 le32_to_cpu(htt_stats_buf->q_empty_failure));
1011 	len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n",
1012 			 le32_to_cpu(htt_stats_buf->q_not_empty_failure));
1013 	len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n",
1014 			 le32_to_cpu(htt_stats_buf->add_msdu_failure));
1015 
1016 	len += scnprintf(buf + len, buf_len - len, "TQM_ERROR_RESET_STATS:\n");
1017 	len += scnprintf(buf + len, buf_len - len, "tqm_cache_ctl_err = %u\n",
1018 			 le32_to_cpu(htt_stats_buf->tqm_cache_ctl_err));
1019 	len += scnprintf(buf + len, buf_len - len, "tqm_soft_reset = %u\n",
1020 			 le32_to_cpu(htt_stats_buf->tqm_soft_reset));
1021 	len += scnprintf(buf + len, buf_len - len,
1022 			 "tqm_reset_total_num_in_use_link_descs = %u\n",
1023 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_link_descs));
1024 	len += scnprintf(buf + len, buf_len - len,
1025 			 "tqm_reset_worst_case_num_lost_link_descs = %u\n",
1026 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_link_descs));
1027 	len += scnprintf(buf + len, buf_len - len,
1028 			 "tqm_reset_worst_case_num_lost_host_tx_bufs_count = %u\n",
1029 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_host_tx_buf_cnt));
1030 	len += scnprintf(buf + len, buf_len - len,
1031 			 "tqm_reset_num_in_use_link_descs_internal_tqm = %u\n",
1032 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_internal_tqm));
1033 	len += scnprintf(buf + len, buf_len - len,
1034 			 "tqm_reset_num_in_use_link_descs_wbm_idle_link_ring = %u\n",
1035 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_idle_link_rng));
1036 	len += scnprintf(buf + len, buf_len - len,
1037 			 "tqm_reset_time_to_tqm_hang_delta_ms = %u\n",
1038 			 le32_to_cpu(htt_stats_buf->tqm_reset_time_to_tqm_hang_delta_ms));
1039 	len += scnprintf(buf + len, buf_len - len, "tqm_reset_recovery_time_ms = %u\n",
1040 			 le32_to_cpu(htt_stats_buf->tqm_reset_recovery_time_ms));
1041 	len += scnprintf(buf + len, buf_len - len, "tqm_reset_num_peers_hdl = %u\n",
1042 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_peers_hdl));
1043 	len += scnprintf(buf + len, buf_len - len,
1044 			 "tqm_reset_cumm_dirty_hw_mpduq_proc_cnt = %u\n",
1045 			 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_mpduq_cnt));
1046 	len += scnprintf(buf + len, buf_len - len,
1047 			 "tqm_reset_cumm_dirty_hw_msduq_proc = %u\n",
1048 			 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_msduq_proc));
1049 	len += scnprintf(buf + len, buf_len - len,
1050 			 "tqm_reset_flush_cache_cmd_su_cnt = %u\n",
1051 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_su_cnt));
1052 	len += scnprintf(buf + len, buf_len - len,
1053 			 "tqm_reset_flush_cache_cmd_other_cnt = %u\n",
1054 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_other_cnt));
1055 	len += scnprintf(buf + len, buf_len - len,
1056 			 "tqm_reset_flush_cache_cmd_trig_type = %u\n",
1057 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_type));
1058 	len += scnprintf(buf + len, buf_len - len,
1059 			 "tqm_reset_flush_cache_cmd_trig_cfg = %u\n",
1060 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_cfg));
1061 	len += scnprintf(buf + len, buf_len - len,
1062 			 "tqm_reset_flush_cache_cmd_skip_cmd_status_null = %u\n\n",
1063 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cmd_skp_status_null));
1064 
1065 	stats_req->buf_len = len;
1066 }
1067 
1068 static void
ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1069 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
1070 					   struct debug_htt_stats_req *stats_req)
1071 {
1072 	const struct ath12k_htt_tx_tqm_gen_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1073 	u8 *buf = stats_req->buf;
1074 	u32 len = stats_req->buf_len;
1075 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1076 	u16 num_elements = tag_len >> 2;
1077 
1078 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV:\n");
1079 	len += print_array_to_buf(buf, len, "gen_mpdu_end_reason",
1080 				  htt_stats_buf->gen_mpdu_end_reason, num_elements,
1081 				  "\n\n");
1082 
1083 	stats_req->buf_len = len;
1084 }
1085 
1086 static void
ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1087 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
1088 					    struct debug_htt_stats_req *stats_req)
1089 {
1090 	const struct ath12k_htt_tx_tqm_list_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1091 	u8 *buf = stats_req->buf;
1092 	u32 len = stats_req->buf_len;
1093 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1094 	u16 num_elems = min_t(u16, (tag_len >> 2),
1095 			      ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_END_REASON);
1096 
1097 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_STATS_TLV:\n");
1098 	len += print_array_to_buf(buf, len, "list_mpdu_end_reason",
1099 				  htt_stats_buf->list_mpdu_end_reason, num_elems, "\n\n");
1100 
1101 	stats_req->buf_len = len;
1102 }
1103 
1104 static void
ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1105 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void *tag_buf, u16 tag_len,
1106 					  struct debug_htt_stats_req *stats_req)
1107 {
1108 	const struct ath12k_htt_tx_tqm_list_mpdu_cnt_tlv *htt_stats_buf = tag_buf;
1109 	u8 *buf = stats_req->buf;
1110 	u32 len = stats_req->buf_len;
1111 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1112 	u16 num_elems = min_t(u16, (tag_len >> 2),
1113 			      ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS);
1114 
1115 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n");
1116 	len += print_array_to_buf(buf, len, "list_mpdu_cnt_hist",
1117 				  htt_stats_buf->list_mpdu_cnt_hist, num_elems, "\n\n");
1118 
1119 	stats_req->buf_len = len;
1120 }
1121 
1122 static void
ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1123 ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void *tag_buf, u16 tag_len,
1124 				       struct debug_htt_stats_req *stats_req)
1125 {
1126 	const struct ath12k_htt_tx_tqm_pdev_stats_tlv *htt_stats_buf = tag_buf;
1127 	u8 *buf = stats_req->buf;
1128 	u32 len = stats_req->buf_len;
1129 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1130 
1131 	if (tag_len < sizeof(*htt_stats_buf))
1132 		return;
1133 
1134 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n");
1135 	len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n",
1136 			 le32_to_cpu(htt_stats_buf->msdu_count));
1137 	len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n",
1138 			 le32_to_cpu(htt_stats_buf->mpdu_count));
1139 	len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n",
1140 			 le32_to_cpu(htt_stats_buf->remove_msdu));
1141 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n",
1142 			 le32_to_cpu(htt_stats_buf->remove_mpdu));
1143 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n",
1144 			 le32_to_cpu(htt_stats_buf->remove_msdu_ttl));
1145 	len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n",
1146 			 le32_to_cpu(htt_stats_buf->send_bar));
1147 	len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n",
1148 			 le32_to_cpu(htt_stats_buf->bar_sync));
1149 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n",
1150 			 le32_to_cpu(htt_stats_buf->notify_mpdu));
1151 	len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
1152 			 le32_to_cpu(htt_stats_buf->sync_cmd));
1153 	len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
1154 			 le32_to_cpu(htt_stats_buf->write_cmd));
1155 	len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n",
1156 			 le32_to_cpu(htt_stats_buf->hwsch_trigger));
1157 	len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
1158 			 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
1159 	len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n",
1160 			 le32_to_cpu(htt_stats_buf->gen_mpdu_cmd));
1161 	len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n",
1162 			 le32_to_cpu(htt_stats_buf->gen_list_cmd));
1163 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n",
1164 			 le32_to_cpu(htt_stats_buf->remove_mpdu_cmd));
1165 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n",
1166 			 le32_to_cpu(htt_stats_buf->remove_mpdu_tried_cmd));
1167 	len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n",
1168 			 le32_to_cpu(htt_stats_buf->mpdu_queue_stats_cmd));
1169 	len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n",
1170 			 le32_to_cpu(htt_stats_buf->mpdu_head_info_cmd));
1171 	len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n",
1172 			 le32_to_cpu(htt_stats_buf->msdu_flow_stats_cmd));
1173 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n",
1174 			 le32_to_cpu(htt_stats_buf->remove_msdu_cmd));
1175 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n",
1176 			 le32_to_cpu(htt_stats_buf->remove_msdu_ttl_cmd));
1177 	len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n",
1178 			 le32_to_cpu(htt_stats_buf->flush_cache_cmd));
1179 	len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n",
1180 			 le32_to_cpu(htt_stats_buf->update_mpduq_cmd));
1181 	len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n",
1182 			 le32_to_cpu(htt_stats_buf->enqueue));
1183 	len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n",
1184 			 le32_to_cpu(htt_stats_buf->enqueue_notify));
1185 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n",
1186 			 le32_to_cpu(htt_stats_buf->notify_mpdu_at_head));
1187 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n",
1188 			 le32_to_cpu(htt_stats_buf->notify_mpdu_state_valid));
1189 	len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n",
1190 			 le32_to_cpu(htt_stats_buf->sched_udp_notify1));
1191 	len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n",
1192 			 le32_to_cpu(htt_stats_buf->sched_udp_notify2));
1193 	len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n",
1194 			 le32_to_cpu(htt_stats_buf->sched_nonudp_notify1));
1195 	len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n",
1196 			 le32_to_cpu(htt_stats_buf->sched_nonudp_notify2));
1197 
1198 	stats_req->buf_len = len;
1199 }
1200 
1201 static void
ath12k_htt_print_tx_de_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1202 ath12k_htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
1203 				     struct debug_htt_stats_req *stats_req)
1204 {
1205 	const struct ath12k_htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf;
1206 	u8 *buf = stats_req->buf;
1207 	u32 len = stats_req->buf_len;
1208 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1209 	u32 mac_id_word;
1210 
1211 	if (tag_len < sizeof(*htt_stats_buf))
1212 		return;
1213 
1214 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
1215 
1216 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
1217 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
1218 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
1219 	len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
1220 			 le32_to_cpu(htt_stats_buf->tcl2fw_entry_count));
1221 	len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
1222 			 le32_to_cpu(htt_stats_buf->not_to_fw));
1223 	len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n",
1224 			 le32_to_cpu(htt_stats_buf->invalid_pdev_vdev_peer));
1225 	len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n",
1226 			 le32_to_cpu(htt_stats_buf->tcl_res_invalid_addrx));
1227 	len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n",
1228 			 le32_to_cpu(htt_stats_buf->wbm2fw_entry_count));
1229 	len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n",
1230 			 le32_to_cpu(htt_stats_buf->invalid_pdev));
1231 	len += scnprintf(buf + len, buf_len - len, "tcl_res_addrx_timeout = %u\n",
1232 			 le32_to_cpu(htt_stats_buf->tcl_res_addrx_timeout));
1233 	len += scnprintf(buf + len, buf_len - len, "invalid_vdev = %u\n",
1234 			 le32_to_cpu(htt_stats_buf->invalid_vdev));
1235 	len += scnprintf(buf + len, buf_len - len, "invalid_tcl_exp_frame_desc = %u\n",
1236 			 le32_to_cpu(htt_stats_buf->invalid_tcl_exp_frame_desc));
1237 	len += scnprintf(buf + len, buf_len - len, "vdev_id_mismatch_count = %u\n\n",
1238 			 le32_to_cpu(htt_stats_buf->vdev_id_mismatch_cnt));
1239 
1240 	stats_req->buf_len = len;
1241 }
1242 
1243 static void
ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1244 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1245 					       struct debug_htt_stats_req *stats_req)
1246 {
1247 	const struct ath12k_htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf;
1248 	u8 *buf = stats_req->buf;
1249 	u32 len = stats_req->buf_len;
1250 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1251 
1252 	if (tag_len < sizeof(*htt_stats_buf))
1253 		return;
1254 
1255 	len += scnprintf(buf + len, buf_len - len,
1256 			 "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n");
1257 	len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n",
1258 			 le32_to_cpu(htt_stats_buf->m1_packets));
1259 	len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n",
1260 			 le32_to_cpu(htt_stats_buf->m2_packets));
1261 	len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n",
1262 			 le32_to_cpu(htt_stats_buf->m3_packets));
1263 	len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n",
1264 			 le32_to_cpu(htt_stats_buf->m4_packets));
1265 	len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n",
1266 			 le32_to_cpu(htt_stats_buf->g1_packets));
1267 	len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n",
1268 			 le32_to_cpu(htt_stats_buf->g2_packets));
1269 	len += scnprintf(buf + len, buf_len - len, "rc4_packets = %u\n",
1270 			 le32_to_cpu(htt_stats_buf->rc4_packets));
1271 	len += scnprintf(buf + len, buf_len - len, "eap_packets = %u\n",
1272 			 le32_to_cpu(htt_stats_buf->eap_packets));
1273 	len += scnprintf(buf + len, buf_len - len, "eapol_start_packets = %u\n",
1274 			 le32_to_cpu(htt_stats_buf->eapol_start_packets));
1275 	len += scnprintf(buf + len, buf_len - len, "eapol_logoff_packets = %u\n",
1276 			 le32_to_cpu(htt_stats_buf->eapol_logoff_packets));
1277 	len += scnprintf(buf + len, buf_len - len, "eapol_encap_asf_packets = %u\n\n",
1278 			 le32_to_cpu(htt_stats_buf->eapol_encap_asf_packets));
1279 
1280 	stats_req->buf_len = len;
1281 }
1282 
1283 static void
ath12k_htt_print_tx_de_classify_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1284 ath12k_htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u16 tag_len,
1285 					  struct debug_htt_stats_req *stats_req)
1286 {
1287 	const struct ath12k_htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf;
1288 	u8 *buf = stats_req->buf;
1289 	u32 len = stats_req->buf_len;
1290 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1291 
1292 	if (tag_len < sizeof(*htt_stats_buf))
1293 		return;
1294 
1295 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n");
1296 	len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n",
1297 			 le32_to_cpu(htt_stats_buf->arp_packets));
1298 	len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n",
1299 			 le32_to_cpu(htt_stats_buf->igmp_packets));
1300 	len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n",
1301 			 le32_to_cpu(htt_stats_buf->dhcp_packets));
1302 	len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n",
1303 			 le32_to_cpu(htt_stats_buf->host_inspected));
1304 	len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n",
1305 			 le32_to_cpu(htt_stats_buf->htt_included));
1306 	len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n",
1307 			 le32_to_cpu(htt_stats_buf->htt_valid_mcs));
1308 	len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n",
1309 			 le32_to_cpu(htt_stats_buf->htt_valid_nss));
1310 	len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n",
1311 			 le32_to_cpu(htt_stats_buf->htt_valid_preamble_type));
1312 	len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n",
1313 			 le32_to_cpu(htt_stats_buf->htt_valid_chainmask));
1314 	len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n",
1315 			 le32_to_cpu(htt_stats_buf->htt_valid_guard_interval));
1316 	len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n",
1317 			 le32_to_cpu(htt_stats_buf->htt_valid_retries));
1318 	len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n",
1319 			 le32_to_cpu(htt_stats_buf->htt_valid_bw_info));
1320 	len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n",
1321 			 le32_to_cpu(htt_stats_buf->htt_valid_power));
1322 	len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n",
1323 			 le32_to_cpu(htt_stats_buf->htt_valid_key_flags));
1324 	len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n",
1325 			 le32_to_cpu(htt_stats_buf->htt_valid_no_encryption));
1326 	len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n",
1327 			 le32_to_cpu(htt_stats_buf->fse_entry_count));
1328 	len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n",
1329 			 le32_to_cpu(htt_stats_buf->fse_priority_be));
1330 	len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n",
1331 			 le32_to_cpu(htt_stats_buf->fse_priority_high));
1332 	len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n",
1333 			 le32_to_cpu(htt_stats_buf->fse_priority_low));
1334 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n",
1335 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_be));
1336 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n",
1337 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_over_sub));
1338 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n",
1339 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_bursty));
1340 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n",
1341 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_interactive));
1342 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n",
1343 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_periodic));
1344 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n",
1345 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_alloc));
1346 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n",
1347 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_created));
1348 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n",
1349 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_send_to_host));
1350 	len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n",
1351 			 le32_to_cpu(htt_stats_buf->mcast_entry));
1352 	len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n",
1353 			 le32_to_cpu(htt_stats_buf->bcast_entry));
1354 	len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n",
1355 			 le32_to_cpu(htt_stats_buf->htt_update_peer_cache));
1356 	len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n",
1357 			 le32_to_cpu(htt_stats_buf->htt_learning_frame));
1358 	len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n",
1359 			 le32_to_cpu(htt_stats_buf->fse_invalid_peer));
1360 	len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n",
1361 			 le32_to_cpu(htt_stats_buf->mec_notify));
1362 
1363 	stats_req->buf_len = len;
1364 }
1365 
1366 static void
ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1367 ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u16 tag_len,
1368 						 struct debug_htt_stats_req *stats_req)
1369 {
1370 	const struct ath12k_htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf;
1371 	u8 *buf = stats_req->buf;
1372 	u32 len = stats_req->buf_len;
1373 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1374 
1375 	if (tag_len < sizeof(*htt_stats_buf))
1376 		return;
1377 
1378 	len += scnprintf(buf + len, buf_len - len,
1379 			 "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n");
1380 	len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n",
1381 			 le32_to_cpu(htt_stats_buf->ap_bss_peer_not_found));
1382 	len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n",
1383 			 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_no_peer));
1384 	len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n",
1385 			 le32_to_cpu(htt_stats_buf->sta_delete_in_progress));
1386 	len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n",
1387 			 le32_to_cpu(htt_stats_buf->ibss_no_bss_peer));
1388 	len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n",
1389 			 le32_to_cpu(htt_stats_buf->invalid_vdev_type));
1390 	len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n",
1391 			 le32_to_cpu(htt_stats_buf->invalid_ast_peer_entry));
1392 	len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n",
1393 			 le32_to_cpu(htt_stats_buf->peer_entry_invalid));
1394 	len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n",
1395 			 le32_to_cpu(htt_stats_buf->ethertype_not_ip));
1396 	len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n",
1397 			 le32_to_cpu(htt_stats_buf->eapol_lookup_failed));
1398 	len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n",
1399 			 le32_to_cpu(htt_stats_buf->qpeer_not_allow_data));
1400 	len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n",
1401 			 le32_to_cpu(htt_stats_buf->fse_tid_override));
1402 	len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n",
1403 			 le32_to_cpu(htt_stats_buf->ipv6_jumbogram_zero_length));
1404 	len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n",
1405 			 le32_to_cpu(htt_stats_buf->qos_to_non_qos_in_prog));
1406 	len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_eapol = %u\n",
1407 			 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_eapol));
1408 	len += scnprintf(buf + len, buf_len - len, "unicast_on_ap_bss_peer = %u\n",
1409 			 le32_to_cpu(htt_stats_buf->unicast_on_ap_bss_peer));
1410 	len += scnprintf(buf + len, buf_len - len, "ap_vdev_invalid = %u\n",
1411 			 le32_to_cpu(htt_stats_buf->ap_vdev_invalid));
1412 	len += scnprintf(buf + len, buf_len - len, "incomplete_llc = %u\n",
1413 			 le32_to_cpu(htt_stats_buf->incomplete_llc));
1414 	len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m3 = %u\n",
1415 			 le32_to_cpu(htt_stats_buf->eapol_duplicate_m3));
1416 	len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m4 = %u\n\n",
1417 			 le32_to_cpu(htt_stats_buf->eapol_duplicate_m4));
1418 
1419 	stats_req->buf_len = len;
1420 }
1421 
1422 static void
ath12k_htt_print_tx_de_classify_status_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1423 ath12k_htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u16 tag_len,
1424 						 struct debug_htt_stats_req *stats_req)
1425 {
1426 	const struct ath12k_htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf;
1427 	u8 *buf = stats_req->buf;
1428 	u32 len = stats_req->buf_len;
1429 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1430 
1431 	if (tag_len < sizeof(*htt_stats_buf))
1432 		return;
1433 
1434 	len += scnprintf(buf + len, buf_len - len,
1435 			 "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n");
1436 	len += scnprintf(buf + len, buf_len - len, "eok = %u\n",
1437 			 le32_to_cpu(htt_stats_buf->eok));
1438 	len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n",
1439 			 le32_to_cpu(htt_stats_buf->classify_done));
1440 	len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n",
1441 			 le32_to_cpu(htt_stats_buf->lookup_failed));
1442 	len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n",
1443 			 le32_to_cpu(htt_stats_buf->send_host_dhcp));
1444 	len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n",
1445 			 le32_to_cpu(htt_stats_buf->send_host_mcast));
1446 	len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n",
1447 			 le32_to_cpu(htt_stats_buf->send_host_unknown_dest));
1448 	len += scnprintf(buf + len, buf_len - len, "send_host = %u\n",
1449 			 le32_to_cpu(htt_stats_buf->send_host));
1450 	len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n",
1451 			 le32_to_cpu(htt_stats_buf->status_invalid));
1452 
1453 	stats_req->buf_len = len;
1454 }
1455 
1456 static void
ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1457 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1458 						 struct debug_htt_stats_req *stats_req)
1459 {
1460 	const struct ath12k_htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf;
1461 	u8 *buf = stats_req->buf;
1462 	u32 len = stats_req->buf_len;
1463 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1464 
1465 	if (tag_len < sizeof(*htt_stats_buf))
1466 		return;
1467 
1468 	len += scnprintf(buf + len, buf_len - len,
1469 			 "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n");
1470 	len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n",
1471 			 le32_to_cpu(htt_stats_buf->enqueued_pkts));
1472 	len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n",
1473 			 le32_to_cpu(htt_stats_buf->to_tqm));
1474 	len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n",
1475 			 le32_to_cpu(htt_stats_buf->to_tqm_bypass));
1476 
1477 	stats_req->buf_len = len;
1478 }
1479 
1480 static void
ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1481 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u16 tag_len,
1482 						 struct debug_htt_stats_req *stats_req)
1483 {
1484 	const struct ath12k_htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf;
1485 	u8 *buf = stats_req->buf;
1486 	u32 len = stats_req->buf_len;
1487 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1488 
1489 	if (tag_len < sizeof(*htt_stats_buf))
1490 		return;
1491 
1492 	len += scnprintf(buf + len, buf_len - len,
1493 			 "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n");
1494 	len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n",
1495 			 le32_to_cpu(htt_stats_buf->discarded_pkts));
1496 	len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n",
1497 			 le32_to_cpu(htt_stats_buf->local_frames));
1498 	len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n",
1499 			 le32_to_cpu(htt_stats_buf->is_ext_msdu));
1500 
1501 	stats_req->buf_len = len;
1502 }
1503 
1504 static void
ath12k_htt_print_tx_de_compl_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1505 ath12k_htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u16 tag_len,
1506 				       struct debug_htt_stats_req *stats_req)
1507 {
1508 	const struct ath12k_htt_tx_de_compl_stats_tlv *htt_stats_buf = tag_buf;
1509 	u8 *buf = stats_req->buf;
1510 	u32 len = stats_req->buf_len;
1511 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1512 
1513 	if (tag_len < sizeof(*htt_stats_buf))
1514 		return;
1515 
1516 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n");
1517 	len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n",
1518 			 le32_to_cpu(htt_stats_buf->tcl_dummy_frame));
1519 	len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n",
1520 			 le32_to_cpu(htt_stats_buf->tqm_dummy_frame));
1521 	len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n",
1522 			 le32_to_cpu(htt_stats_buf->tqm_notify_frame));
1523 	len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n",
1524 			 le32_to_cpu(htt_stats_buf->fw2wbm_enq));
1525 	len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n",
1526 			 le32_to_cpu(htt_stats_buf->tqm_bypass_frame));
1527 
1528 	stats_req->buf_len = len;
1529 }
1530 
1531 static void
ath12k_htt_print_tx_selfgen_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1532 ath12k_htt_print_tx_selfgen_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
1533 					  struct debug_htt_stats_req *stats_req)
1534 {
1535 	const struct ath12k_htt_tx_selfgen_cmn_stats_tlv *htt_stats_buf = tag_buf;
1536 	u8 *buf = stats_req->buf;
1537 	u32 len = stats_req->buf_len;
1538 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1539 	u32 mac_id_word;
1540 
1541 	if (tag_len < sizeof(*htt_stats_buf))
1542 		return;
1543 
1544 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
1545 
1546 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:\n");
1547 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
1548 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
1549 	len += scnprintf(buf + len, buf_len - len, "su_bar = %u\n",
1550 			 le32_to_cpu(htt_stats_buf->su_bar));
1551 	len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
1552 			 le32_to_cpu(htt_stats_buf->rts));
1553 	len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
1554 			 le32_to_cpu(htt_stats_buf->cts2self));
1555 	len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
1556 			 le32_to_cpu(htt_stats_buf->qos_null));
1557 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_1 = %u\n",
1558 			 le32_to_cpu(htt_stats_buf->delayed_bar_1));
1559 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_2 = %u\n",
1560 			 le32_to_cpu(htt_stats_buf->delayed_bar_2));
1561 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_3 = %u\n",
1562 			 le32_to_cpu(htt_stats_buf->delayed_bar_3));
1563 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_4 = %u\n",
1564 			 le32_to_cpu(htt_stats_buf->delayed_bar_4));
1565 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_5 = %u\n",
1566 			 le32_to_cpu(htt_stats_buf->delayed_bar_5));
1567 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_6 = %u\n",
1568 			 le32_to_cpu(htt_stats_buf->delayed_bar_6));
1569 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_7 = %u\n\n",
1570 			 le32_to_cpu(htt_stats_buf->delayed_bar_7));
1571 
1572 	stats_req->buf_len = len;
1573 }
1574 
1575 static void
ath12k_htt_print_tx_selfgen_ac_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1576 ath12k_htt_print_tx_selfgen_ac_stats_tlv(const void *tag_buf, u16 tag_len,
1577 					 struct debug_htt_stats_req *stats_req)
1578 {
1579 	const struct ath12k_htt_tx_selfgen_ac_stats_tlv *htt_stats_buf = tag_buf;
1580 	u8 *buf = stats_req->buf;
1581 	u32 len = stats_req->buf_len;
1582 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1583 
1584 	if (tag_len < sizeof(*htt_stats_buf))
1585 		return;
1586 
1587 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_STATS_TLV:\n");
1588 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_tried = %u\n",
1589 			 le32_to_cpu(htt_stats_buf->ac_su_ndpa));
1590 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_tried = %u\n",
1591 			 le32_to_cpu(htt_stats_buf->ac_su_ndp));
1592 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_tried = %u\n",
1593 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndpa));
1594 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_tried = %u\n",
1595 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp));
1596 	len += print_array_to_buf_index(buf, len, "ac_mu_mimo_brpollX_tried = ", 1,
1597 					htt_stats_buf->ac_mu_mimo_brpoll,
1598 					ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS - 1,
1599 					"\n\n");
1600 
1601 	stats_req->buf_len = len;
1602 }
1603 
1604 static void
ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1605 ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, u16 tag_len,
1606 					 struct debug_htt_stats_req *stats_req)
1607 {
1608 	const struct ath12k_htt_tx_selfgen_ax_stats_tlv *htt_stats_buf = tag_buf;
1609 	u8 *buf = stats_req->buf;
1610 	u32 len = stats_req->buf_len;
1611 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1612 
1613 	if (tag_len < sizeof(*htt_stats_buf))
1614 		return;
1615 
1616 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:\n");
1617 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_tried = %u\n",
1618 			 le32_to_cpu(htt_stats_buf->ax_su_ndpa));
1619 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_tried = %u\n",
1620 			 le32_to_cpu(htt_stats_buf->ax_su_ndp));
1621 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_tried = %u\n",
1622 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa));
1623 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_tried = %u\n",
1624 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp));
1625 	len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpollX_tried = ", 1,
1626 					htt_stats_buf->ax_mu_mimo_brpoll,
1627 					ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1, "\n");
1628 	len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n",
1629 			 le32_to_cpu(htt_stats_buf->ax_basic_trigger));
1630 	len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger = %u\n",
1631 			 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger));
1632 	len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n",
1633 			 le32_to_cpu(htt_stats_buf->ax_bsr_trigger));
1634 	len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n",
1635 			 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger));
1636 	len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n\n",
1637 			 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger));
1638 
1639 	stats_req->buf_len = len;
1640 }
1641 
1642 static void
ath12k_htt_print_tx_selfgen_be_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1643 ath12k_htt_print_tx_selfgen_be_stats_tlv(const void *tag_buf, u16 tag_len,
1644 					 struct debug_htt_stats_req *stats_req)
1645 {
1646 	const struct ath12k_htt_tx_selfgen_be_stats_tlv *htt_stats_buf = tag_buf;
1647 	u8 *buf = stats_req->buf;
1648 	u32 len = stats_req->buf_len;
1649 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1650 
1651 	if (tag_len < sizeof(*htt_stats_buf))
1652 		return;
1653 
1654 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_STATS_TLV:\n");
1655 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_queued = %u\n",
1656 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_queued));
1657 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_tried = %u\n",
1658 			 le32_to_cpu(htt_stats_buf->be_su_ndpa));
1659 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_queued = %u\n",
1660 			 le32_to_cpu(htt_stats_buf->be_su_ndp_queued));
1661 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_tried = %u\n",
1662 			 le32_to_cpu(htt_stats_buf->be_su_ndp));
1663 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_queued = %u\n",
1664 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_queued));
1665 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_tried = %u\n",
1666 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa));
1667 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_queued = %u\n",
1668 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_queued));
1669 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_tried = %u\n",
1670 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp));
1671 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_queued = ", 1,
1672 					htt_stats_buf->be_mu_mimo_brpoll_queued,
1673 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1674 					"\n");
1675 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_tried = ", 1,
1676 					htt_stats_buf->be_mu_mimo_brpoll,
1677 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1678 					"\n");
1679 	len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger = ",
1680 				  htt_stats_buf->be_ul_mumimo_trigger,
1681 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1682 	len += scnprintf(buf + len, buf_len - len, "be_basic_trigger = %u\n",
1683 			 le32_to_cpu(htt_stats_buf->be_basic_trigger));
1684 	len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trigger = %u\n",
1685 			 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger));
1686 	len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger = %u\n",
1687 			 le32_to_cpu(htt_stats_buf->be_bsr_trigger));
1688 	len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger = %u\n",
1689 			 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger));
1690 	len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger = %u\n\n",
1691 			 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger));
1692 
1693 	stats_req->buf_len = len;
1694 }
1695 
1696 static void
ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1697 ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(const void *tag_buf, u16 tag_len,
1698 					     struct debug_htt_stats_req *stats_req)
1699 {
1700 	const struct ath12k_htt_tx_selfgen_ac_err_stats_tlv *htt_stats_buf = tag_buf;
1701 	u8 *buf = stats_req->buf;
1702 	u32 len = stats_req->buf_len;
1703 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1704 
1705 	if (tag_len < sizeof(*htt_stats_buf))
1706 		return;
1707 
1708 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:\n");
1709 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_err = %u\n",
1710 			 le32_to_cpu(htt_stats_buf->ac_su_ndp_err));
1711 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_err = %u\n",
1712 			 le32_to_cpu(htt_stats_buf->ac_su_ndpa_err));
1713 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u\n",
1714 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndpa_err));
1715 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u\n",
1716 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp_err));
1717 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u\n",
1718 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp1_err));
1719 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u\n",
1720 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp2_err));
1721 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n\n",
1722 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp3_err));
1723 
1724 	stats_req->buf_len = len;
1725 }
1726 
1727 static void
ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1728 ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf, u16 tag_len,
1729 					     struct debug_htt_stats_req *stats_req)
1730 {
1731 	const struct ath12k_htt_tx_selfgen_ax_err_stats_tlv *htt_stats_buf = tag_buf;
1732 	u8 *buf = stats_req->buf;
1733 	u32 len = stats_req->buf_len;
1734 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1735 
1736 	if (tag_len < sizeof(*htt_stats_buf))
1737 		return;
1738 
1739 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:\n");
1740 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_err = %u\n",
1741 			 le32_to_cpu(htt_stats_buf->ax_su_ndp_err));
1742 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_err = %u\n",
1743 			 le32_to_cpu(htt_stats_buf->ax_su_ndpa_err));
1744 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u\n",
1745 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa_err));
1746 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u\n",
1747 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp_err));
1748 	len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpX_err", 1,
1749 					htt_stats_buf->ax_mu_mimo_brp_err,
1750 					ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1,
1751 					"\n");
1752 	len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n",
1753 			 le32_to_cpu(htt_stats_buf->ax_basic_trigger_err));
1754 	len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger_err = %u\n",
1755 			 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger_err));
1756 	len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n",
1757 			 le32_to_cpu(htt_stats_buf->ax_bsr_trigger_err));
1758 	len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n",
1759 			 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger_err));
1760 	len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n\n",
1761 			 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger_err));
1762 
1763 	stats_req->buf_len = len;
1764 }
1765 
1766 static void
ath12k_htt_print_tx_selfgen_be_err_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1767 ath12k_htt_print_tx_selfgen_be_err_stats_tlv(const void *tag_buf, u16 tag_len,
1768 					     struct debug_htt_stats_req *stats_req)
1769 {
1770 	const struct ath12k_htt_tx_selfgen_be_err_stats_tlv *htt_stats_buf = tag_buf;
1771 	u8 *buf = stats_req->buf;
1772 	u32 len = stats_req->buf_len;
1773 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1774 
1775 	if (tag_len < sizeof(*htt_stats_buf))
1776 		return;
1777 
1778 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_ERR_STATS_TLV:\n");
1779 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_err = %u\n",
1780 			 le32_to_cpu(htt_stats_buf->be_su_ndp_err));
1781 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_flushed = %u\n",
1782 			 le32_to_cpu(htt_stats_buf->be_su_ndp_flushed));
1783 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_err = %u\n",
1784 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_err));
1785 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_flushed = %u\n",
1786 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_flushed));
1787 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_err = %u\n",
1788 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_err));
1789 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_flushed = %u\n",
1790 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_flushed));
1791 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_err = %u\n",
1792 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_err));
1793 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_flushed = %u\n",
1794 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_flushed));
1795 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpX_err", 1,
1796 					htt_stats_buf->be_mu_mimo_brp_err,
1797 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1798 					"\n");
1799 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_flushed", 1,
1800 					htt_stats_buf->be_mu_mimo_brpoll_flushed,
1801 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1802 					"\n");
1803 	len += print_array_to_buf(buf, len, "be_mu_mimo_num_cbf_rcvd_on_brp_err",
1804 				  htt_stats_buf->be_mu_mimo_brp_err_num_cbf_rxd,
1805 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1806 	len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger_err",
1807 				  htt_stats_buf->be_ul_mumimo_trigger_err,
1808 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1809 	len += scnprintf(buf + len, buf_len - len, "be_basic_trigger_err = %u\n",
1810 			 le32_to_cpu(htt_stats_buf->be_basic_trigger_err));
1811 	len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trig_err = %u\n",
1812 			 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger_err));
1813 	len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger_err = %u\n",
1814 			 le32_to_cpu(htt_stats_buf->be_bsr_trigger_err));
1815 	len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger_err = %u\n",
1816 			 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger_err));
1817 	len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger_err = %u\n\n",
1818 			 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger_err));
1819 
1820 	stats_req->buf_len = len;
1821 }
1822 
1823 static void
ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats)1824 ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1825 						      struct debug_htt_stats_req *stats)
1826 {
1827 	const struct ath12k_htt_tx_selfgen_ac_sched_status_stats_tlv *htt_stats_buf =
1828 		     tag_buf;
1829 	u8 *buf = stats->buf;
1830 	u32 len = stats->buf_len;
1831 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1832 
1833 	if (tag_len < sizeof(*htt_stats_buf))
1834 		return;
1835 
1836 	len += scnprintf(buf + len, buf_len - len,
1837 			 "HTT_TX_SELFGEN_AC_SCHED_STATUS_STATS_TLV:\n");
1838 	len += print_array_to_buf(buf, len, "ac_su_ndpa_sch_status",
1839 				  htt_stats_buf->ac_su_ndpa_sch_status,
1840 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1841 	len += print_array_to_buf(buf, len, "ac_su_ndp_sch_status",
1842 				  htt_stats_buf->ac_su_ndp_sch_status,
1843 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1844 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndpa_sch_status",
1845 				  htt_stats_buf->ac_mu_mimo_ndpa_sch_status,
1846 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1847 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_status",
1848 				  htt_stats_buf->ac_mu_mimo_ndp_sch_status,
1849 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1850 	len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_status",
1851 				  htt_stats_buf->ac_mu_mimo_brp_sch_status,
1852 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1853 	len += print_array_to_buf(buf, len, "ac_su_ndp_sch_flag_err",
1854 				  htt_stats_buf->ac_su_ndp_sch_flag_err,
1855 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1856 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_flag_err",
1857 				  htt_stats_buf->ac_mu_mimo_ndp_sch_flag_err,
1858 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1859 	len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_flag_err",
1860 				  htt_stats_buf->ac_mu_mimo_brp_sch_flag_err,
1861 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1862 
1863 	stats->buf_len = len;
1864 }
1865 
1866 static void
ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats)1867 ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1868 						      struct debug_htt_stats_req *stats)
1869 {
1870 	const struct ath12k_htt_tx_selfgen_ax_sched_status_stats_tlv *htt_stats_buf =
1871 		     tag_buf;
1872 	u8 *buf = stats->buf;
1873 	u32 len = stats->buf_len;
1874 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1875 
1876 	if (tag_len < sizeof(*htt_stats_buf))
1877 		return;
1878 
1879 	len += scnprintf(buf + len, buf_len - len,
1880 			 "HTT_TX_SELFGEN_AX_SCHED_STATUS_STATS_TLV:\n");
1881 	len += print_array_to_buf(buf, len, "ax_su_ndpa_sch_status",
1882 				  htt_stats_buf->ax_su_ndpa_sch_status,
1883 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1884 	len += print_array_to_buf(buf, len, "ax_su_ndp_sch_status",
1885 				  htt_stats_buf->ax_su_ndp_sch_status,
1886 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1887 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndpa_sch_status",
1888 				  htt_stats_buf->ax_mu_mimo_ndpa_sch_status,
1889 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1890 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_status",
1891 				  htt_stats_buf->ax_mu_mimo_ndp_sch_status,
1892 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1893 	len += print_array_to_buf(buf, len, "ax_mu_brp_sch_status",
1894 				  htt_stats_buf->ax_mu_brp_sch_status,
1895 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1896 	len += print_array_to_buf(buf, len, "ax_mu_bar_sch_status",
1897 				  htt_stats_buf->ax_mu_bar_sch_status,
1898 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1899 	len += print_array_to_buf(buf, len, "ax_basic_trig_sch_status",
1900 				  htt_stats_buf->ax_basic_trig_sch_status,
1901 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1902 	len += print_array_to_buf(buf, len, "ax_su_ndp_sch_flag_err",
1903 				  htt_stats_buf->ax_su_ndp_sch_flag_err,
1904 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1905 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_flag_err",
1906 				  htt_stats_buf->ax_mu_mimo_ndp_sch_flag_err,
1907 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1908 	len += print_array_to_buf(buf, len, "ax_mu_brp_sch_flag_err",
1909 				  htt_stats_buf->ax_mu_brp_sch_flag_err,
1910 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1911 	len += print_array_to_buf(buf, len, "ax_mu_bar_sch_flag_err",
1912 				  htt_stats_buf->ax_mu_bar_sch_flag_err,
1913 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1914 	len += print_array_to_buf(buf, len, "ax_basic_trig_sch_flag_err",
1915 				  htt_stats_buf->ax_basic_trig_sch_flag_err,
1916 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1917 	len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_status",
1918 				  htt_stats_buf->ax_ulmumimo_trig_sch_status,
1919 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1920 	len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_flag_err",
1921 				  htt_stats_buf->ax_ulmumimo_trig_sch_flag_err,
1922 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1923 
1924 	stats->buf_len = len;
1925 }
1926 
1927 static void
ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats)1928 ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1929 						      struct debug_htt_stats_req *stats)
1930 {
1931 	const struct ath12k_htt_tx_selfgen_be_sched_status_stats_tlv *htt_stats_buf =
1932 		     tag_buf;
1933 	u8 *buf = stats->buf;
1934 	u32 len = stats->buf_len;
1935 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1936 
1937 	if (tag_len < sizeof(*htt_stats_buf))
1938 		return;
1939 
1940 	len += scnprintf(buf + len, buf_len - len,
1941 			 "HTT_TX_SELFGEN_BE_SCHED_STATUS_STATS_TLV:\n");
1942 	len += print_array_to_buf(buf, len, "be_su_ndpa_sch_status",
1943 				  htt_stats_buf->be_su_ndpa_sch_status,
1944 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1945 	len += print_array_to_buf(buf, len, "be_su_ndp_sch_status",
1946 				  htt_stats_buf->be_su_ndp_sch_status,
1947 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1948 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndpa_sch_status",
1949 				  htt_stats_buf->be_mu_mimo_ndpa_sch_status,
1950 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1951 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_status",
1952 				  htt_stats_buf->be_mu_mimo_ndp_sch_status,
1953 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1954 	len += print_array_to_buf(buf, len, "be_mu_brp_sch_status",
1955 				  htt_stats_buf->be_mu_brp_sch_status,
1956 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1957 	len += print_array_to_buf(buf, len, "be_mu_bar_sch_status",
1958 				  htt_stats_buf->be_mu_bar_sch_status,
1959 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1960 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_status",
1961 				  htt_stats_buf->be_basic_trig_sch_status,
1962 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1963 	len += print_array_to_buf(buf, len, "be_su_ndp_sch_flag_err",
1964 				  htt_stats_buf->be_su_ndp_sch_flag_err,
1965 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1966 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_flag_err",
1967 				  htt_stats_buf->be_mu_mimo_ndp_sch_flag_err,
1968 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1969 	len += print_array_to_buf(buf, len, "be_mu_brp_sch_flag_err",
1970 				  htt_stats_buf->be_mu_brp_sch_flag_err,
1971 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1972 	len += print_array_to_buf(buf, len, "be_mu_bar_sch_flag_err",
1973 				  htt_stats_buf->be_mu_bar_sch_flag_err,
1974 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1975 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1976 				  htt_stats_buf->be_basic_trig_sch_flag_err,
1977 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1978 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1979 				  htt_stats_buf->be_basic_trig_sch_flag_err,
1980 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1981 	len += print_array_to_buf(buf, len, "be_ulmumimo_trig_sch_flag_err",
1982 				  htt_stats_buf->be_ulmumimo_trig_sch_flag_err,
1983 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1984 
1985 	stats->buf_len = len;
1986 }
1987 
1988 static void
ath12k_htt_print_stats_string_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1989 ath12k_htt_print_stats_string_tlv(const void *tag_buf, u16 tag_len,
1990 				  struct debug_htt_stats_req *stats_req)
1991 {
1992 	const struct ath12k_htt_stats_string_tlv *htt_stats_buf = tag_buf;
1993 	u8 *buf = stats_req->buf;
1994 	u32 len = stats_req->buf_len;
1995 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1996 	u8 i;
1997 	u16 index = 0;
1998 	u32 datum;
1999 	char data[ATH12K_HTT_MAX_STRING_LEN] = {0};
2000 
2001 	tag_len = tag_len >> 2;
2002 
2003 	len += scnprintf(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:\n");
2004 	for (i = 0; i < tag_len; i++) {
2005 		datum = __le32_to_cpu(htt_stats_buf->data[i]);
2006 		index += scnprintf(&data[index], ATH12K_HTT_MAX_STRING_LEN - index,
2007 				   "%.*s", 4, (char *)&datum);
2008 		if (index >= ATH12K_HTT_MAX_STRING_LEN)
2009 			break;
2010 	}
2011 	len += scnprintf(buf + len, buf_len - len, "data = %s\n\n", data);
2012 
2013 	stats_req->buf_len = len;
2014 }
2015 
2016 static void
ath12k_htt_print_sring_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2017 ath12k_htt_print_sring_stats_tlv(const void *tag_buf, u16 tag_len,
2018 				 struct debug_htt_stats_req *stats_req)
2019 {
2020 	const struct ath12k_htt_sring_stats_tlv *htt_stats_buf = tag_buf;
2021 	u8 *buf = stats_req->buf;
2022 	u32 len = stats_req->buf_len;
2023 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2024 	u32 mac_id_word;
2025 	u32 avail_words;
2026 	u32 head_tail_ptr;
2027 	u32 sring_stat;
2028 	u32 tail_ptr;
2029 
2030 	if (tag_len < sizeof(*htt_stats_buf))
2031 		return;
2032 
2033 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__ring_id__arena__ep);
2034 	avail_words = __le32_to_cpu(htt_stats_buf->num_avail_words__num_valid_words);
2035 	head_tail_ptr = __le32_to_cpu(htt_stats_buf->head_ptr__tail_ptr);
2036 	sring_stat = __le32_to_cpu(htt_stats_buf->consumer_empty__producer_full);
2037 	tail_ptr = __le32_to_cpu(htt_stats_buf->prefetch_count__internal_tail_ptr);
2038 
2039 	len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n");
2040 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2041 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_MAC_ID));
2042 	len += scnprintf(buf + len, buf_len - len, "ring_id = %u\n",
2043 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_RING_ID));
2044 	len += scnprintf(buf + len, buf_len - len, "arena = %u\n",
2045 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_ARENA));
2046 	len += scnprintf(buf + len, buf_len - len, "ep = %u\n",
2047 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_EP));
2048 	len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n",
2049 			 le32_to_cpu(htt_stats_buf->base_addr_lsb));
2050 	len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n",
2051 			 le32_to_cpu(htt_stats_buf->base_addr_msb));
2052 	len += scnprintf(buf + len, buf_len - len, "ring_size = %u\n",
2053 			 le32_to_cpu(htt_stats_buf->ring_size));
2054 	len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
2055 			 le32_to_cpu(htt_stats_buf->elem_size));
2056 	len += scnprintf(buf + len, buf_len - len, "num_avail_words = %u\n",
2057 			 u32_get_bits(avail_words,
2058 				      ATH12K_HTT_SRING_STATS_NUM_AVAIL_WORDS));
2059 	len += scnprintf(buf + len, buf_len - len, "num_valid_words = %u\n",
2060 			 u32_get_bits(avail_words,
2061 				      ATH12K_HTT_SRING_STATS_NUM_VALID_WORDS));
2062 	len += scnprintf(buf + len, buf_len - len, "head_ptr = %u\n",
2063 			 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_HEAD_PTR));
2064 	len += scnprintf(buf + len, buf_len - len, "tail_ptr = %u\n",
2065 			 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_TAIL_PTR));
2066 	len += scnprintf(buf + len, buf_len - len, "consumer_empty = %u\n",
2067 			 u32_get_bits(sring_stat,
2068 				      ATH12K_HTT_SRING_STATS_CONSUMER_EMPTY));
2069 	len += scnprintf(buf + len, buf_len - len, "producer_full = %u\n",
2070 			 u32_get_bits(head_tail_ptr,
2071 				      ATH12K_HTT_SRING_STATS_PRODUCER_FULL));
2072 	len += scnprintf(buf + len, buf_len - len, "prefetch_count = %u\n",
2073 			 u32_get_bits(tail_ptr, ATH12K_HTT_SRING_STATS_PREFETCH_COUNT));
2074 	len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %u\n\n",
2075 			 u32_get_bits(tail_ptr,
2076 				      ATH12K_HTT_SRING_STATS_INTERNAL_TAIL_PTR));
2077 
2078 	stats_req->buf_len = len;
2079 }
2080 
2081 static void
ath12k_htt_print_sfm_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2082 ath12k_htt_print_sfm_cmn_tlv(const void *tag_buf, u16 tag_len,
2083 			     struct debug_htt_stats_req *stats_req)
2084 {
2085 	const struct ath12k_htt_sfm_cmn_tlv *htt_stats_buf = tag_buf;
2086 	u8 *buf = stats_req->buf;
2087 	u32 len = stats_req->buf_len;
2088 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2089 	u32 mac_id_word;
2090 
2091 	if (tag_len < sizeof(*htt_stats_buf))
2092 		return;
2093 
2094 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
2095 
2096 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n");
2097 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2098 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2099 	len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n",
2100 			 le32_to_cpu(htt_stats_buf->buf_total));
2101 	len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n",
2102 			 le32_to_cpu(htt_stats_buf->mem_empty));
2103 	len += scnprintf(buf + len, buf_len - len, "deallocate_bufs = %u\n",
2104 			 le32_to_cpu(htt_stats_buf->deallocate_bufs));
2105 	len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2106 			 le32_to_cpu(htt_stats_buf->num_records));
2107 
2108 	stats_req->buf_len = len;
2109 }
2110 
2111 static void
ath12k_htt_print_sfm_client_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2112 ath12k_htt_print_sfm_client_tlv(const void *tag_buf, u16 tag_len,
2113 				struct debug_htt_stats_req *stats_req)
2114 {
2115 	const struct ath12k_htt_sfm_client_tlv *htt_stats_buf = tag_buf;
2116 	u8 *buf = stats_req->buf;
2117 	u32 len = stats_req->buf_len;
2118 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2119 
2120 	if (tag_len < sizeof(*htt_stats_buf))
2121 		return;
2122 
2123 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:\n");
2124 	len += scnprintf(buf + len, buf_len - len, "client_id = %u\n",
2125 			 le32_to_cpu(htt_stats_buf->client_id));
2126 	len += scnprintf(buf + len, buf_len - len, "buf_min = %u\n",
2127 			 le32_to_cpu(htt_stats_buf->buf_min));
2128 	len += scnprintf(buf + len, buf_len - len, "buf_max = %u\n",
2129 			 le32_to_cpu(htt_stats_buf->buf_max));
2130 	len += scnprintf(buf + len, buf_len - len, "buf_busy = %u\n",
2131 			 le32_to_cpu(htt_stats_buf->buf_busy));
2132 	len += scnprintf(buf + len, buf_len - len, "buf_alloc = %u\n",
2133 			 le32_to_cpu(htt_stats_buf->buf_alloc));
2134 	len += scnprintf(buf + len, buf_len - len, "buf_avail = %u\n",
2135 			 le32_to_cpu(htt_stats_buf->buf_avail));
2136 	len += scnprintf(buf + len, buf_len - len, "num_users = %u\n\n",
2137 			 le32_to_cpu(htt_stats_buf->num_users));
2138 
2139 	stats_req->buf_len = len;
2140 }
2141 
2142 static void
ath12k_htt_print_sfm_client_user_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2143 ath12k_htt_print_sfm_client_user_tlv(const void *tag_buf, u16 tag_len,
2144 				     struct debug_htt_stats_req *stats_req)
2145 {
2146 	const struct ath12k_htt_sfm_client_user_tlv *htt_stats_buf = tag_buf;
2147 	u8 *buf = stats_req->buf;
2148 	u32 len = stats_req->buf_len;
2149 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2150 	u16 num_elems = tag_len >> 2;
2151 
2152 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV:\n");
2153 	len += print_array_to_buf(buf, len, "dwords_used_by_user_n",
2154 				  htt_stats_buf->dwords_used_by_user_n,
2155 				  num_elems, "\n\n");
2156 
2157 	stats_req->buf_len = len;
2158 }
2159 
2160 static void
ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2161 ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, u16 tag_len,
2162 					       struct debug_htt_stats_req *stats_req)
2163 {
2164 	const struct ath12k_htt_tx_pdev_mu_mimo_sch_stats_tlv *htt_stats_buf = tag_buf;
2165 	u8 *buf = stats_req->buf;
2166 	u32 len = stats_req->buf_len;
2167 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2168 	u8 i;
2169 
2170 	if (tag_len < sizeof(*htt_stats_buf))
2171 		return;
2172 
2173 	len += scnprintf(buf + len, buf_len - len,
2174 			 "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:\n");
2175 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n",
2176 			 le32_to_cpu(htt_stats_buf->mu_mimo_sch_posted));
2177 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n",
2178 			 le32_to_cpu(htt_stats_buf->mu_mimo_sch_failed));
2179 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n",
2180 			 le32_to_cpu(htt_stats_buf->mu_mimo_ppdu_posted));
2181 	len += scnprintf(buf + len, buf_len - len,
2182 			 "\nac_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2183 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[0]));
2184 	for (i = 1; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2185 		len += scnprintf(buf + len, buf_len - len,
2186 				 "ac_mu_mimo_sch_posted_per_group_index %u ", i);
2187 		len += scnprintf(buf + len, buf_len - len,
2188 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2189 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[i]));
2190 	}
2191 
2192 	for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2193 		len += scnprintf(buf + len, buf_len - len,
2194 				 "ac_mu_mimo_sch_posted_per_group_index %u ",
2195 				 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS);
2196 		len += scnprintf(buf + len, buf_len - len,
2197 				 "(TOTAL STREAMS = %u) = %u\n",
2198 				 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS + 1,
2199 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_grp_sz_ext[i]));
2200 	}
2201 
2202 	len += scnprintf(buf + len, buf_len - len,
2203 			 "\nax_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2204 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[0]));
2205 	for (i = 1; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2206 		len += scnprintf(buf + len, buf_len - len,
2207 				 "ax_mu_mimo_sch_posted_per_group_index %u ", i);
2208 		len += scnprintf(buf + len, buf_len - len,
2209 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2210 				 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[i]));
2211 	}
2212 
2213 	len += scnprintf(buf + len, buf_len - len,
2214 			"\nbe_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2215 			le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[0]));
2216 	for (i = 1; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2217 		len += scnprintf(buf + len, buf_len - len,
2218 				 "be_mu_mimo_sch_posted_per_group_index %u ", i);
2219 		len += scnprintf(buf + len, buf_len - len,
2220 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2221 				 le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[i]));
2222 	}
2223 
2224 	len += scnprintf(buf + len, buf_len - len, "\n11ac MU_MIMO SCH STATS:\n");
2225 	for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2226 		len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_sch_nusers_");
2227 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2228 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_sch_nusers[i]));
2229 	}
2230 
2231 	len += scnprintf(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:\n");
2232 	for (i = 0; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2233 		len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_sch_nusers_");
2234 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2235 				 le32_to_cpu(htt_stats_buf->ax_mu_mimo_sch_nusers[i]));
2236 	}
2237 
2238 	len += scnprintf(buf + len, buf_len - len, "\n11be MU_MIMO SCH STATS:\n");
2239 	for (i = 0; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2240 		len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_sch_nusers_");
2241 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2242 				 le32_to_cpu(htt_stats_buf->be_mu_mimo_sch_nusers[i]));
2243 	}
2244 
2245 	len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n");
2246 	for (i = 0; i < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS; i++) {
2247 		len += scnprintf(buf + len, buf_len - len,
2248 				 "ax_ofdma_sch_nusers_%u = %u\n", i,
2249 				 le32_to_cpu(htt_stats_buf->ax_ofdma_sch_nusers[i]));
2250 		len += scnprintf(buf + len, buf_len - len,
2251 				 "ax_ul_ofdma_basic_sch_nusers_%u = %u\n", i,
2252 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_nusers[i]));
2253 		len += scnprintf(buf + len, buf_len - len,
2254 				 "ax_ul_ofdma_bsr_sch_nusers_%u = %u\n", i,
2255 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bsr_nusers[i]));
2256 		len += scnprintf(buf + len, buf_len - len,
2257 				 "ax_ul_ofdma_bar_sch_nusers_%u = %u\n", i,
2258 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bar_nusers[i]));
2259 		len += scnprintf(buf + len, buf_len - len,
2260 				 "ax_ul_ofdma_brp_sch_nusers_%u = %u\n\n", i,
2261 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_brp_nusers[i]));
2262 	}
2263 
2264 	len += scnprintf(buf + len, buf_len - len, "11ax UL MUMIMO SCH STATS:\n");
2265 	for (i = 0; i < ATH12K_HTT_TX_NUM_UL_MUMIMO_USER_STATS; i++) {
2266 		len += scnprintf(buf + len, buf_len - len,
2267 				 "ax_ul_mumimo_basic_sch_nusers_%u = %u\n", i,
2268 				 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_nusers[i]));
2269 		len += scnprintf(buf + len, buf_len - len,
2270 				 "ax_ul_mumimo_brp_sch_nusers_%u = %u\n\n", i,
2271 				 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_brp_nusers[i]));
2272 	}
2273 
2274 	stats_req->buf_len = len;
2275 }
2276 
2277 static void
ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2278 ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(const void *tag_buf, u16 tag_len,
2279 					      struct debug_htt_stats_req *stats_req)
2280 {
2281 	const struct ath12k_htt_tx_pdev_mumimo_grp_stats_tlv *htt_stats_buf = tag_buf;
2282 	u8 *buf = stats_req->buf;
2283 	u32 len = stats_req->buf_len;
2284 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2285 	int j;
2286 
2287 	if (tag_len < sizeof(*htt_stats_buf))
2288 		return;
2289 
2290 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_MUMIMO_GRP_STATS:\n");
2291 	len += print_array_to_buf(buf, len,
2292 				  "dl_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2293 				  htt_stats_buf->dl_mumimo_grp_tputs,
2294 				  ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n");
2295 	len += print_array_to_buf(buf, len, "dl_mumimo_grp eligible",
2296 				  htt_stats_buf->dl_mumimo_grp_eligible,
2297 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2298 	len += print_array_to_buf(buf, len, "dl_mumimo_grp_ineligible",
2299 				  htt_stats_buf->dl_mumimo_grp_ineligible,
2300 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2301 	len += scnprintf(buf + len, buf_len - len, "dl_mumimo_grp_invalid:\n");
2302 	for (j = 0; j < ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ; j++) {
2303 		len += scnprintf(buf + len, buf_len - len, "grp_id = %u", j);
2304 		len += print_array_to_buf(buf, len, "",
2305 					  htt_stats_buf->dl_mumimo_grp_invalid,
2306 					  ATH12K_HTT_STATS_MAX_INVALID_REASON_CODE,
2307 					  "\n");
2308 	}
2309 
2310 	len += print_array_to_buf(buf, len, "ul_mumimo_grp_best_grp_size",
2311 				  htt_stats_buf->ul_mumimo_grp_best_grp_size,
2312 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2313 	len += print_array_to_buf(buf, len, "ul_mumimo_grp_best_num_usrs = ",
2314 				  htt_stats_buf->ul_mumimo_grp_best_usrs,
2315 				  ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS, "\n");
2316 	len += print_array_to_buf(buf, len,
2317 				  "ul_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2318 				  htt_stats_buf->ul_mumimo_grp_tputs,
2319 				  ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n\n");
2320 
2321 	stats_req->buf_len = len;
2322 }
2323 
2324 static void
ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2325 ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
2326 						struct debug_htt_stats_req *stats_req)
2327 {
2328 	const struct ath12k_htt_tx_pdev_mpdu_stats_tlv *htt_stats_buf = tag_buf;
2329 	u8 *buf = stats_req->buf;
2330 	u32 len = stats_req->buf_len;
2331 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2332 	u32 user_index;
2333 	u32 tx_sched_mode;
2334 
2335 	if (tag_len < sizeof(*htt_stats_buf))
2336 		return;
2337 
2338 	user_index = __le32_to_cpu(htt_stats_buf->user_index);
2339 	tx_sched_mode = __le32_to_cpu(htt_stats_buf->tx_sched_mode);
2340 
2341 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AC) {
2342 		if (!user_index)
2343 			len += scnprintf(buf + len, buf_len - len,
2344 					 "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n");
2345 
2346 		if (user_index < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS) {
2347 			len += scnprintf(buf + len, buf_len - len,
2348 					 "ac_mu_mimo_mpdus_queued_usr_%u = %u\n",
2349 					 user_index,
2350 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2351 			len += scnprintf(buf + len, buf_len - len,
2352 					 "ac_mu_mimo_mpdus_tried_usr_%u = %u\n",
2353 					 user_index,
2354 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2355 			len += scnprintf(buf + len, buf_len - len,
2356 					 "ac_mu_mimo_mpdus_failed_usr_%u = %u\n",
2357 					 user_index,
2358 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2359 			len += scnprintf(buf + len, buf_len - len,
2360 					 "ac_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2361 					 user_index,
2362 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2363 			len += scnprintf(buf + len, buf_len - len,
2364 					 "ac_mu_mimo_err_no_ba_usr_%u = %u\n",
2365 					 user_index,
2366 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2367 			len += scnprintf(buf + len, buf_len - len,
2368 					 "ac_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2369 					 user_index,
2370 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2371 			len += scnprintf(buf + len, buf_len - len,
2372 					"ac_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2373 					 user_index,
2374 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2375 		}
2376 	}
2377 
2378 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AX) {
2379 		if (!user_index)
2380 			len += scnprintf(buf + len, buf_len - len,
2381 					 "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n");
2382 
2383 		if (user_index < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS) {
2384 			len += scnprintf(buf + len, buf_len - len,
2385 					 "ax_mu_mimo_mpdus_queued_usr_%u = %u\n",
2386 					 user_index,
2387 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2388 			len += scnprintf(buf + len, buf_len - len,
2389 					 "ax_mu_mimo_mpdus_tried_usr_%u = %u\n",
2390 					 user_index,
2391 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2392 			len += scnprintf(buf + len, buf_len - len,
2393 					 "ax_mu_mimo_mpdus_failed_usr_%u = %u\n",
2394 					 user_index,
2395 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2396 			len += scnprintf(buf + len, buf_len - len,
2397 					 "ax_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2398 					 user_index,
2399 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2400 			len += scnprintf(buf + len, buf_len - len,
2401 					 "ax_mu_mimo_err_no_ba_usr_%u = %u\n",
2402 					 user_index,
2403 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2404 			len += scnprintf(buf + len, buf_len - len,
2405 					 "ax_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2406 					 user_index,
2407 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2408 			len += scnprintf(buf + len, buf_len - len,
2409 					 "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2410 					 user_index,
2411 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2412 		}
2413 	}
2414 
2415 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_OFDMA_AX) {
2416 		if (!user_index)
2417 			len += scnprintf(buf + len, buf_len - len,
2418 					 "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n");
2419 
2420 		if (user_index < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS) {
2421 			len += scnprintf(buf + len, buf_len - len,
2422 					 "ax_mu_ofdma_mpdus_queued_usr_%u = %u\n",
2423 					 user_index,
2424 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2425 			len += scnprintf(buf + len, buf_len - len,
2426 					 "ax_mu_ofdma_mpdus_tried_usr_%u = %u\n",
2427 					 user_index,
2428 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2429 			len += scnprintf(buf + len, buf_len - len,
2430 					 "ax_mu_ofdma_mpdus_failed_usr_%u = %u\n",
2431 					 user_index,
2432 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2433 			len += scnprintf(buf + len, buf_len - len,
2434 					 "ax_mu_ofdma_mpdus_requeued_usr_%u = %u\n",
2435 					 user_index,
2436 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2437 			len += scnprintf(buf + len, buf_len - len,
2438 					 "ax_mu_ofdma_err_no_ba_usr_%u = %u\n",
2439 					 user_index,
2440 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2441 			len += scnprintf(buf + len, buf_len - len,
2442 					 "ax_mu_ofdma_mpdu_underrun_usr_%u = %u\n",
2443 					 user_index,
2444 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2445 			len += scnprintf(buf + len, buf_len - len,
2446 					 "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n\n",
2447 					 user_index,
2448 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2449 		}
2450 	}
2451 
2452 	stats_req->buf_len = len;
2453 }
2454 
2455 static void
ath12k_htt_print_pdev_cca_stats_hist_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2456 ath12k_htt_print_pdev_cca_stats_hist_tlv(const void *tag_buf, u16 tag_len,
2457 					 struct debug_htt_stats_req *stats_req)
2458 {
2459 	const struct ath12k_htt_pdev_cca_stats_hist_v1_tlv *htt_stats_buf = tag_buf;
2460 	u8 *buf = stats_req->buf;
2461 	u32 len = stats_req->buf_len;
2462 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2463 
2464 	if (tag_len < sizeof(*htt_stats_buf))
2465 		return;
2466 
2467 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_CCA_STATS_HIST_TLV :\n");
2468 	len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
2469 			 le32_to_cpu(htt_stats_buf->chan_num));
2470 	len += scnprintf(buf + len, buf_len - len, "num_records = %u\n",
2471 			 le32_to_cpu(htt_stats_buf->num_records));
2472 	len += scnprintf(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x\n",
2473 			 le32_to_cpu(htt_stats_buf->valid_cca_counters_bitmap));
2474 	len += scnprintf(buf + len, buf_len - len, "collection_interval = %u\n\n",
2475 			 le32_to_cpu(htt_stats_buf->collection_interval));
2476 
2477 	stats_req->buf_len = len;
2478 }
2479 
2480 static void
ath12k_htt_print_pdev_stats_cca_counters_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2481 ath12k_htt_print_pdev_stats_cca_counters_tlv(const void *tag_buf, u16 tag_len,
2482 					     struct debug_htt_stats_req *stats_req)
2483 {
2484 	const struct ath12k_htt_pdev_stats_cca_counters_tlv *htt_stats_buf = tag_buf;
2485 	u8 *buf = stats_req->buf;
2486 	u32 len = stats_req->buf_len;
2487 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2488 
2489 	if (tag_len < sizeof(*htt_stats_buf))
2490 		return;
2491 
2492 	len += scnprintf(buf + len, buf_len - len,
2493 			 "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)\n");
2494 	len += scnprintf(buf + len, buf_len - len, "tx_frame_usec = %u\n",
2495 			 le32_to_cpu(htt_stats_buf->tx_frame_usec));
2496 	len += scnprintf(buf + len, buf_len - len, "rx_frame_usec = %u\n",
2497 			 le32_to_cpu(htt_stats_buf->rx_frame_usec));
2498 	len += scnprintf(buf + len, buf_len - len, "rx_clear_usec = %u\n",
2499 			 le32_to_cpu(htt_stats_buf->rx_clear_usec));
2500 	len += scnprintf(buf + len, buf_len - len, "my_rx_frame_usec = %u\n",
2501 			 le32_to_cpu(htt_stats_buf->my_rx_frame_usec));
2502 	len += scnprintf(buf + len, buf_len - len, "usec_cnt = %u\n",
2503 			 le32_to_cpu(htt_stats_buf->usec_cnt));
2504 	len += scnprintf(buf + len, buf_len - len, "med_rx_idle_usec = %u\n",
2505 			 le32_to_cpu(htt_stats_buf->med_rx_idle_usec));
2506 	len += scnprintf(buf + len, buf_len - len, "med_tx_idle_global_usec = %u\n",
2507 			 le32_to_cpu(htt_stats_buf->med_tx_idle_global_usec));
2508 	len += scnprintf(buf + len, buf_len - len, "cca_obss_usec = %u\n\n",
2509 			 le32_to_cpu(htt_stats_buf->cca_obss_usec));
2510 
2511 	stats_req->buf_len = len;
2512 }
2513 
2514 static void
ath12k_htt_print_pdev_obss_pd_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2515 ath12k_htt_print_pdev_obss_pd_stats_tlv(const void *tag_buf, u16 tag_len,
2516 					struct debug_htt_stats_req *stats_req)
2517 {
2518 	const struct ath12k_htt_pdev_obss_pd_stats_tlv *htt_stats_buf = tag_buf;
2519 	u8 *buf = stats_req->buf;
2520 	u32 len = stats_req->buf_len;
2521 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2522 	u8 i;
2523 	static const char *access_cat_names[ATH12K_HTT_NUM_AC_WMM] = {"best effort",
2524 								      "background",
2525 								      "video", "voice"};
2526 
2527 	if (tag_len < sizeof(*htt_stats_buf))
2528 		return;
2529 
2530 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_STATS_TLV:\n");
2531 	len += scnprintf(buf + len, buf_len - len, "num_spatial_reuse_tx = %u\n",
2532 			 le32_to_cpu(htt_stats_buf->num_sr_tx_transmissions));
2533 	len += scnprintf(buf + len, buf_len - len,
2534 			 "num_spatial_reuse_opportunities = %u\n",
2535 			 le32_to_cpu(htt_stats_buf->num_spatial_reuse_opportunities));
2536 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_opportunities = %u\n",
2537 			 le32_to_cpu(htt_stats_buf->num_non_srg_opportunities));
2538 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_tried = %u\n",
2539 			 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_tried));
2540 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_success = %u\n",
2541 			 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_success));
2542 	len += scnprintf(buf + len, buf_len - len, "num_srg_opportunities = %u\n",
2543 			 le32_to_cpu(htt_stats_buf->num_srg_opportunities));
2544 	len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2545 			 le32_to_cpu(htt_stats_buf->num_srg_ppdu_tried));
2546 	len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_success = %u\n",
2547 			 le32_to_cpu(htt_stats_buf->num_srg_ppdu_success));
2548 	len += scnprintf(buf + len, buf_len - len, "num_psr_opportunities = %u\n",
2549 			 le32_to_cpu(htt_stats_buf->num_psr_opportunities));
2550 	len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_tried = %u\n",
2551 			 le32_to_cpu(htt_stats_buf->num_psr_ppdu_tried));
2552 	len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_success = %u\n",
2553 			 le32_to_cpu(htt_stats_buf->num_psr_ppdu_success));
2554 	len += scnprintf(buf + len, buf_len - len, "min_duration_check_flush_cnt = %u\n",
2555 			 le32_to_cpu(htt_stats_buf->num_obss_min_dur_check_flush_cnt));
2556 	len += scnprintf(buf + len, buf_len - len, "sr_ppdu_abort_flush_cnt = %u\n\n",
2557 			 le32_to_cpu(htt_stats_buf->num_sr_ppdu_abort_flush_cnt));
2558 
2559 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_PER_AC_STATS:\n");
2560 	for (i = 0; i < ATH12K_HTT_NUM_AC_WMM; i++) {
2561 		len += scnprintf(buf + len, buf_len - len, "Access Category %u (%s)\n",
2562 				 i, access_cat_names[i]);
2563 		len += scnprintf(buf + len, buf_len - len,
2564 				 "num_non_srg_ppdu_tried = %u\n",
2565 				 le32_to_cpu(htt_stats_buf->num_non_srg_tried_per_ac[i]));
2566 		len += scnprintf(buf + len, buf_len - len,
2567 				 "num_non_srg_ppdu_success = %u\n",
2568 				 le32_to_cpu(htt_stats_buf->num_non_srg_success_ac[i]));
2569 		len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2570 				 le32_to_cpu(htt_stats_buf->num_srg_tried_per_ac[i]));
2571 		len += scnprintf(buf + len, buf_len - len,
2572 				 "num_srg_ppdu_success = %u\n\n",
2573 				 le32_to_cpu(htt_stats_buf->num_srg_success_per_ac[i]));
2574 	}
2575 
2576 	stats_req->buf_len = len;
2577 }
2578 
2579 static void
ath12k_htt_print_pdev_tx_rate_txbf_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2580 ath12k_htt_print_pdev_tx_rate_txbf_stats_tlv(const void *tag_buf, u16 tag_len,
2581 					     struct debug_htt_stats_req *stats_req)
2582 {
2583 	const struct ath12k_htt_pdev_txrate_txbf_stats_tlv *htt_stats_buf = tag_buf;
2584 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2585 	u32 len = stats_req->buf_len;
2586 	u8 *buf = stats_req->buf;
2587 	u8 i;
2588 
2589 	if (tag_len < sizeof(*htt_stats_buf))
2590 		return;
2591 
2592 	len += scnprintf(buf + len, buf_len - len,
2593 			 "HTT_STATS_PDEV_TX_RATE_TXBF_STATS:\n");
2594 	len += scnprintf(buf + len, buf_len - len, "Legacy OFDM Rates: 6 Mbps: %u, ",
2595 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[0]));
2596 	len += scnprintf(buf + len, buf_len - len, "9 Mbps: %u, 12 Mbps: %u, ",
2597 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[1]),
2598 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[2]));
2599 	len += scnprintf(buf + len, buf_len - len, "18 Mbps: %u\n",
2600 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[3]));
2601 	len += scnprintf(buf + len, buf_len - len, "24 Mbps: %u, 36 Mbps: %u, ",
2602 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[4]),
2603 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[5]));
2604 	len += scnprintf(buf + len, buf_len - len, "48 Mbps: %u, 54 Mbps: %u\n",
2605 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[6]),
2606 			 le32_to_cpu(htt_stats_buf->tx_legacy_ofdm_rate[7]));
2607 
2608 	len += print_array_to_buf(buf, len, "tx_ol_mcs", htt_stats_buf->tx_su_ol_mcs,
2609 				  ATH12K_HTT_TX_BF_RATE_STATS_NUM_MCS_COUNTERS, "\n");
2610 	len += print_array_to_buf(buf, len, "tx_ibf_mcs", htt_stats_buf->tx_su_ibf_mcs,
2611 				  ATH12K_HTT_TX_BF_RATE_STATS_NUM_MCS_COUNTERS, "\n");
2612 	len += print_array_to_buf(buf, len, "tx_txbf_mcs", htt_stats_buf->tx_su_txbf_mcs,
2613 				  ATH12K_HTT_TX_BF_RATE_STATS_NUM_MCS_COUNTERS, "\n");
2614 	len += print_array_to_buf_index(buf, len, "tx_ol_nss", 1,
2615 					htt_stats_buf->tx_su_ol_nss,
2616 					ATH12K_HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS,
2617 					"\n");
2618 	len += print_array_to_buf_index(buf, len, "tx_ibf_nss", 1,
2619 					htt_stats_buf->tx_su_ibf_nss,
2620 					ATH12K_HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS,
2621 					"\n");
2622 	len += print_array_to_buf_index(buf, len, "tx_txbf_nss", 1,
2623 					htt_stats_buf->tx_su_txbf_nss,
2624 					ATH12K_HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS,
2625 					"\n");
2626 	len += print_array_to_buf(buf, len, "tx_ol_bw", htt_stats_buf->tx_su_ol_bw,
2627 				  ATH12K_HTT_TXBF_NUM_BW_CNTRS, "\n");
2628 	for (i = 0; i < ATH12K_HTT_TXBF_NUM_REDUCED_CHAN_TYPES; i++)
2629 		len += print_array_to_buf(buf, len, i ? "quarter_tx_ol_bw" :
2630 					  "half_tx_ol_bw",
2631 					  htt_stats_buf->ol[i],
2632 					  ATH12K_HTT_TXBF_NUM_BW_CNTRS,
2633 					  "\n");
2634 
2635 	len += print_array_to_buf(buf, len, "tx_ibf_bw", htt_stats_buf->tx_su_ibf_bw,
2636 				  ATH12K_HTT_TXBF_NUM_BW_CNTRS, "\n");
2637 	for (i = 0; i < ATH12K_HTT_TXBF_NUM_REDUCED_CHAN_TYPES; i++)
2638 		len += print_array_to_buf(buf, len, i ? "quarter_tx_ibf_bw" :
2639 					  "half_tx_ibf_bw",
2640 					  htt_stats_buf->ibf[i],
2641 					  ATH12K_HTT_TXBF_NUM_BW_CNTRS,
2642 					  "\n");
2643 
2644 	len += print_array_to_buf(buf, len, "tx_txbf_bw", htt_stats_buf->tx_su_txbf_bw,
2645 				  ATH12K_HTT_TXBF_NUM_BW_CNTRS, "\n");
2646 	for (i = 0; i < ATH12K_HTT_TXBF_NUM_REDUCED_CHAN_TYPES; i++)
2647 		len += print_array_to_buf(buf, len, i ? "quarter_tx_txbf_bw" :
2648 					  "half_tx_txbf_bw",
2649 					  htt_stats_buf->txbf[i],
2650 					  ATH12K_HTT_TXBF_NUM_BW_CNTRS,
2651 					  "\n");
2652 	len += scnprintf(buf + len, buf_len - len, "\n");
2653 
2654 	len += scnprintf(buf + len, buf_len - len,
2655 			 "HTT_STATS_PDEV_TXBF_FLAG_RETURN_STATS:\n");
2656 	len += scnprintf(buf + len, buf_len - len, "TXBF_reason_code_stats: 0:%u, 1:%u,",
2657 			 le32_to_cpu(htt_stats_buf->txbf_flag_set_mu_mode),
2658 			 le32_to_cpu(htt_stats_buf->txbf_flag_set_final_status));
2659 	len += scnprintf(buf + len, buf_len - len, " 2:%u, 3:%u, 4:%u, 5:%u, ",
2660 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_verified_txbf_mode),
2661 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_disable_p2p_access),
2662 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_max_nss_in_he160),
2663 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_disable_uldlofdma));
2664 	len += scnprintf(buf + len, buf_len - len, "6:%u, 7:%u\n\n",
2665 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_mcs_threshold_val),
2666 			 le32_to_cpu(htt_stats_buf->txbf_flag_not_set_final_status));
2667 
2668 	stats_req->buf_len = len;
2669 }
2670 
2671 static void
ath12k_htt_print_txbf_ofdma_ax_ndpa_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2672 ath12k_htt_print_txbf_ofdma_ax_ndpa_stats_tlv(const void *tag_buf, u16 tag_len,
2673 					      struct debug_htt_stats_req *stats_req)
2674 {
2675 	const struct ath12k_htt_txbf_ofdma_ax_ndpa_stats_tlv *stats_buf = tag_buf;
2676 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2677 	u32 len = stats_req->buf_len;
2678 	u8 *buf = stats_req->buf;
2679 	u32 num_elements;
2680 	u8 i;
2681 
2682 	if (tag_len < sizeof(*stats_buf))
2683 		return;
2684 
2685 	num_elements = le32_to_cpu(stats_buf->num_elems_ax_ndpa_arr);
2686 
2687 	len += scnprintf(buf + len, buf_len - len, "HTT_TXBF_OFDMA_AX_NDPA_STATS_TLV:\n");
2688 	len += scnprintf(buf + len, buf_len - len, "ax_ofdma_ndpa_queued =");
2689 	for (i = 0; i < num_elements; i++)
2690 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2691 				 le32_to_cpu(stats_buf->ax_ndpa[i].ax_ofdma_ndpa_queued));
2692 	len--;
2693 	*(buf + len) = '\0';
2694 
2695 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndpa_tried =");
2696 	for (i = 0; i < num_elements; i++)
2697 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2698 				 le32_to_cpu(stats_buf->ax_ndpa[i].ax_ofdma_ndpa_tried));
2699 	len--;
2700 	*(buf + len) = '\0';
2701 
2702 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndpa_flushed =");
2703 	for (i = 0; i < num_elements; i++)
2704 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2705 				 le32_to_cpu(stats_buf->ax_ndpa[i].ax_ofdma_ndpa_flush));
2706 	len--;
2707 	*(buf + len) = '\0';
2708 
2709 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndpa_err =");
2710 	for (i = 0; i < num_elements; i++)
2711 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2712 				 le32_to_cpu(stats_buf->ax_ndpa[i].ax_ofdma_ndpa_err));
2713 	len--;
2714 	*(buf + len) = '\0';
2715 
2716 	len += scnprintf(buf + len, buf_len - len, "\n\n");
2717 
2718 	stats_req->buf_len = len;
2719 }
2720 
2721 static void
ath12k_htt_print_txbf_ofdma_ax_ndp_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2722 ath12k_htt_print_txbf_ofdma_ax_ndp_stats_tlv(const void *tag_buf, u16 tag_len,
2723 					     struct debug_htt_stats_req *stats_req)
2724 {
2725 	const struct ath12k_htt_txbf_ofdma_ax_ndp_stats_tlv *stats_buf = tag_buf;
2726 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2727 	u32 len = stats_req->buf_len;
2728 	u8 *buf = stats_req->buf;
2729 	u32 num_elements;
2730 	u8 i;
2731 
2732 	if (tag_len < sizeof(*stats_buf))
2733 		return;
2734 
2735 	num_elements = le32_to_cpu(stats_buf->num_elems_ax_ndp_arr);
2736 
2737 	len += scnprintf(buf + len, buf_len - len, "HTT_TXBF_OFDMA_AX_NDP_STATS_TLV:\n");
2738 	len += scnprintf(buf + len, buf_len - len, "ax_ofdma_ndp_queued =");
2739 	for (i = 0; i < num_elements; i++)
2740 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2741 				 le32_to_cpu(stats_buf->ax_ndp[i].ax_ofdma_ndp_queued));
2742 	len--;
2743 	*(buf + len) = '\0';
2744 
2745 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndp_tried =");
2746 	for (i = 0; i < num_elements; i++)
2747 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2748 				 le32_to_cpu(stats_buf->ax_ndp[i].ax_ofdma_ndp_tried));
2749 	len--;
2750 	*(buf + len) = '\0';
2751 
2752 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndp_flushed =");
2753 	for (i = 0; i < num_elements; i++)
2754 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2755 				 le32_to_cpu(stats_buf->ax_ndp[i].ax_ofdma_ndp_flush));
2756 	len--;
2757 	*(buf + len) = '\0';
2758 
2759 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_ndp_err =");
2760 	for (i = 0; i < num_elements; i++)
2761 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2762 				 le32_to_cpu(stats_buf->ax_ndp[i].ax_ofdma_ndp_err));
2763 	len--;
2764 	*(buf + len) = '\0';
2765 
2766 	len += scnprintf(buf + len, buf_len - len, "\n\n");
2767 
2768 	stats_req->buf_len = len;
2769 }
2770 
2771 static void
ath12k_htt_print_txbf_ofdma_ax_brp_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2772 ath12k_htt_print_txbf_ofdma_ax_brp_stats_tlv(const void *tag_buf, u16 tag_len,
2773 					     struct debug_htt_stats_req *stats_req)
2774 {
2775 	const struct ath12k_htt_txbf_ofdma_ax_brp_stats_tlv *stats_buf = tag_buf;
2776 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2777 	u32 len = stats_req->buf_len;
2778 	u8 *buf = stats_req->buf;
2779 	u32 num_elements;
2780 	u8 i;
2781 
2782 	if (tag_len < sizeof(*stats_buf))
2783 		return;
2784 
2785 	num_elements = le32_to_cpu(stats_buf->num_elems_ax_brp_arr);
2786 
2787 	len += scnprintf(buf + len, buf_len - len, "HTT_TXBF_OFDMA_AX_BRP_STATS_TLV:\n");
2788 	len += scnprintf(buf + len, buf_len - len, "ax_ofdma_brpoll_queued =");
2789 	for (i = 0; i < num_elements; i++)
2790 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2791 				 le32_to_cpu(stats_buf->ax_brp[i].ax_ofdma_brp_queued));
2792 	len--;
2793 	*(buf + len) = '\0';
2794 
2795 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_brpoll_tied =");
2796 	for (i = 0; i < num_elements; i++)
2797 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2798 				 le32_to_cpu(stats_buf->ax_brp[i].ax_ofdma_brp_tried));
2799 	len--;
2800 	*(buf + len) = '\0';
2801 
2802 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_brpoll_flushed =");
2803 	for (i = 0; i < num_elements; i++)
2804 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2805 				 le32_to_cpu(stats_buf->ax_brp[i].ax_ofdma_brp_flushed));
2806 	len--;
2807 	*(buf + len) = '\0';
2808 
2809 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_brp_err =");
2810 	for (i = 0; i < num_elements; i++)
2811 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2812 				 le32_to_cpu(stats_buf->ax_brp[i].ax_ofdma_brp_err));
2813 	len--;
2814 	*(buf + len) = '\0';
2815 
2816 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_brp_err_num_cbf_rcvd =");
2817 	for (i = 0; i < num_elements; i++)
2818 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2819 				 le32_to_cpu(stats_buf->ax_brp[i].ax_ofdma_num_cbf_rcvd));
2820 	len--;
2821 	*(buf + len) = '\0';
2822 
2823 	len += scnprintf(buf + len, buf_len - len, "\n\n");
2824 
2825 	stats_req->buf_len = len;
2826 }
2827 
2828 static void
ath12k_htt_print_txbf_ofdma_ax_steer_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2829 ath12k_htt_print_txbf_ofdma_ax_steer_stats_tlv(const void *tag_buf, u16 tag_len,
2830 					       struct debug_htt_stats_req *stats_req)
2831 {
2832 	const struct ath12k_htt_txbf_ofdma_ax_steer_stats_tlv *stats_buf = tag_buf;
2833 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2834 	u32 len = stats_req->buf_len;
2835 	u8 *buf = stats_req->buf;
2836 	u32 num_elements;
2837 	u8 i;
2838 
2839 	if (tag_len < sizeof(*stats_buf))
2840 		return;
2841 
2842 	num_elements = le32_to_cpu(stats_buf->num_elems_ax_steer_arr);
2843 
2844 	len += scnprintf(buf + len, buf_len - len,
2845 			 "HTT_TXBF_OFDMA_AX_STEER_STATS_TLV:\n");
2846 	len += scnprintf(buf + len, buf_len - len, "ax_ofdma_num_ppdu_steer =");
2847 	for (i = 0; i < num_elements; i++)
2848 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2849 				 le32_to_cpu(stats_buf->ax_steer[i].num_ppdu_steer));
2850 	len--;
2851 	*(buf + len) = '\0';
2852 
2853 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_num_usrs_prefetch =");
2854 	for (i = 0; i < num_elements; i++)
2855 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2856 				 le32_to_cpu(stats_buf->ax_steer[i].num_usr_prefetch));
2857 	len--;
2858 	*(buf + len) = '\0';
2859 
2860 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_num_usrs_sound =");
2861 	for (i = 0; i < num_elements; i++)
2862 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2863 				 le32_to_cpu(stats_buf->ax_steer[i].num_usr_sound));
2864 	len--;
2865 	*(buf + len) = '\0';
2866 
2867 	len += scnprintf(buf + len, buf_len - len, "\nax_ofdma_num_usrs_force_sound =");
2868 	for (i = 0; i < num_elements; i++)
2869 		len += scnprintf(buf + len, buf_len - len, " %u:%u,", i + 1,
2870 				 le32_to_cpu(stats_buf->ax_steer[i].num_usr_force_sound));
2871 	len--;
2872 	*(buf + len) = '\0';
2873 
2874 	len += scnprintf(buf + len, buf_len - len, "\n\n");
2875 
2876 	stats_req->buf_len = len;
2877 }
2878 
2879 static void
ath12k_htt_print_txbf_ofdma_ax_steer_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2880 ath12k_htt_print_txbf_ofdma_ax_steer_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
2881 						    struct debug_htt_stats_req *stats_req)
2882 {
2883 	const struct ath12k_htt_txbf_ofdma_ax_steer_mpdu_stats_tlv *stats_buf = tag_buf;
2884 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2885 	u32 len = stats_req->buf_len;
2886 	u8 *buf = stats_req->buf;
2887 
2888 	if (tag_len < sizeof(*stats_buf))
2889 		return;
2890 
2891 	len += scnprintf(buf + len, buf_len - len,
2892 			 "HTT_TXBF_OFDMA_AX_STEER_MPDU_STATS_TLV:\n");
2893 	len += scnprintf(buf + len, buf_len - len, "rbo_steer_mpdus_tried = %u\n",
2894 			 le32_to_cpu(stats_buf->ax_ofdma_rbo_steer_mpdus_tried));
2895 	len += scnprintf(buf + len, buf_len - len, "rbo_steer_mpdus_failed = %u\n",
2896 			 le32_to_cpu(stats_buf->ax_ofdma_rbo_steer_mpdus_failed));
2897 	len += scnprintf(buf + len, buf_len - len, "sifs_steer_mpdus_tried = %u\n",
2898 			 le32_to_cpu(stats_buf->ax_ofdma_sifs_steer_mpdus_tried));
2899 	len += scnprintf(buf + len, buf_len - len, "sifs_steer_mpdus_failed = %u\n\n",
2900 			 le32_to_cpu(stats_buf->ax_ofdma_sifs_steer_mpdus_failed));
2901 
2902 	stats_req->buf_len = len;
2903 }
2904 
ath12k_htt_print_dlpager_entry(const struct ath12k_htt_pgs_info * pg_info,int idx,char * str_buf)2905 static void ath12k_htt_print_dlpager_entry(const struct ath12k_htt_pgs_info *pg_info,
2906 					   int idx, char *str_buf)
2907 {
2908 	u64 page_timestamp;
2909 	u16 index = 0;
2910 
2911 	page_timestamp = ath12k_le32hilo_to_u64(pg_info->ts_msb, pg_info->ts_lsb);
2912 
2913 	index += snprintf(&str_buf[index], ATH12K_HTT_MAX_STRING_LEN - index,
2914 			  "Index - %u ; Page Number - %u ; ",
2915 			  idx, le32_to_cpu(pg_info->page_num));
2916 	index += snprintf(&str_buf[index], ATH12K_HTT_MAX_STRING_LEN - index,
2917 			  "Num of pages - %u ; Timestamp - %lluus\n",
2918 			  le32_to_cpu(pg_info->num_pgs), page_timestamp);
2919 }
2920 
2921 static void
ath12k_htt_print_dlpager_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2922 ath12k_htt_print_dlpager_stats_tlv(const void *tag_buf, u16 tag_len,
2923 				   struct debug_htt_stats_req *stats_req)
2924 {
2925 	const struct ath12k_htt_dl_pager_stats_tlv *stat_buf = tag_buf;
2926 	u32 len = stats_req->buf_len;
2927 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2928 	u32 dword_lock, dword_unlock;
2929 	int i;
2930 	u8 *buf = stats_req->buf;
2931 	u8 pg_locked;
2932 	u8 pg_unlock;
2933 	char str_buf[ATH12K_HTT_MAX_STRING_LEN] = {0};
2934 
2935 	if (tag_len < sizeof(*stat_buf))
2936 		return;
2937 
2938 	dword_lock = le32_get_bits(stat_buf->info2,
2939 				   ATH12K_HTT_DLPAGER_TOTAL_LOCK_PAGES_INFO2);
2940 	dword_unlock = le32_get_bits(stat_buf->info2,
2941 				     ATH12K_HTT_DLPAGER_TOTAL_FREE_PAGES_INFO2);
2942 
2943 	pg_locked = ATH12K_HTT_STATS_PAGE_LOCKED;
2944 	pg_unlock = ATH12K_HTT_STATS_PAGE_UNLOCKED;
2945 
2946 	len += scnprintf(buf + len, buf_len - len, "HTT_DLPAGER_STATS_TLV:\n");
2947 	len += scnprintf(buf + len, buf_len - len, "ASYNC locked pages = %u\n",
2948 			 le32_get_bits(stat_buf->info0,
2949 				       ATH12K_HTT_DLPAGER_ASYNC_LOCK_PG_CNT_INFO0));
2950 	len += scnprintf(buf + len, buf_len - len, "SYNC locked pages = %u\n",
2951 			 le32_get_bits(stat_buf->info0,
2952 				       ATH12K_HTT_DLPAGER_SYNC_LOCK_PG_CNT_INFO0));
2953 	len += scnprintf(buf + len, buf_len - len, "Total locked pages = %u\n",
2954 			 le32_get_bits(stat_buf->info1,
2955 				       ATH12K_HTT_DLPAGER_TOTAL_LOCK_PAGES_INFO1));
2956 	len += scnprintf(buf + len, buf_len - len, "Total free pages = %u\n",
2957 			 le32_get_bits(stat_buf->info1,
2958 				       ATH12K_HTT_DLPAGER_TOTAL_FREE_PAGES_INFO1));
2959 
2960 	len += scnprintf(buf + len, buf_len - len, "\nLOCKED PAGES HISTORY\n");
2961 	len += scnprintf(buf + len, buf_len - len, "last_locked_page_idx = %u\n",
2962 			 dword_lock ? dword_lock - 1 : (ATH12K_PAGER_MAX - 1));
2963 
2964 	for (i = 0; i < ATH12K_PAGER_MAX; i++) {
2965 		memset(str_buf, 0x0, ATH12K_HTT_MAX_STRING_LEN);
2966 		ath12k_htt_print_dlpager_entry(&stat_buf->pgs_info[pg_locked][i],
2967 					       i, str_buf);
2968 		len += scnprintf(buf + len, buf_len - len, "%s", str_buf);
2969 	}
2970 
2971 	len += scnprintf(buf + len, buf_len - len, "\nUNLOCKED PAGES HISTORY\n");
2972 	len += scnprintf(buf + len, buf_len - len, "last_unlocked_page_idx = %u\n",
2973 			 dword_unlock ? dword_unlock - 1 : ATH12K_PAGER_MAX - 1);
2974 
2975 	for (i = 0; i < ATH12K_PAGER_MAX; i++) {
2976 		memset(str_buf, 0x0, ATH12K_HTT_MAX_STRING_LEN);
2977 		ath12k_htt_print_dlpager_entry(&stat_buf->pgs_info[pg_unlock][i],
2978 					       i, str_buf);
2979 		len += scnprintf(buf + len, buf_len - len, "%s", str_buf);
2980 	}
2981 
2982 	len += scnprintf(buf + len, buf_len - len, "\n");
2983 
2984 	stats_req->buf_len = len;
2985 }
2986 
2987 static void
ath12k_htt_print_phy_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2988 ath12k_htt_print_phy_stats_tlv(const void *tag_buf, u16 tag_len,
2989 			       struct debug_htt_stats_req *stats_req)
2990 {
2991 	const struct ath12k_htt_phy_stats_tlv *htt_stats_buf = tag_buf;
2992 	u32 len = stats_req->buf_len;
2993 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2994 	u8 *buf = stats_req->buf, i;
2995 
2996 	if (tag_len < sizeof(*htt_stats_buf))
2997 		return;
2998 
2999 	len += scnprintf(buf + len, buf_len - len, "HTT_PHY_STATS_TLV:\n");
3000 	for (i = 0; i < ATH12K_HTT_STATS_MAX_CHAINS; i++)
3001 		len += scnprintf(buf + len, buf_len - len, "bdf_nf_chain[%d] = %d\n",
3002 				 i, a_sle32_to_cpu(htt_stats_buf->nf_chain[i]));
3003 	for (i = 0; i < ATH12K_HTT_STATS_MAX_CHAINS; i++)
3004 		len += scnprintf(buf + len, buf_len - len, "runtime_nf_chain[%d] = %d\n",
3005 				 i, a_sle32_to_cpu(htt_stats_buf->runtime_nf_chain[i]));
3006 	len += scnprintf(buf + len, buf_len - len, "false_radar_cnt = %u / %u (mins)\n",
3007 			 le32_to_cpu(htt_stats_buf->false_radar_cnt),
3008 			 le32_to_cpu(htt_stats_buf->fw_run_time));
3009 	len += scnprintf(buf + len, buf_len - len, "radar_cs_cnt = %u\n",
3010 			 le32_to_cpu(htt_stats_buf->radar_cs_cnt));
3011 	len += scnprintf(buf + len, buf_len - len, "ani_level = %d\n\n",
3012 			 a_sle32_to_cpu(htt_stats_buf->ani_level));
3013 
3014 	stats_req->buf_len = len;
3015 }
3016 
3017 static void
ath12k_htt_print_phy_counters_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3018 ath12k_htt_print_phy_counters_tlv(const void *tag_buf, u16 tag_len,
3019 				  struct debug_htt_stats_req *stats_req)
3020 {
3021 	const struct ath12k_htt_phy_counters_tlv *htt_stats_buf = tag_buf;
3022 	u32 len = stats_req->buf_len;
3023 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3024 	u8 *buf = stats_req->buf;
3025 
3026 	if (tag_len < sizeof(*htt_stats_buf))
3027 		return;
3028 
3029 	len += scnprintf(buf + len, buf_len - len, "HTT_PHY_COUNTERS_TLV:\n");
3030 	len += scnprintf(buf + len, buf_len - len, "rx_ofdma_timing_err_cnt = %u\n",
3031 			 le32_to_cpu(htt_stats_buf->rx_ofdma_timing_err_cnt));
3032 	len += scnprintf(buf + len, buf_len - len, "rx_cck_fail_cnt = %u\n",
3033 			 le32_to_cpu(htt_stats_buf->rx_cck_fail_cnt));
3034 	len += scnprintf(buf + len, buf_len - len, "mactx_abort_cnt = %u\n",
3035 			 le32_to_cpu(htt_stats_buf->mactx_abort_cnt));
3036 	len += scnprintf(buf + len, buf_len - len, "macrx_abort_cnt = %u\n",
3037 			 le32_to_cpu(htt_stats_buf->macrx_abort_cnt));
3038 	len += scnprintf(buf + len, buf_len - len, "phytx_abort_cnt = %u\n",
3039 			 le32_to_cpu(htt_stats_buf->phytx_abort_cnt));
3040 	len += scnprintf(buf + len, buf_len - len, "phyrx_abort_cnt = %u\n",
3041 			 le32_to_cpu(htt_stats_buf->phyrx_abort_cnt));
3042 	len += scnprintf(buf + len, buf_len - len, "phyrx_defer_abort_cnt = %u\n",
3043 			 le32_to_cpu(htt_stats_buf->phyrx_defer_abort_cnt));
3044 	len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_lstf_event_cnt = %u\n",
3045 			 le32_to_cpu(htt_stats_buf->rx_gain_adj_lstf_event_cnt));
3046 	len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_non_legacy_cnt = %u\n",
3047 			 le32_to_cpu(htt_stats_buf->rx_gain_adj_non_legacy_cnt));
3048 	len += print_array_to_buf(buf, len, "rx_pkt_cnt", htt_stats_buf->rx_pkt_cnt,
3049 				  ATH12K_HTT_MAX_RX_PKT_CNT, "\n");
3050 	len += print_array_to_buf(buf, len, "rx_pkt_crc_pass_cnt",
3051 				  htt_stats_buf->rx_pkt_crc_pass_cnt,
3052 				  ATH12K_HTT_MAX_RX_PKT_CRC_PASS_CNT, "\n");
3053 	len += print_array_to_buf(buf, len, "per_blk_err_cnt",
3054 				  htt_stats_buf->per_blk_err_cnt,
3055 				  ATH12K_HTT_MAX_PER_BLK_ERR_CNT, "\n");
3056 	len += print_array_to_buf(buf, len, "rx_ota_err_cnt",
3057 				  htt_stats_buf->rx_ota_err_cnt,
3058 				  ATH12K_HTT_MAX_RX_OTA_ERR_CNT, "\n\n");
3059 
3060 	stats_req->buf_len = len;
3061 }
3062 
3063 static void
ath12k_htt_print_phy_reset_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3064 ath12k_htt_print_phy_reset_stats_tlv(const void *tag_buf, u16 tag_len,
3065 				     struct debug_htt_stats_req *stats_req)
3066 {
3067 	const struct ath12k_htt_phy_reset_stats_tlv *htt_stats_buf = tag_buf;
3068 	u32 len = stats_req->buf_len;
3069 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3070 	u8 *buf = stats_req->buf;
3071 
3072 	if (tag_len < sizeof(*htt_stats_buf))
3073 		return;
3074 
3075 	len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_STATS_TLV:\n");
3076 	len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3077 			 le32_to_cpu(htt_stats_buf->pdev_id));
3078 	len += scnprintf(buf + len, buf_len - len, "chan_mhz = %u\n",
3079 			 le32_to_cpu(htt_stats_buf->chan_mhz));
3080 	len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq1 = %u\n",
3081 			 le32_to_cpu(htt_stats_buf->chan_band_center_freq1));
3082 	len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq2 = %u\n",
3083 			 le32_to_cpu(htt_stats_buf->chan_band_center_freq2));
3084 	len += scnprintf(buf + len, buf_len - len, "chan_phy_mode = %u\n",
3085 			 le32_to_cpu(htt_stats_buf->chan_phy_mode));
3086 	len += scnprintf(buf + len, buf_len - len, "chan_flags = 0x%0x\n",
3087 			 le32_to_cpu(htt_stats_buf->chan_flags));
3088 	len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
3089 			 le32_to_cpu(htt_stats_buf->chan_num));
3090 	len += scnprintf(buf + len, buf_len - len, "reset_cause = 0x%0x\n",
3091 			 le32_to_cpu(htt_stats_buf->reset_cause));
3092 	len += scnprintf(buf + len, buf_len - len, "prev_reset_cause = 0x%0x\n",
3093 			 le32_to_cpu(htt_stats_buf->prev_reset_cause));
3094 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_src = 0x%0x\n",
3095 			 le32_to_cpu(htt_stats_buf->phy_warm_reset_src));
3096 	len += scnprintf(buf + len, buf_len - len, "rx_gain_tbl_mode = %d\n",
3097 			 le32_to_cpu(htt_stats_buf->rx_gain_tbl_mode));
3098 	len += scnprintf(buf + len, buf_len - len, "xbar_val = 0x%0x\n",
3099 			 le32_to_cpu(htt_stats_buf->xbar_val));
3100 	len += scnprintf(buf + len, buf_len - len, "force_calibration = %u\n",
3101 			 le32_to_cpu(htt_stats_buf->force_calibration));
3102 	len += scnprintf(buf + len, buf_len - len, "phyrf_mode = %u\n",
3103 			 le32_to_cpu(htt_stats_buf->phyrf_mode));
3104 	len += scnprintf(buf + len, buf_len - len, "phy_homechan = %u\n",
3105 			 le32_to_cpu(htt_stats_buf->phy_homechan));
3106 	len += scnprintf(buf + len, buf_len - len, "phy_tx_ch_mask = 0x%0x\n",
3107 			 le32_to_cpu(htt_stats_buf->phy_tx_ch_mask));
3108 	len += scnprintf(buf + len, buf_len - len, "phy_rx_ch_mask = 0x%0x\n",
3109 			 le32_to_cpu(htt_stats_buf->phy_rx_ch_mask));
3110 	len += scnprintf(buf + len, buf_len - len, "phybb_ini_mask = 0x%0x\n",
3111 			 le32_to_cpu(htt_stats_buf->phybb_ini_mask));
3112 	len += scnprintf(buf + len, buf_len - len, "phyrf_ini_mask = 0x%0x\n",
3113 			 le32_to_cpu(htt_stats_buf->phyrf_ini_mask));
3114 	len += scnprintf(buf + len, buf_len - len, "phy_dfs_en_mask = 0x%0x\n",
3115 			 le32_to_cpu(htt_stats_buf->phy_dfs_en_mask));
3116 	len += scnprintf(buf + len, buf_len - len, "phy_sscan_en_mask = 0x%0x\n",
3117 			 le32_to_cpu(htt_stats_buf->phy_sscan_en_mask));
3118 	len += scnprintf(buf + len, buf_len - len, "phy_synth_sel_mask = 0x%0x\n",
3119 			 le32_to_cpu(htt_stats_buf->phy_synth_sel_mask));
3120 	len += scnprintf(buf + len, buf_len - len, "phy_adfs_freq = %u\n",
3121 			 le32_to_cpu(htt_stats_buf->phy_adfs_freq));
3122 	len += scnprintf(buf + len, buf_len - len, "cck_fir_settings = 0x%0x\n",
3123 			 le32_to_cpu(htt_stats_buf->cck_fir_settings));
3124 	len += scnprintf(buf + len, buf_len - len, "phy_dyn_pri_chan = %u\n",
3125 			 le32_to_cpu(htt_stats_buf->phy_dyn_pri_chan));
3126 	len += scnprintf(buf + len, buf_len - len, "cca_thresh = 0x%0x\n",
3127 			 le32_to_cpu(htt_stats_buf->cca_thresh));
3128 	len += scnprintf(buf + len, buf_len - len, "dyn_cca_status = %u\n",
3129 			 le32_to_cpu(htt_stats_buf->dyn_cca_status));
3130 	len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_hw = 0x%x\n",
3131 			 le32_to_cpu(htt_stats_buf->rxdesense_thresh_hw));
3132 	len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_sw = 0x%x\n\n",
3133 			 le32_to_cpu(htt_stats_buf->rxdesense_thresh_sw));
3134 
3135 	stats_req->buf_len = len;
3136 }
3137 
3138 static void
ath12k_htt_print_phy_reset_counters_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3139 ath12k_htt_print_phy_reset_counters_tlv(const void *tag_buf, u16 tag_len,
3140 					struct debug_htt_stats_req *stats_req)
3141 {
3142 	const struct ath12k_htt_phy_reset_counters_tlv *htt_stats_buf = tag_buf;
3143 	u32 len = stats_req->buf_len;
3144 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3145 	u8 *buf = stats_req->buf;
3146 
3147 	if (tag_len < sizeof(*htt_stats_buf))
3148 		return;
3149 
3150 	len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_COUNTERS_TLV:\n");
3151 	len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3152 			 le32_to_cpu(htt_stats_buf->pdev_id));
3153 	len += scnprintf(buf + len, buf_len - len, "cf_active_low_fail_cnt = %u\n",
3154 			 le32_to_cpu(htt_stats_buf->cf_active_low_fail_cnt));
3155 	len += scnprintf(buf + len, buf_len - len, "cf_active_low_pass_cnt = %u\n",
3156 			 le32_to_cpu(htt_stats_buf->cf_active_low_pass_cnt));
3157 	len += scnprintf(buf + len, buf_len - len, "phy_off_through_vreg_cnt = %u\n",
3158 			 le32_to_cpu(htt_stats_buf->phy_off_through_vreg_cnt));
3159 	len += scnprintf(buf + len, buf_len - len, "force_calibration_cnt = %u\n",
3160 			 le32_to_cpu(htt_stats_buf->force_calibration_cnt));
3161 	len += scnprintf(buf + len, buf_len - len, "rf_mode_switch_phy_off_cnt = %u\n",
3162 			 le32_to_cpu(htt_stats_buf->rf_mode_switch_phy_off_cnt));
3163 	len += scnprintf(buf + len, buf_len - len, "temperature_recal_cnt = %u\n\n",
3164 			 le32_to_cpu(htt_stats_buf->temperature_recal_cnt));
3165 
3166 	stats_req->buf_len = len;
3167 }
3168 
3169 static void
ath12k_htt_print_phy_tpc_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3170 ath12k_htt_print_phy_tpc_stats_tlv(const void *tag_buf, u16 tag_len,
3171 				   struct debug_htt_stats_req *stats_req)
3172 {
3173 	const struct ath12k_htt_phy_tpc_stats_tlv *htt_stats_buf = tag_buf;
3174 	u32 len = stats_req->buf_len;
3175 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3176 	u8 *buf = stats_req->buf;
3177 
3178 	if (tag_len < sizeof(*htt_stats_buf))
3179 		return;
3180 
3181 	len += scnprintf(buf + len, buf_len - len, "HTT_PHY_TPC_STATS_TLV:\n");
3182 	len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3183 			 le32_to_cpu(htt_stats_buf->pdev_id));
3184 	len += scnprintf(buf + len, buf_len - len, "tx_power_scale = %u\n",
3185 			 le32_to_cpu(htt_stats_buf->tx_power_scale));
3186 	len += scnprintf(buf + len, buf_len - len, "tx_power_scale_db = %u\n",
3187 			 le32_to_cpu(htt_stats_buf->tx_power_scale_db));
3188 	len += scnprintf(buf + len, buf_len - len, "min_negative_tx_power = %d\n",
3189 			 le32_to_cpu(htt_stats_buf->min_negative_tx_power));
3190 	len += scnprintf(buf + len, buf_len - len, "reg_ctl_domain = %u\n",
3191 			 le32_to_cpu(htt_stats_buf->reg_ctl_domain));
3192 	len += scnprintf(buf + len, buf_len - len, "twice_max_rd_power = %u\n",
3193 			 le32_to_cpu(htt_stats_buf->twice_max_rd_power));
3194 	len += scnprintf(buf + len, buf_len - len, "max_tx_power = %u\n",
3195 			 le32_to_cpu(htt_stats_buf->max_tx_power));
3196 	len += scnprintf(buf + len, buf_len - len, "home_max_tx_power = %u\n",
3197 			 le32_to_cpu(htt_stats_buf->home_max_tx_power));
3198 	len += scnprintf(buf + len, buf_len - len, "psd_power = %d\n",
3199 			 le32_to_cpu(htt_stats_buf->psd_power));
3200 	len += scnprintf(buf + len, buf_len - len, "eirp_power = %u\n",
3201 			 le32_to_cpu(htt_stats_buf->eirp_power));
3202 	len += scnprintf(buf + len, buf_len - len, "power_type_6ghz = %u\n",
3203 			 le32_to_cpu(htt_stats_buf->power_type_6ghz));
3204 	len += print_array_to_buf(buf, len, "max_reg_allowed_power",
3205 				  htt_stats_buf->max_reg_allowed_power,
3206 				  ATH12K_HTT_STATS_MAX_CHAINS, "\n");
3207 	len += print_array_to_buf(buf, len, "max_reg_allowed_power_6ghz",
3208 				  htt_stats_buf->max_reg_allowed_power_6ghz,
3209 				  ATH12K_HTT_STATS_MAX_CHAINS, "\n");
3210 	len += print_array_to_buf(buf, len, "sub_band_cfreq",
3211 				  htt_stats_buf->sub_band_cfreq,
3212 				  ATH12K_HTT_MAX_CH_PWR_INFO_SIZE, "\n");
3213 	len += print_array_to_buf(buf, len, "sub_band_txpower",
3214 				  htt_stats_buf->sub_band_txpower,
3215 				  ATH12K_HTT_MAX_CH_PWR_INFO_SIZE, "\n\n");
3216 
3217 	stats_req->buf_len = len;
3218 }
3219 
3220 static void
ath12k_htt_print_soc_txrx_stats_common_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3221 ath12k_htt_print_soc_txrx_stats_common_tlv(const void *tag_buf, u16 tag_len,
3222 					   struct debug_htt_stats_req *stats_req)
3223 {
3224 	const struct ath12k_htt_t2h_soc_txrx_stats_common_tlv *htt_stats_buf = tag_buf;
3225 	u64 drop_count;
3226 	u32 len = stats_req->buf_len;
3227 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3228 	u8 *buf = stats_req->buf;
3229 
3230 	if (tag_len < sizeof(*htt_stats_buf))
3231 		return;
3232 
3233 	drop_count = ath12k_le32hilo_to_u64(htt_stats_buf->inv_peers_msdu_drop_count_hi,
3234 					    htt_stats_buf->inv_peers_msdu_drop_count_lo);
3235 
3236 	len += scnprintf(buf + len, buf_len - len, "HTT_SOC_COMMON_STATS_TLV:\n");
3237 	len += scnprintf(buf + len, buf_len - len, "soc_drop_count = %llu\n\n",
3238 			 drop_count);
3239 
3240 	stats_req->buf_len = len;
3241 }
3242 
3243 static void
ath12k_htt_print_tx_per_rate_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3244 ath12k_htt_print_tx_per_rate_stats_tlv(const void *tag_buf, u16 tag_len,
3245 				       struct debug_htt_stats_req *stats_req)
3246 {
3247 	const struct ath12k_htt_tx_per_rate_stats_tlv *stats_buf = tag_buf;
3248 	u32 len = stats_req->buf_len;
3249 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3250 	u32 ru_size_cnt = 0;
3251 	u32 rc_mode, ru_type;
3252 	u8 *buf = stats_req->buf, i;
3253 	const char *mode_prefix;
3254 
3255 	if (tag_len < sizeof(*stats_buf))
3256 		return;
3257 
3258 	rc_mode = le32_to_cpu(stats_buf->rc_mode);
3259 	ru_type = le32_to_cpu(stats_buf->ru_type);
3260 
3261 	switch (rc_mode) {
3262 	case ATH12K_HTT_STATS_RC_MODE_DLSU:
3263 		len += scnprintf(buf + len, buf_len - len, "HTT_TX_PER_STATS:\n");
3264 		len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_SU:\n");
3265 		mode_prefix = "su";
3266 		break;
3267 	case ATH12K_HTT_STATS_RC_MODE_DLMUMIMO:
3268 		len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_DL_MUMIMO:\n");
3269 		mode_prefix = "mu";
3270 		break;
3271 	case ATH12K_HTT_STATS_RC_MODE_DLOFDMA:
3272 		len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_DL_OFDMA:\n");
3273 		mode_prefix = "ofdma";
3274 		if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
3275 			ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_STATS_NUM_AX_RU_SIZE_CNTRS;
3276 		else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
3277 			ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS;
3278 		break;
3279 	case ATH12K_HTT_STATS_RC_MODE_ULMUMIMO:
3280 		len += scnprintf(buf + len, buf_len - len, "HTT_RX_PER_STATS:\n");
3281 		len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_UL_MUMIMO:\n");
3282 		mode_prefix = "ulmu";
3283 		break;
3284 	case ATH12K_HTT_STATS_RC_MODE_ULOFDMA:
3285 		len += scnprintf(buf + len, buf_len - len, "\nPER_STATS_UL_OFDMA:\n");
3286 		mode_prefix = "ulofdma";
3287 		if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_RU_ONLY)
3288 			ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_STATS_NUM_AX_RU_SIZE_CNTRS;
3289 		else if (ru_type == ATH12K_HTT_STATS_RU_TYPE_SINGLE_AND_MULTI_RU)
3290 			ru_size_cnt = ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS;
3291 		break;
3292 	default:
3293 		return;
3294 	}
3295 
3296 	len += scnprintf(buf + len, buf_len - len, "\nPER per BW:\n");
3297 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3298 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3299 		len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
3300 				 mode_prefix);
3301 	else
3302 		len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
3303 				 mode_prefix);
3304 	for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
3305 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3306 				 le32_to_cpu(stats_buf->per_bw[i].ppdus_tried));
3307 	len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
3308 			 le32_to_cpu(stats_buf->per_bw320.ppdus_tried));
3309 
3310 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3311 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3312 		len += scnprintf(buf + len, buf_len - len, "non_data_ppdus_%s = ",
3313 				 mode_prefix);
3314 	else
3315 		len += scnprintf(buf + len, buf_len - len, "ppdus_ack_failed_%s = ",
3316 				 mode_prefix);
3317 	for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
3318 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3319 				 le32_to_cpu(stats_buf->per_bw[i].ppdus_ack_failed));
3320 	len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
3321 			 le32_to_cpu(stats_buf->per_bw320.ppdus_ack_failed));
3322 
3323 	len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ", mode_prefix);
3324 	for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
3325 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3326 				 le32_to_cpu(stats_buf->per_bw[i].mpdus_tried));
3327 	len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
3328 			 le32_to_cpu(stats_buf->per_bw320.mpdus_tried));
3329 
3330 	len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ", mode_prefix);
3331 	for (i = 0; i < ATH12K_HTT_TX_PDEV_STATS_NUM_BW_CNTRS; i++)
3332 		len += scnprintf(buf + len, buf_len - len, " %u:%u", i,
3333 				 le32_to_cpu(stats_buf->per_bw[i].mpdus_failed));
3334 	len += scnprintf(buf + len, buf_len - len, " %u:%u\n", i,
3335 			 le32_to_cpu(stats_buf->per_bw320.mpdus_failed));
3336 
3337 	len += scnprintf(buf + len, buf_len - len, "\nPER per NSS:\n");
3338 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3339 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3340 		len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
3341 				 mode_prefix);
3342 	else
3343 		len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
3344 				 mode_prefix);
3345 	for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
3346 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i + 1,
3347 				 le32_to_cpu(stats_buf->per_nss[i].ppdus_tried));
3348 	len += scnprintf(buf + len, buf_len - len, "\n");
3349 
3350 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3351 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3352 		len += scnprintf(buf + len, buf_len - len, "non_data_ppdus_%s = ",
3353 				 mode_prefix);
3354 	else
3355 		len += scnprintf(buf + len, buf_len - len, "ppdus_ack_failed_%s = ",
3356 				 mode_prefix);
3357 	for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
3358 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i + 1,
3359 				 le32_to_cpu(stats_buf->per_nss[i].ppdus_ack_failed));
3360 	len += scnprintf(buf + len, buf_len - len, "\n");
3361 
3362 	len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ", mode_prefix);
3363 	for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
3364 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i + 1,
3365 				 le32_to_cpu(stats_buf->per_nss[i].mpdus_tried));
3366 	len += scnprintf(buf + len, buf_len - len, "\n");
3367 
3368 	len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ", mode_prefix);
3369 	for (i = 0; i < ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS; i++)
3370 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i + 1,
3371 				 le32_to_cpu(stats_buf->per_nss[i].mpdus_failed));
3372 	len += scnprintf(buf + len, buf_len - len, "\n");
3373 
3374 	len += scnprintf(buf + len, buf_len - len, "\nPER per MCS:\n");
3375 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3376 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3377 		len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
3378 				 mode_prefix);
3379 	else
3380 		len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
3381 				 mode_prefix);
3382 	for (i = 0; i < ATH12K_HTT_TXBF_RATE_STAT_NUM_MCS_CNTRS; i++)
3383 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3384 				 le32_to_cpu(stats_buf->per_mcs[i].ppdus_tried));
3385 	len += scnprintf(buf + len, buf_len - len, "\n");
3386 
3387 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA ||
3388 	    rc_mode == ATH12K_HTT_STATS_RC_MODE_ULMUMIMO)
3389 		len += scnprintf(buf + len, buf_len - len, "non_data_ppdus_%s = ",
3390 				 mode_prefix);
3391 	else
3392 		len += scnprintf(buf + len, buf_len - len, "ppdus_ack_failed_%s = ",
3393 				 mode_prefix);
3394 	for (i = 0; i < ATH12K_HTT_TXBF_RATE_STAT_NUM_MCS_CNTRS; i++)
3395 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3396 				 le32_to_cpu(stats_buf->per_mcs[i].ppdus_ack_failed));
3397 	len += scnprintf(buf + len, buf_len - len, "\n");
3398 
3399 	len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ", mode_prefix);
3400 	for (i = 0; i < ATH12K_HTT_TXBF_RATE_STAT_NUM_MCS_CNTRS; i++)
3401 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3402 				 le32_to_cpu(stats_buf->per_mcs[i].mpdus_tried));
3403 	len += scnprintf(buf + len, buf_len - len, "\n");
3404 
3405 	len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ", mode_prefix);
3406 	for (i = 0; i < ATH12K_HTT_TXBF_RATE_STAT_NUM_MCS_CNTRS; i++)
3407 		len += scnprintf(buf + len, buf_len - len, " %u:%u ", i,
3408 				 le32_to_cpu(stats_buf->per_mcs[i].mpdus_failed));
3409 	len += scnprintf(buf + len, buf_len - len, "\n");
3410 
3411 	if ((rc_mode == ATH12K_HTT_STATS_RC_MODE_DLOFDMA ||
3412 	     rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA) &&
3413 	     ru_type != ATH12K_HTT_STATS_RU_TYPE_INVALID) {
3414 		len += scnprintf(buf + len, buf_len - len, "\nPER per RU:\n");
3415 
3416 		if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA)
3417 			len += scnprintf(buf + len, buf_len - len, "data_ppdus_%s = ",
3418 					 mode_prefix);
3419 		else
3420 			len += scnprintf(buf + len, buf_len - len, "ppdus_tried_%s = ",
3421 					 mode_prefix);
3422 		for (i = 0; i < ru_size_cnt; i++)
3423 			len += scnprintf(buf + len, buf_len - len, " %s:%u ",
3424 					 ath12k_tx_ru_size_to_str(ru_type, i),
3425 					 le32_to_cpu(stats_buf->ru[i].ppdus_tried));
3426 		len += scnprintf(buf + len, buf_len - len, "\n");
3427 
3428 		if (rc_mode == ATH12K_HTT_STATS_RC_MODE_ULOFDMA)
3429 			len += scnprintf(buf + len, buf_len - len,
3430 					 "non_data_ppdus_%s = ", mode_prefix);
3431 		else
3432 			len += scnprintf(buf + len, buf_len - len,
3433 					 "ppdus_ack_failed_%s = ", mode_prefix);
3434 		for (i = 0; i < ru_size_cnt; i++)
3435 			len += scnprintf(buf + len, buf_len - len, " %s:%u ",
3436 					 ath12k_tx_ru_size_to_str(ru_type, i),
3437 					 le32_to_cpu(stats_buf->ru[i].ppdus_ack_failed));
3438 		len += scnprintf(buf + len, buf_len - len, "\n");
3439 
3440 		len += scnprintf(buf + len, buf_len - len, "mpdus_tried_%s = ",
3441 				 mode_prefix);
3442 		for (i = 0; i < ru_size_cnt; i++)
3443 			len += scnprintf(buf + len, buf_len - len, " %s:%u ",
3444 					 ath12k_tx_ru_size_to_str(ru_type, i),
3445 					 le32_to_cpu(stats_buf->ru[i].mpdus_tried));
3446 		len += scnprintf(buf + len, buf_len - len, "\n");
3447 
3448 		len += scnprintf(buf + len, buf_len - len, "mpdus_failed_%s = ",
3449 				 mode_prefix);
3450 		for (i = 0; i < ru_size_cnt; i++)
3451 			len += scnprintf(buf + len, buf_len - len, " %s:%u ",
3452 					 ath12k_tx_ru_size_to_str(ru_type, i),
3453 					 le32_to_cpu(stats_buf->ru[i].mpdus_failed));
3454 		len += scnprintf(buf + len, buf_len - len, "\n\n");
3455 	}
3456 
3457 	if (rc_mode == ATH12K_HTT_STATS_RC_MODE_DLMUMIMO) {
3458 		len += scnprintf(buf + len, buf_len - len, "\nlast_probed_bw  = %u\n",
3459 				 le32_to_cpu(stats_buf->last_probed_bw));
3460 		len += scnprintf(buf + len, buf_len - len, "last_probed_nss = %u\n",
3461 				 le32_to_cpu(stats_buf->last_probed_nss));
3462 		len += scnprintf(buf + len, buf_len - len, "last_probed_mcs = %u\n",
3463 				 le32_to_cpu(stats_buf->last_probed_mcs));
3464 		len += print_array_to_buf(buf, len, "MU Probe count per RC MODE",
3465 					  stats_buf->probe_cnt,
3466 					  ATH12K_HTT_RC_MODE_2D_COUNT, "\n\n");
3467 	}
3468 
3469 	stats_req->buf_len = len;
3470 }
3471 
3472 static void
ath12k_htt_print_ast_entry_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3473 ath12k_htt_print_ast_entry_tlv(const void *tag_buf, u16 tag_len,
3474 			       struct debug_htt_stats_req *stats_req)
3475 {
3476 	const struct ath12k_htt_ast_entry_tlv *htt_stats_buf = tag_buf;
3477 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3478 	u32 len = stats_req->buf_len;
3479 	u8 *buf = stats_req->buf;
3480 	u32 mac_addr_l32;
3481 	u32 mac_addr_h16;
3482 	u32 ast_info;
3483 
3484 	if (tag_len < sizeof(*htt_stats_buf))
3485 		return;
3486 
3487 	mac_addr_l32 = le32_to_cpu(htt_stats_buf->mac_addr.mac_addr_l32);
3488 	mac_addr_h16 = le32_to_cpu(htt_stats_buf->mac_addr.mac_addr_h16);
3489 	ast_info = le32_to_cpu(htt_stats_buf->info);
3490 
3491 	len += scnprintf(buf + len, buf_len - len, "HTT_AST_ENTRY_TLV:\n");
3492 	len += scnprintf(buf + len, buf_len - len, "ast_index = %u\n",
3493 			 le32_to_cpu(htt_stats_buf->ast_index));
3494 	len += scnprintf(buf + len, buf_len - len,
3495 			 "mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
3496 			 u32_get_bits(mac_addr_l32, ATH12K_HTT_MAC_ADDR_L32_0),
3497 			 u32_get_bits(mac_addr_l32, ATH12K_HTT_MAC_ADDR_L32_1),
3498 			 u32_get_bits(mac_addr_l32, ATH12K_HTT_MAC_ADDR_L32_2),
3499 			 u32_get_bits(mac_addr_l32, ATH12K_HTT_MAC_ADDR_L32_3),
3500 			 u32_get_bits(mac_addr_h16, ATH12K_HTT_MAC_ADDR_H16_0),
3501 			 u32_get_bits(mac_addr_h16, ATH12K_HTT_MAC_ADDR_H16_1));
3502 
3503 	len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
3504 			 le32_to_cpu(htt_stats_buf->sw_peer_id));
3505 	len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3506 			 u32_get_bits(ast_info, ATH12K_HTT_AST_PDEV_ID_INFO));
3507 	len += scnprintf(buf + len, buf_len - len, "vdev_id = %u\n",
3508 			 u32_get_bits(ast_info, ATH12K_HTT_AST_VDEV_ID_INFO));
3509 	len += scnprintf(buf + len, buf_len - len, "next_hop = %u\n",
3510 			 u32_get_bits(ast_info, ATH12K_HTT_AST_NEXT_HOP_INFO));
3511 	len += scnprintf(buf + len, buf_len - len, "mcast = %u\n",
3512 			 u32_get_bits(ast_info, ATH12K_HTT_AST_MCAST_INFO));
3513 	len += scnprintf(buf + len, buf_len - len, "monitor_direct = %u\n",
3514 			 u32_get_bits(ast_info, ATH12K_HTT_AST_MONITOR_DIRECT_INFO));
3515 	len += scnprintf(buf + len, buf_len - len, "mesh_sta = %u\n",
3516 			 u32_get_bits(ast_info, ATH12K_HTT_AST_MESH_STA_INFO));
3517 	len += scnprintf(buf + len, buf_len - len, "mec = %u\n",
3518 			 u32_get_bits(ast_info, ATH12K_HTT_AST_MEC_INFO));
3519 	len += scnprintf(buf + len, buf_len - len, "intra_bss = %u\n\n",
3520 			 u32_get_bits(ast_info, ATH12K_HTT_AST_INTRA_BSS_INFO));
3521 
3522 	stats_req->buf_len = len;
3523 }
3524 
3525 static const char*
ath12k_htt_get_punct_dir_type_str(enum ath12k_htt_stats_direction direction)3526 ath12k_htt_get_punct_dir_type_str(enum ath12k_htt_stats_direction direction)
3527 {
3528 	switch (direction) {
3529 	case ATH12K_HTT_STATS_DIRECTION_TX:
3530 		return "tx";
3531 	case ATH12K_HTT_STATS_DIRECTION_RX:
3532 		return "rx";
3533 	default:
3534 		return "unknown";
3535 	}
3536 }
3537 
3538 static const char*
ath12k_htt_get_punct_ppdu_type_str(enum ath12k_htt_stats_ppdu_type ppdu_type)3539 ath12k_htt_get_punct_ppdu_type_str(enum ath12k_htt_stats_ppdu_type ppdu_type)
3540 {
3541 	switch (ppdu_type) {
3542 	case ATH12K_HTT_STATS_PPDU_TYPE_MODE_SU:
3543 		return "su";
3544 	case ATH12K_HTT_STATS_PPDU_TYPE_DL_MU_MIMO:
3545 		return "dl_mu_mimo";
3546 	case ATH12K_HTT_STATS_PPDU_TYPE_UL_MU_MIMO:
3547 		return "ul_mu_mimo";
3548 	case ATH12K_HTT_STATS_PPDU_TYPE_DL_MU_OFDMA:
3549 		return "dl_mu_ofdma";
3550 	case ATH12K_HTT_STATS_PPDU_TYPE_UL_MU_OFDMA:
3551 		return "ul_mu_ofdma";
3552 	default:
3553 		return "unknown";
3554 	}
3555 }
3556 
3557 static const char*
ath12k_htt_get_punct_pream_type_str(enum ath12k_htt_stats_param_type pream_type)3558 ath12k_htt_get_punct_pream_type_str(enum ath12k_htt_stats_param_type pream_type)
3559 {
3560 	switch (pream_type) {
3561 	case ATH12K_HTT_STATS_PREAM_OFDM:
3562 		return "ofdm";
3563 	case ATH12K_HTT_STATS_PREAM_CCK:
3564 		return "cck";
3565 	case ATH12K_HTT_STATS_PREAM_HT:
3566 		return "ht";
3567 	case ATH12K_HTT_STATS_PREAM_VHT:
3568 		return "ac";
3569 	case ATH12K_HTT_STATS_PREAM_HE:
3570 		return "ax";
3571 	case ATH12K_HTT_STATS_PREAM_EHT:
3572 		return "be";
3573 	default:
3574 		return "unknown";
3575 	}
3576 }
3577 
3578 static void
ath12k_htt_print_puncture_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3579 ath12k_htt_print_puncture_stats_tlv(const void *tag_buf, u16 tag_len,
3580 				    struct debug_htt_stats_req *stats_req)
3581 {
3582 	const struct ath12k_htt_pdev_puncture_stats_tlv *stats_buf = tag_buf;
3583 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3584 	u32 len = stats_req->buf_len;
3585 	u8 *buf = stats_req->buf;
3586 	const char *direction;
3587 	const char *ppdu_type;
3588 	const char *preamble;
3589 	u32 mac_id__word;
3590 	u32 subband_limit;
3591 	u8 i;
3592 
3593 	if (tag_len < sizeof(*stats_buf))
3594 		return;
3595 
3596 	mac_id__word = le32_to_cpu(stats_buf->mac_id__word);
3597 	subband_limit = min(le32_to_cpu(stats_buf->subband_cnt),
3598 			    ATH12K_HTT_PUNCT_STATS_MAX_SUBBAND_CNT);
3599 
3600 	direction = ath12k_htt_get_punct_dir_type_str(le32_to_cpu(stats_buf->direction));
3601 	ppdu_type = ath12k_htt_get_punct_ppdu_type_str(le32_to_cpu(stats_buf->ppdu_type));
3602 	preamble = ath12k_htt_get_punct_pream_type_str(le32_to_cpu(stats_buf->preamble));
3603 
3604 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_PUNCTURE_STATS_TLV:\n");
3605 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
3606 			 u32_get_bits(mac_id__word, ATH12K_HTT_STATS_MAC_ID));
3607 	len += scnprintf(buf + len, buf_len - len,
3608 			 "%s_%s_%s_last_used_pattern_mask = 0x%08x\n",
3609 			 direction, preamble, ppdu_type,
3610 			 le32_to_cpu(stats_buf->last_used_pattern_mask));
3611 
3612 	for (i = 0; i < subband_limit; i++) {
3613 		len += scnprintf(buf + len, buf_len - len,
3614 				 "%s_%s_%s_num_subbands_used_cnt_%02d = %u\n",
3615 				 direction, preamble, ppdu_type, i + 1,
3616 				 le32_to_cpu(stats_buf->num_subbands_used_cnt[i]));
3617 	}
3618 	len += scnprintf(buf + len, buf_len - len, "\n");
3619 
3620 	stats_req->buf_len = len;
3621 }
3622 
3623 static void
ath12k_htt_print_dmac_reset_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3624 ath12k_htt_print_dmac_reset_stats_tlv(const void *tag_buf, u16 tag_len,
3625 				      struct debug_htt_stats_req *stats_req)
3626 {
3627 	const struct ath12k_htt_dmac_reset_stats_tlv *htt_stats_buf = tag_buf;
3628 	u8 *buf = stats_req->buf;
3629 	u32 len = stats_req->buf_len;
3630 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3631 	u64 time;
3632 
3633 	if (tag_len < sizeof(*htt_stats_buf))
3634 		return;
3635 
3636 	len += scnprintf(buf + len, buf_len - len, "HTT_DMAC_RESET_STATS_TLV:\n");
3637 	len += scnprintf(buf + len, buf_len - len, "reset_count = %u\n",
3638 			 le32_to_cpu(htt_stats_buf->reset_count));
3639 	time = ath12k_le32hilo_to_u64(htt_stats_buf->reset_time_hi_ms,
3640 				      htt_stats_buf->reset_time_lo_ms);
3641 	len += scnprintf(buf + len, buf_len - len, "reset_time_ms = %llu\n", time);
3642 	time = ath12k_le32hilo_to_u64(htt_stats_buf->disengage_time_hi_ms,
3643 				      htt_stats_buf->disengage_time_lo_ms);
3644 	len += scnprintf(buf + len, buf_len - len, "disengage_time_ms = %llu\n", time);
3645 
3646 	time = ath12k_le32hilo_to_u64(htt_stats_buf->engage_time_hi_ms,
3647 				      htt_stats_buf->engage_time_lo_ms);
3648 	len += scnprintf(buf + len, buf_len - len, "engage_time_ms = %llu\n", time);
3649 
3650 	len += scnprintf(buf + len, buf_len - len, "disengage_count = %u\n",
3651 			 le32_to_cpu(htt_stats_buf->disengage_count));
3652 	len += scnprintf(buf + len, buf_len - len, "engage_count = %u\n",
3653 			 le32_to_cpu(htt_stats_buf->engage_count));
3654 	len += scnprintf(buf + len, buf_len - len, "drain_dest_ring_mask = 0x%x\n\n",
3655 			 le32_to_cpu(htt_stats_buf->drain_dest_ring_mask));
3656 
3657 	stats_req->buf_len = len;
3658 }
3659 
3660 static void
ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3661 ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(const void *tag_buf, u16 tag_len,
3662 						 struct debug_htt_stats_req *stats_req)
3663 {
3664 	const struct ath12k_htt_pdev_sched_algo_ofdma_stats_tlv *htt_stats_buf = tag_buf;
3665 	u8 *buf = stats_req->buf;
3666 	u32 len = stats_req->buf_len;
3667 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3668 	u32 mac_id_word;
3669 
3670 	if (tag_len < sizeof(*htt_stats_buf))
3671 		return;
3672 
3673 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
3674 
3675 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_SCHED_ALGO_TLV:\n");
3676 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
3677 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
3678 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_enabled_count",
3679 				  htt_stats_buf->rate_based_dlofdma_enabled_cnt,
3680 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3681 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_disabled_count",
3682 				  htt_stats_buf->rate_based_dlofdma_disabled_cnt,
3683 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3684 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_probing_count",
3685 				  htt_stats_buf->rate_based_dlofdma_disabled_cnt,
3686 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3687 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_monitoring_count",
3688 				  htt_stats_buf->rate_based_dlofdma_monitor_cnt,
3689 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3690 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_enabled_count",
3691 				  htt_stats_buf->chan_acc_lat_based_dlofdma_enabled_cnt,
3692 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3693 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_disabled_count",
3694 				  htt_stats_buf->chan_acc_lat_based_dlofdma_disabled_cnt,
3695 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3696 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_monitoring_count",
3697 				  htt_stats_buf->chan_acc_lat_based_dlofdma_monitor_cnt,
3698 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3699 	len += print_array_to_buf(buf, len, "downgrade_to_dl_su_ru_alloc_fail",
3700 				  htt_stats_buf->downgrade_to_dl_su_ru_alloc_fail,
3701 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3702 	len += print_array_to_buf(buf, len, "candidate_list_single_user_disable_ofdma",
3703 				  htt_stats_buf->candidate_list_single_user_disable_ofdma,
3704 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3705 	len += print_array_to_buf(buf, len, "dl_cand_list_dropped_high_ul_qos_weight",
3706 				  htt_stats_buf->dl_cand_list_dropped_high_ul_qos_weight,
3707 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3708 	len += print_array_to_buf(buf, len, "ax_dlofdma_disabled_due_to_pipelining",
3709 				  htt_stats_buf->ax_dlofdma_disabled_due_to_pipelining,
3710 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3711 	len += print_array_to_buf(buf, len, "dlofdma_disabled_su_only_eligible",
3712 				  htt_stats_buf->dlofdma_disabled_su_only_eligible,
3713 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3714 	len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_tried",
3715 				  htt_stats_buf->dlofdma_disabled_consec_no_mpdus_tried,
3716 				  ATH12K_HTT_NUM_AC_WMM, "\n");
3717 	len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_success",
3718 				  htt_stats_buf->dlofdma_disabled_consec_no_mpdus_success,
3719 				  ATH12K_HTT_NUM_AC_WMM, "\n\n");
3720 
3721 	stats_req->buf_len = len;
3722 }
3723 
3724 static void
ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3725 ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(const void *tag_buf, u16 tag_len,
3726 						 struct debug_htt_stats_req *stats_req)
3727 {
3728 	const struct ath12k_htt_tx_pdev_rate_stats_be_ofdma_tlv *htt_stats_buf = tag_buf;
3729 	u8 *buf = stats_req->buf;
3730 	u32 len = stats_req->buf_len;
3731 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3732 	u32 mac_id_word;
3733 	u8 i;
3734 
3735 	if (tag_len < sizeof(*htt_stats_buf))
3736 		return;
3737 
3738 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
3739 
3740 	len += scnprintf(buf + len, buf_len - len,
3741 			 "HTT_TX_PDEV_RATE_STATS_BE_OFDMA_TLV:\n");
3742 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
3743 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
3744 	len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ldpc = %u\n",
3745 			 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ldpc));
3746 	len += print_array_to_buf(buf, len, "be_ofdma_tx_mcs",
3747 				  htt_stats_buf->be_ofdma_tx_mcs,
3748 				  ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
3749 	len += print_array_to_buf(buf, len, "be_ofdma_eht_sig_mcs",
3750 				  htt_stats_buf->be_ofdma_eht_sig_mcs,
3751 				  ATH12K_HTT_TX_PDEV_NUM_EHT_SIG_MCS_CNTRS, "\n");
3752 	len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ru_size = ");
3753 	for (i = 0; i < ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS; i++)
3754 		len += scnprintf(buf + len, buf_len - len, " %s:%u ",
3755 				 ath12k_htt_be_tx_rx_ru_size_to_str(i),
3756 				 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ru_size[i]));
3757 	len += scnprintf(buf + len, buf_len - len, "\n");
3758 	len += print_array_to_buf_index(buf, len, "be_ofdma_tx_nss = ", 1,
3759 					htt_stats_buf->be_ofdma_tx_nss,
3760 					ATH12K_HTT_PDEV_STAT_NUM_SPATIAL_STREAMS,
3761 					"\n");
3762 	len += print_array_to_buf(buf, len, "be_ofdma_tx_bw",
3763 				  htt_stats_buf->be_ofdma_tx_bw,
3764 				  ATH12K_HTT_TX_PDEV_NUM_BE_BW_CNTRS, "\n");
3765 	for (i = 0; i < ATH12K_HTT_TX_PDEV_NUM_GI_CNTRS; i++) {
3766 		len += scnprintf(buf + len, buf_len - len,
3767 				 "be_ofdma_tx_gi[%u]", i);
3768 		len += print_array_to_buf(buf, len, "", htt_stats_buf->gi[i],
3769 					  ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
3770 	}
3771 	len += scnprintf(buf + len, buf_len - len, "\n");
3772 
3773 	stats_req->buf_len = len;
3774 }
3775 
3776 static void
ath12k_htt_print_pdev_mbssid_ctrl_frame_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)3777 ath12k_htt_print_pdev_mbssid_ctrl_frame_stats_tlv(const void *tag_buf, u16 tag_len,
3778 						  struct debug_htt_stats_req *stats_req)
3779 {
3780 	const struct ath12k_htt_pdev_mbssid_ctrl_frame_tlv *htt_stats_buf = tag_buf;
3781 	u8 *buf = stats_req->buf;
3782 	u32 len = stats_req->buf_len;
3783 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
3784 	u32 mac_id_word;
3785 
3786 	if (tag_len < sizeof(*htt_stats_buf))
3787 		return;
3788 
3789 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
3790 
3791 	len += scnprintf(buf + len, buf_len - len, "HTT_MBSSID_CTRL_FRAME_STATS_TLV:\n");
3792 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
3793 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
3794 	len += scnprintf(buf + len, buf_len - len, "basic_trigger_across_bss = %u\n",
3795 			 le32_to_cpu(htt_stats_buf->basic_trigger_across_bss));
3796 	len += scnprintf(buf + len, buf_len - len, "basic_trigger_within_bss = %u\n",
3797 			 le32_to_cpu(htt_stats_buf->basic_trigger_within_bss));
3798 	len += scnprintf(buf + len, buf_len - len, "bsr_trigger_across_bss = %u\n",
3799 			 le32_to_cpu(htt_stats_buf->bsr_trigger_across_bss));
3800 	len += scnprintf(buf + len, buf_len - len, "bsr_trigger_within_bss = %u\n",
3801 			 le32_to_cpu(htt_stats_buf->bsr_trigger_within_bss));
3802 	len += scnprintf(buf + len, buf_len - len, "mu_rts_across_bss = %u\n",
3803 			 le32_to_cpu(htt_stats_buf->mu_rts_across_bss));
3804 	len += scnprintf(buf + len, buf_len - len, "mu_rts_within_bss = %u\n",
3805 			 le32_to_cpu(htt_stats_buf->mu_rts_within_bss));
3806 	len += scnprintf(buf + len, buf_len - len, "ul_mumimo_trigger_across_bss = %u\n",
3807 			 le32_to_cpu(htt_stats_buf->ul_mumimo_trigger_across_bss));
3808 	len += scnprintf(buf + len, buf_len - len,
3809 			 "ul_mumimo_trigger_within_bss = %u\n\n",
3810 			 le32_to_cpu(htt_stats_buf->ul_mumimo_trigger_within_bss));
3811 
3812 	stats_req->buf_len = len;
3813 }
3814 
ath12k_dbg_htt_ext_stats_parse(struct ath12k_base * ab,u16 tag,u16 len,const void * tag_buf,void * user_data)3815 static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
3816 					  u16 tag, u16 len, const void *tag_buf,
3817 					  void *user_data)
3818 {
3819 	struct debug_htt_stats_req *stats_req = user_data;
3820 
3821 	switch (tag) {
3822 	case HTT_STATS_TX_PDEV_CMN_TAG:
3823 		htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req);
3824 		break;
3825 	case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
3826 		htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req);
3827 		break;
3828 	case HTT_STATS_TX_PDEV_SIFS_TAG:
3829 		htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req);
3830 		break;
3831 	case HTT_STATS_TX_PDEV_FLUSH_TAG:
3832 		htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req);
3833 		break;
3834 	case HTT_STATS_TX_PDEV_SIFS_HIST_TAG:
3835 		htt_print_tx_pdev_stats_sifs_hist_tlv(tag_buf, len, stats_req);
3836 		break;
3837 	case HTT_STATS_PDEV_CTRL_PATH_TX_STATS_TAG:
3838 		htt_print_pdev_ctrl_path_tx_stats_tlv(tag_buf, len, stats_req);
3839 		break;
3840 	case HTT_STATS_MU_PPDU_DIST_TAG:
3841 		htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(tag_buf, len, stats_req);
3842 		break;
3843 	case HTT_STATS_TX_SCHED_CMN_TAG:
3844 		ath12k_htt_print_stats_tx_sched_cmn_tlv(tag_buf, len, stats_req);
3845 		break;
3846 	case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG:
3847 		ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, len, stats_req);
3848 		break;
3849 	case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG:
3850 		ath12k_htt_print_sched_txq_cmd_posted_tlv(tag_buf, len, stats_req);
3851 		break;
3852 	case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG:
3853 		ath12k_htt_print_sched_txq_cmd_reaped_tlv(tag_buf, len, stats_req);
3854 		break;
3855 	case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG:
3856 		ath12k_htt_print_sched_txq_sched_order_su_tlv(tag_buf, len, stats_req);
3857 		break;
3858 	case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG:
3859 		ath12k_htt_print_sched_txq_sched_ineligibility_tlv(tag_buf, len,
3860 								   stats_req);
3861 		break;
3862 	case HTT_STATS_SCHED_TXQ_SUPERCYCLE_TRIGGER_TAG:
3863 		ath12k_htt_print_sched_txq_supercycle_trigger_tlv(tag_buf, len,
3864 								  stats_req);
3865 		break;
3866 	case HTT_STATS_HW_PDEV_ERRS_TAG:
3867 		ath12k_htt_print_hw_stats_pdev_errs_tlv(tag_buf, len, stats_req);
3868 		break;
3869 	case HTT_STATS_HW_INTR_MISC_TAG:
3870 		ath12k_htt_print_hw_stats_intr_misc_tlv(tag_buf, len, stats_req);
3871 		break;
3872 	case HTT_STATS_WHAL_TX_TAG:
3873 		ath12k_htt_print_hw_stats_whal_tx_tlv(tag_buf, len, stats_req);
3874 		break;
3875 	case HTT_STATS_HW_WAR_TAG:
3876 		ath12k_htt_print_hw_war_tlv(tag_buf, len, stats_req);
3877 		break;
3878 	case HTT_STATS_TX_TQM_CMN_TAG:
3879 		ath12k_htt_print_tx_tqm_cmn_stats_tlv(tag_buf, len, stats_req);
3880 		break;
3881 	case HTT_STATS_TX_TQM_ERROR_STATS_TAG:
3882 		ath12k_htt_print_tx_tqm_error_stats_tlv(tag_buf, len, stats_req);
3883 		break;
3884 	case HTT_STATS_TX_TQM_GEN_MPDU_TAG:
3885 		ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(tag_buf, len, stats_req);
3886 		break;
3887 	case HTT_STATS_TX_TQM_LIST_MPDU_TAG:
3888 		ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(tag_buf, len, stats_req);
3889 		break;
3890 	case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG:
3891 		ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(tag_buf, len, stats_req);
3892 		break;
3893 	case HTT_STATS_TX_TQM_PDEV_TAG:
3894 		ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req);
3895 		break;
3896 	case HTT_STATS_TX_DE_CMN_TAG:
3897 		ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req);
3898 		break;
3899 	case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
3900 		ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req);
3901 		break;
3902 	case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
3903 		ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req);
3904 		break;
3905 	case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
3906 		ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req);
3907 		break;
3908 	case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
3909 		ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req);
3910 		break;
3911 	case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
3912 		ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req);
3913 		break;
3914 	case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
3915 		ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req);
3916 		break;
3917 	case HTT_STATS_TX_DE_COMPL_STATS_TAG:
3918 		ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
3919 		break;
3920 	case HTT_STATS_TX_SELFGEN_CMN_STATS_TAG:
3921 		ath12k_htt_print_tx_selfgen_cmn_stats_tlv(tag_buf, len, stats_req);
3922 		break;
3923 	case HTT_STATS_TX_SELFGEN_AC_STATS_TAG:
3924 		ath12k_htt_print_tx_selfgen_ac_stats_tlv(tag_buf, len, stats_req);
3925 		break;
3926 	case HTT_STATS_TX_SELFGEN_AX_STATS_TAG:
3927 		ath12k_htt_print_tx_selfgen_ax_stats_tlv(tag_buf, len, stats_req);
3928 		break;
3929 	case HTT_STATS_TX_SELFGEN_BE_STATS_TAG:
3930 		ath12k_htt_print_tx_selfgen_be_stats_tlv(tag_buf, len, stats_req);
3931 		break;
3932 	case HTT_STATS_TX_SELFGEN_AC_ERR_STATS_TAG:
3933 		ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(tag_buf, len, stats_req);
3934 		break;
3935 	case HTT_STATS_TX_SELFGEN_AX_ERR_STATS_TAG:
3936 		ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(tag_buf, len, stats_req);
3937 		break;
3938 	case HTT_STATS_TX_SELFGEN_BE_ERR_STATS_TAG:
3939 		ath12k_htt_print_tx_selfgen_be_err_stats_tlv(tag_buf, len, stats_req);
3940 		break;
3941 	case HTT_STATS_TX_SELFGEN_AC_SCHED_STATUS_STATS_TAG:
3942 		ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(tag_buf, len,
3943 								      stats_req);
3944 		break;
3945 	case HTT_STATS_TX_SELFGEN_AX_SCHED_STATUS_STATS_TAG:
3946 		ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(tag_buf, len,
3947 								      stats_req);
3948 		break;
3949 	case HTT_STATS_TX_SELFGEN_BE_SCHED_STATUS_STATS_TAG:
3950 		ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(tag_buf, len,
3951 								      stats_req);
3952 		break;
3953 	case HTT_STATS_STRING_TAG:
3954 		ath12k_htt_print_stats_string_tlv(tag_buf, len, stats_req);
3955 		break;
3956 	case HTT_STATS_SRING_STATS_TAG:
3957 		ath12k_htt_print_sring_stats_tlv(tag_buf, len, stats_req);
3958 		break;
3959 	case HTT_STATS_SFM_CMN_TAG:
3960 		ath12k_htt_print_sfm_cmn_tlv(tag_buf, len, stats_req);
3961 		break;
3962 	case HTT_STATS_SFM_CLIENT_TAG:
3963 		ath12k_htt_print_sfm_client_tlv(tag_buf, len, stats_req);
3964 		break;
3965 	case HTT_STATS_SFM_CLIENT_USER_TAG:
3966 		ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req);
3967 		break;
3968 	case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG:
3969 		ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req);
3970 		break;
3971 	case HTT_STATS_TX_PDEV_MUMIMO_GRP_STATS_TAG:
3972 		ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(tag_buf, len, stats_req);
3973 		break;
3974 	case HTT_STATS_TX_PDEV_MPDU_STATS_TAG:
3975 		ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(tag_buf, len, stats_req);
3976 		break;
3977 	case HTT_STATS_PDEV_CCA_1SEC_HIST_TAG:
3978 	case HTT_STATS_PDEV_CCA_100MSEC_HIST_TAG:
3979 	case HTT_STATS_PDEV_CCA_STAT_CUMULATIVE_TAG:
3980 		ath12k_htt_print_pdev_cca_stats_hist_tlv(tag_buf, len, stats_req);
3981 		break;
3982 	case HTT_STATS_PDEV_CCA_COUNTERS_TAG:
3983 		ath12k_htt_print_pdev_stats_cca_counters_tlv(tag_buf, len, stats_req);
3984 		break;
3985 	case HTT_STATS_PDEV_OBSS_PD_TAG:
3986 		ath12k_htt_print_pdev_obss_pd_stats_tlv(tag_buf, len, stats_req);
3987 		break;
3988 	case HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG:
3989 		ath12k_htt_print_pdev_tx_rate_txbf_stats_tlv(tag_buf, len, stats_req);
3990 		break;
3991 	case HTT_STATS_TXBF_OFDMA_AX_NDPA_STATS_TAG:
3992 		ath12k_htt_print_txbf_ofdma_ax_ndpa_stats_tlv(tag_buf, len, stats_req);
3993 		break;
3994 	case HTT_STATS_TXBF_OFDMA_AX_NDP_STATS_TAG:
3995 		ath12k_htt_print_txbf_ofdma_ax_ndp_stats_tlv(tag_buf, len, stats_req);
3996 		break;
3997 	case HTT_STATS_TXBF_OFDMA_AX_BRP_STATS_TAG:
3998 		ath12k_htt_print_txbf_ofdma_ax_brp_stats_tlv(tag_buf, len, stats_req);
3999 		break;
4000 	case HTT_STATS_TXBF_OFDMA_AX_STEER_STATS_TAG:
4001 		ath12k_htt_print_txbf_ofdma_ax_steer_stats_tlv(tag_buf, len, stats_req);
4002 		break;
4003 	case HTT_STATS_TXBF_OFDMA_AX_STEER_MPDU_STATS_TAG:
4004 		ath12k_htt_print_txbf_ofdma_ax_steer_mpdu_stats_tlv(tag_buf, len,
4005 								    stats_req);
4006 		break;
4007 	case HTT_STATS_DLPAGER_STATS_TAG:
4008 		ath12k_htt_print_dlpager_stats_tlv(tag_buf, len, stats_req);
4009 		break;
4010 	case HTT_STATS_PHY_STATS_TAG:
4011 		ath12k_htt_print_phy_stats_tlv(tag_buf, len, stats_req);
4012 		break;
4013 	case HTT_STATS_PHY_COUNTERS_TAG:
4014 		ath12k_htt_print_phy_counters_tlv(tag_buf, len, stats_req);
4015 		break;
4016 	case HTT_STATS_PHY_RESET_STATS_TAG:
4017 		ath12k_htt_print_phy_reset_stats_tlv(tag_buf, len, stats_req);
4018 		break;
4019 	case HTT_STATS_PHY_RESET_COUNTERS_TAG:
4020 		ath12k_htt_print_phy_reset_counters_tlv(tag_buf, len, stats_req);
4021 		break;
4022 	case HTT_STATS_PHY_TPC_STATS_TAG:
4023 		ath12k_htt_print_phy_tpc_stats_tlv(tag_buf, len, stats_req);
4024 		break;
4025 	case HTT_STATS_SOC_TXRX_STATS_COMMON_TAG:
4026 		ath12k_htt_print_soc_txrx_stats_common_tlv(tag_buf, len, stats_req);
4027 		break;
4028 	case HTT_STATS_PER_RATE_STATS_TAG:
4029 		ath12k_htt_print_tx_per_rate_stats_tlv(tag_buf, len, stats_req);
4030 		break;
4031 	case HTT_STATS_AST_ENTRY_TAG:
4032 		ath12k_htt_print_ast_entry_tlv(tag_buf, len, stats_req);
4033 		break;
4034 	case HTT_STATS_PDEV_PUNCTURE_STATS_TAG:
4035 		ath12k_htt_print_puncture_stats_tlv(tag_buf, len, stats_req);
4036 		break;
4037 	case HTT_STATS_DMAC_RESET_STATS_TAG:
4038 		ath12k_htt_print_dmac_reset_stats_tlv(tag_buf, len, stats_req);
4039 		break;
4040 	case HTT_STATS_PDEV_SCHED_ALGO_OFDMA_STATS_TAG:
4041 		ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(tag_buf, len, stats_req);
4042 		break;
4043 	case HTT_STATS_TX_PDEV_RATE_STATS_BE_OFDMA_TAG:
4044 		ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(tag_buf, len, stats_req);
4045 		break;
4046 	case HTT_STATS_PDEV_MBSSID_CTRL_FRAME_STATS_TAG:
4047 		ath12k_htt_print_pdev_mbssid_ctrl_frame_stats_tlv(tag_buf, len,
4048 								  stats_req);
4049 		break;
4050 	default:
4051 		break;
4052 	}
4053 
4054 	return 0;
4055 }
4056 
ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base * ab,struct sk_buff * skb)4057 void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
4058 					  struct sk_buff *skb)
4059 {
4060 	struct ath12k_htt_extd_stats_msg *msg;
4061 	struct debug_htt_stats_req *stats_req;
4062 	struct ath12k *ar;
4063 	u32 len, pdev_id, stats_info;
4064 	u64 cookie;
4065 	int ret;
4066 	bool send_completion = false;
4067 
4068 	msg = (struct ath12k_htt_extd_stats_msg *)skb->data;
4069 	cookie = le64_to_cpu(msg->cookie);
4070 
4071 	if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) !=
4072 			 ATH12K_HTT_STATS_MAGIC_VALUE) {
4073 		ath12k_warn(ab, "received invalid htt ext stats event\n");
4074 		return;
4075 	}
4076 
4077 	pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB);
4078 	rcu_read_lock();
4079 	ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
4080 	if (!ar) {
4081 		ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
4082 		goto exit;
4083 	}
4084 
4085 	stats_req = ar->debug.htt_stats.stats_req;
4086 	if (!stats_req)
4087 		goto exit;
4088 
4089 	spin_lock_bh(&ar->data_lock);
4090 
4091 	stats_info = le32_to_cpu(msg->info1);
4092 	stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE);
4093 	if (stats_req->done)
4094 		send_completion = true;
4095 
4096 	spin_unlock_bh(&ar->data_lock);
4097 
4098 	len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH);
4099 	if (len > skb->len) {
4100 		ath12k_warn(ab, "invalid length %d for HTT stats", len);
4101 		goto exit;
4102 	}
4103 
4104 	ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
4105 				     ath12k_dbg_htt_ext_stats_parse,
4106 				     stats_req);
4107 	if (ret)
4108 		ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
4109 
4110 	if (send_completion)
4111 		complete(&stats_req->htt_stats_rcvd);
4112 exit:
4113 	rcu_read_unlock();
4114 }
4115 
ath12k_read_htt_stats_type(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)4116 static ssize_t ath12k_read_htt_stats_type(struct file *file,
4117 					  char __user *user_buf,
4118 					  size_t count, loff_t *ppos)
4119 {
4120 	struct ath12k *ar = file->private_data;
4121 	enum ath12k_dbg_htt_ext_stats_type type;
4122 	char buf[32];
4123 	size_t len;
4124 
4125 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
4126 	type = ar->debug.htt_stats.type;
4127 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4128 
4129 	len = scnprintf(buf, sizeof(buf), "%u\n", type);
4130 
4131 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
4132 }
4133 
ath12k_write_htt_stats_type(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)4134 static ssize_t ath12k_write_htt_stats_type(struct file *file,
4135 					   const char __user *user_buf,
4136 					   size_t count, loff_t *ppos)
4137 {
4138 	struct ath12k *ar = file->private_data;
4139 	enum ath12k_dbg_htt_ext_stats_type type;
4140 	unsigned int cfg_param[4] = {0};
4141 	const int size = 32;
4142 	int num_args;
4143 
4144 	char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
4145 	if (!buf)
4146 		return -ENOMEM;
4147 
4148 	if (copy_from_user(buf, user_buf, count))
4149 		return -EFAULT;
4150 
4151 	num_args = sscanf(buf, "%u %u %u %u %u\n", &type, &cfg_param[0],
4152 			  &cfg_param[1], &cfg_param[2], &cfg_param[3]);
4153 	if (!num_args || num_args > 5)
4154 		return -EINVAL;
4155 
4156 	if (type == ATH12K_DBG_HTT_EXT_STATS_RESET ||
4157 	    type >= ATH12K_DBG_HTT_NUM_EXT_STATS)
4158 		return -EINVAL;
4159 
4160 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
4161 
4162 	ar->debug.htt_stats.type = type;
4163 	ar->debug.htt_stats.cfg_param[0] = cfg_param[0];
4164 	ar->debug.htt_stats.cfg_param[1] = cfg_param[1];
4165 	ar->debug.htt_stats.cfg_param[2] = cfg_param[2];
4166 	ar->debug.htt_stats.cfg_param[3] = cfg_param[3];
4167 
4168 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4169 
4170 	return count;
4171 }
4172 
4173 static const struct file_operations fops_htt_stats_type = {
4174 	.read = ath12k_read_htt_stats_type,
4175 	.write = ath12k_write_htt_stats_type,
4176 	.open = simple_open,
4177 	.owner = THIS_MODULE,
4178 	.llseek = default_llseek,
4179 };
4180 
ath12k_debugfs_htt_stats_req(struct ath12k * ar)4181 static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
4182 {
4183 	struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
4184 	enum ath12k_dbg_htt_ext_stats_type type = stats_req->type;
4185 	u64 cookie;
4186 	int ret, pdev_id;
4187 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
4188 
4189 	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
4190 
4191 	init_completion(&stats_req->htt_stats_rcvd);
4192 
4193 	pdev_id = ath12k_mac_get_target_pdev_id(ar);
4194 	stats_req->done = false;
4195 	stats_req->pdev_id = pdev_id;
4196 
4197 	cookie = u64_encode_bits(ATH12K_HTT_STATS_MAGIC_VALUE,
4198 				 ATH12K_HTT_STATS_COOKIE_MSB);
4199 	cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB);
4200 
4201 	if (stats_req->override_cfg_param) {
4202 		cfg_params.cfg0 = stats_req->cfg_param[0];
4203 		cfg_params.cfg1 = stats_req->cfg_param[1];
4204 		cfg_params.cfg2 = stats_req->cfg_param[2];
4205 		cfg_params.cfg3 = stats_req->cfg_param[3];
4206 	}
4207 
4208 	ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
4209 	if (ret) {
4210 		ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
4211 		return ret;
4212 	}
4213 	if (!wait_for_completion_timeout(&stats_req->htt_stats_rcvd, 3 * HZ)) {
4214 		spin_lock_bh(&ar->data_lock);
4215 		if (!stats_req->done) {
4216 			stats_req->done = true;
4217 			spin_unlock_bh(&ar->data_lock);
4218 			ath12k_warn(ar->ab, "stats request timed out\n");
4219 			return -ETIMEDOUT;
4220 		}
4221 		spin_unlock_bh(&ar->data_lock);
4222 	}
4223 
4224 	return 0;
4225 }
4226 
ath12k_open_htt_stats(struct inode * inode,struct file * file)4227 static int ath12k_open_htt_stats(struct inode *inode,
4228 				 struct file *file)
4229 {
4230 	struct ath12k *ar = inode->i_private;
4231 	struct debug_htt_stats_req *stats_req;
4232 	enum ath12k_dbg_htt_ext_stats_type type = ar->debug.htt_stats.type;
4233 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
4234 	int ret;
4235 
4236 	if (type == ATH12K_DBG_HTT_EXT_STATS_RESET)
4237 		return -EPERM;
4238 
4239 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
4240 
4241 	if (ah->state != ATH12K_HW_STATE_ON) {
4242 		ret = -ENETDOWN;
4243 		goto err_unlock;
4244 	}
4245 
4246 	if (ar->debug.htt_stats.stats_req) {
4247 		ret = -EAGAIN;
4248 		goto err_unlock;
4249 	}
4250 
4251 	stats_req = kzalloc(sizeof(*stats_req) + ATH12K_HTT_STATS_BUF_SIZE, GFP_KERNEL);
4252 	if (!stats_req) {
4253 		ret = -ENOMEM;
4254 		goto err_unlock;
4255 	}
4256 
4257 	ar->debug.htt_stats.stats_req = stats_req;
4258 	stats_req->type = type;
4259 	stats_req->cfg_param[0] = ar->debug.htt_stats.cfg_param[0];
4260 	stats_req->cfg_param[1] = ar->debug.htt_stats.cfg_param[1];
4261 	stats_req->cfg_param[2] = ar->debug.htt_stats.cfg_param[2];
4262 	stats_req->cfg_param[3] = ar->debug.htt_stats.cfg_param[3];
4263 	stats_req->override_cfg_param = !!stats_req->cfg_param[0] ||
4264 					!!stats_req->cfg_param[1] ||
4265 					!!stats_req->cfg_param[2] ||
4266 					!!stats_req->cfg_param[3];
4267 
4268 	ret = ath12k_debugfs_htt_stats_req(ar);
4269 	if (ret < 0)
4270 		goto out;
4271 
4272 	file->private_data = stats_req;
4273 
4274 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4275 
4276 	return 0;
4277 out:
4278 	kfree(stats_req);
4279 	ar->debug.htt_stats.stats_req = NULL;
4280 err_unlock:
4281 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4282 
4283 	return ret;
4284 }
4285 
ath12k_release_htt_stats(struct inode * inode,struct file * file)4286 static int ath12k_release_htt_stats(struct inode *inode,
4287 				    struct file *file)
4288 {
4289 	struct ath12k *ar = inode->i_private;
4290 
4291 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
4292 	kfree(file->private_data);
4293 	ar->debug.htt_stats.stats_req = NULL;
4294 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4295 
4296 	return 0;
4297 }
4298 
ath12k_read_htt_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)4299 static ssize_t ath12k_read_htt_stats(struct file *file,
4300 				     char __user *user_buf,
4301 				     size_t count, loff_t *ppos)
4302 {
4303 	struct debug_htt_stats_req *stats_req = file->private_data;
4304 	char *buf;
4305 	u32 length;
4306 
4307 	buf = stats_req->buf;
4308 	length = min_t(u32, stats_req->buf_len, ATH12K_HTT_STATS_BUF_SIZE);
4309 	return simple_read_from_buffer(user_buf, count, ppos, buf, length);
4310 }
4311 
4312 static const struct file_operations fops_dump_htt_stats = {
4313 	.open = ath12k_open_htt_stats,
4314 	.release = ath12k_release_htt_stats,
4315 	.read = ath12k_read_htt_stats,
4316 	.owner = THIS_MODULE,
4317 	.llseek = default_llseek,
4318 };
4319 
ath12k_write_htt_stats_reset(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)4320 static ssize_t ath12k_write_htt_stats_reset(struct file *file,
4321 					    const char __user *user_buf,
4322 					    size_t count, loff_t *ppos)
4323 {
4324 	struct ath12k *ar = file->private_data;
4325 	enum ath12k_dbg_htt_ext_stats_type type;
4326 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
4327 	u8 param_pos;
4328 	int ret;
4329 
4330 	ret = kstrtou32_from_user(user_buf, count, 0, &type);
4331 	if (ret)
4332 		return ret;
4333 
4334 	if (type >= ATH12K_DBG_HTT_NUM_EXT_STATS ||
4335 	    type == ATH12K_DBG_HTT_EXT_STATS_RESET)
4336 		return -E2BIG;
4337 
4338 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
4339 	cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET;
4340 	param_pos = (type >> 5) + 1;
4341 
4342 	switch (param_pos) {
4343 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES:
4344 		cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type);
4345 		break;
4346 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES:
4347 		cfg_params.cfg2 = ATH12K_HTT_STATS_RESET_BITMAP32_BIT(cfg_params.cfg0 +
4348 								      type);
4349 		break;
4350 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_128_BYTES:
4351 		cfg_params.cfg3 = ATH12K_HTT_STATS_RESET_BITMAP64_BIT(cfg_params.cfg0 +
4352 								      type);
4353 		break;
4354 	default:
4355 		break;
4356 	}
4357 
4358 	ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar,
4359 						 ATH12K_DBG_HTT_EXT_STATS_RESET,
4360 						 &cfg_params,
4361 						 0ULL);
4362 	if (ret) {
4363 		ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
4364 		wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4365 		return ret;
4366 	}
4367 
4368 	ar->debug.htt_stats.reset = type;
4369 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
4370 
4371 	return count;
4372 }
4373 
4374 static const struct file_operations fops_htt_stats_reset = {
4375 	.write = ath12k_write_htt_stats_reset,
4376 	.open = simple_open,
4377 	.owner = THIS_MODULE,
4378 	.llseek = default_llseek,
4379 };
4380 
ath12k_debugfs_htt_stats_register(struct ath12k * ar)4381 void ath12k_debugfs_htt_stats_register(struct ath12k *ar)
4382 {
4383 	debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev,
4384 			    ar, &fops_htt_stats_type);
4385 	debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev,
4386 			    ar, &fops_dump_htt_stats);
4387 	debugfs_create_file("htt_stats_reset", 0200, ar->debug.debugfs_pdev,
4388 			    ar, &fops_htt_stats_reset);
4389 }
4390