xref: /linux/drivers/net/wireless/ath/ath12k/debugfs_htt_stats.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
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_be_tx_rx_ru_size_to_str(u8 ru_size)51 static const char *ath12k_htt_be_tx_rx_ru_size_to_str(u8 ru_size)
52 {
53 	switch (ru_size) {
54 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_26:
55 		return "26";
56 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_52:
57 		return "52";
58 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_52_26:
59 		return "52+26";
60 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_106:
61 		return "106";
62 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_106_26:
63 		return "106+26";
64 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_242:
65 		return "242";
66 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_484:
67 		return "484";
68 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_484_242:
69 		return "484+242";
70 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996:
71 		return "996";
72 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996_484:
73 		return "996+484";
74 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996_484_242:
75 		return "996+484+242";
76 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x2:
77 		return "996x2";
78 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x2_484:
79 		return "996x2+484";
80 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x3:
81 		return "996x3";
82 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x3_484:
83 		return "996x3+484";
84 	case ATH12K_HTT_TX_RX_PDEV_STATS_BE_RU_SIZE_996x4:
85 		return "996x4";
86 	default:
87 		return "unknown";
88 	}
89 }
90 
91 static void
htt_print_tx_pdev_stats_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)92 htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
93 				struct debug_htt_stats_req *stats_req)
94 {
95 	const struct ath12k_htt_tx_pdev_stats_cmn_tlv *htt_stats_buf = tag_buf;
96 	u8 *buf = stats_req->buf;
97 	u32 len = stats_req->buf_len;
98 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
99 	u32 mac_id_word;
100 
101 	if (tag_len < sizeof(*htt_stats_buf))
102 		return;
103 
104 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
105 
106 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n");
107 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
108 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
109 	len += scnprintf(buf + len, buf_len - len, "comp_delivered = %u\n",
110 			 le32_to_cpu(htt_stats_buf->comp_delivered));
111 	len += scnprintf(buf + len, buf_len - len, "self_triggers = %u\n",
112 			 le32_to_cpu(htt_stats_buf->self_triggers));
113 	len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
114 			 le32_to_cpu(htt_stats_buf->hw_queued));
115 	len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
116 			 le32_to_cpu(htt_stats_buf->hw_reaped));
117 	len += scnprintf(buf + len, buf_len - len, "underrun = %u\n",
118 			 le32_to_cpu(htt_stats_buf->underrun));
119 	len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n",
120 			 le32_to_cpu(htt_stats_buf->hw_paused));
121 	len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n",
122 			 le32_to_cpu(htt_stats_buf->hw_flush));
123 	len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n",
124 			 le32_to_cpu(htt_stats_buf->hw_filt));
125 	len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
126 			 le32_to_cpu(htt_stats_buf->tx_abort));
127 	len += scnprintf(buf + len, buf_len - len, "ppdu_ok = %u\n",
128 			 le32_to_cpu(htt_stats_buf->ppdu_ok));
129 	len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n",
130 			 le32_to_cpu(htt_stats_buf->mpdu_requed));
131 	len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n",
132 			 le32_to_cpu(htt_stats_buf->tx_xretry));
133 	len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n",
134 			 le32_to_cpu(htt_stats_buf->data_rc));
135 	len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n",
136 			 le32_to_cpu(htt_stats_buf->mpdu_dropped_xretry));
137 	len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n",
138 			 le32_to_cpu(htt_stats_buf->illgl_rate_phy_err));
139 	len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n",
140 			 le32_to_cpu(htt_stats_buf->cont_xretry));
141 	len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n",
142 			 le32_to_cpu(htt_stats_buf->tx_timeout));
143 	len += scnprintf(buf + len, buf_len - len, "tx_time_dur_data = %u\n",
144 			 le32_to_cpu(htt_stats_buf->tx_time_dur_data));
145 	len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n",
146 			 le32_to_cpu(htt_stats_buf->pdev_resets));
147 	len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n",
148 			 le32_to_cpu(htt_stats_buf->phy_underrun));
149 	len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n",
150 			 le32_to_cpu(htt_stats_buf->txop_ovf));
151 	len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n",
152 			 le32_to_cpu(htt_stats_buf->seq_posted));
153 	len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n",
154 			 le32_to_cpu(htt_stats_buf->seq_failed_queueing));
155 	len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n",
156 			 le32_to_cpu(htt_stats_buf->seq_completed));
157 	len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n",
158 			 le32_to_cpu(htt_stats_buf->seq_restarted));
159 	len += scnprintf(buf + len, buf_len - len, "seq_txop_repost_stop = %u\n",
160 			 le32_to_cpu(htt_stats_buf->seq_txop_repost_stop));
161 	len += scnprintf(buf + len, buf_len - len, "next_seq_cancel = %u\n",
162 			 le32_to_cpu(htt_stats_buf->next_seq_cancel));
163 	len += scnprintf(buf + len, buf_len - len, "dl_mu_mimo_seq_posted = %u\n",
164 			 le32_to_cpu(htt_stats_buf->mu_seq_posted));
165 	len += scnprintf(buf + len, buf_len - len, "dl_mu_ofdma_seq_posted = %u\n",
166 			 le32_to_cpu(htt_stats_buf->mu_ofdma_seq_posted));
167 	len += scnprintf(buf + len, buf_len - len, "ul_mu_mimo_seq_posted = %u\n",
168 			 le32_to_cpu(htt_stats_buf->ul_mumimo_seq_posted));
169 	len += scnprintf(buf + len, buf_len - len, "ul_mu_ofdma_seq_posted = %u\n",
170 			 le32_to_cpu(htt_stats_buf->ul_ofdma_seq_posted));
171 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_peer_blacklisted = %u\n",
172 			 le32_to_cpu(htt_stats_buf->num_mu_peer_blacklisted));
173 	len += scnprintf(buf + len, buf_len - len, "seq_qdepth_repost_stop = %u\n",
174 			 le32_to_cpu(htt_stats_buf->seq_qdepth_repost_stop));
175 	len += scnprintf(buf + len, buf_len - len, "seq_min_msdu_repost_stop = %u\n",
176 			 le32_to_cpu(htt_stats_buf->seq_min_msdu_repost_stop));
177 	len += scnprintf(buf + len, buf_len - len, "mu_seq_min_msdu_repost_stop = %u\n",
178 			 le32_to_cpu(htt_stats_buf->mu_seq_min_msdu_repost_stop));
179 	len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n",
180 			 le32_to_cpu(htt_stats_buf->seq_switch_hw_paused));
181 	len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n",
182 			 le32_to_cpu(htt_stats_buf->next_seq_posted_dsr));
183 	len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n",
184 			 le32_to_cpu(htt_stats_buf->seq_posted_isr));
185 	len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n",
186 			 le32_to_cpu(htt_stats_buf->seq_ctrl_cached));
187 	len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n",
188 			 le32_to_cpu(htt_stats_buf->mpdu_count_tqm));
189 	len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n",
190 			 le32_to_cpu(htt_stats_buf->msdu_count_tqm));
191 	len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n",
192 			 le32_to_cpu(htt_stats_buf->mpdu_removed_tqm));
193 	len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n",
194 			 le32_to_cpu(htt_stats_buf->msdu_removed_tqm));
195 	len += scnprintf(buf + len, buf_len - len, "remove_mpdus_max_retries = %u\n",
196 			 le32_to_cpu(htt_stats_buf->remove_mpdus_max_retries));
197 	len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n",
198 			 le32_to_cpu(htt_stats_buf->mpdus_sw_flush));
199 	len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
200 			 le32_to_cpu(htt_stats_buf->mpdus_hw_filter));
201 	len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n",
202 			 le32_to_cpu(htt_stats_buf->mpdus_truncated));
203 	len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n",
204 			 le32_to_cpu(htt_stats_buf->mpdus_ack_failed));
205 	len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n",
206 			 le32_to_cpu(htt_stats_buf->mpdus_expired));
207 	len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n",
208 			 le32_to_cpu(htt_stats_buf->mpdus_seq_hw_retry));
209 	len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
210 			 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
211 	len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n",
212 			 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt_valid));
213 	len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n",
214 			 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt));
215 	len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n",
216 			 le32_to_cpu(htt_stats_buf->num_total_ppdus_tried_ota));
217 	len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n",
218 			 le32_to_cpu(htt_stats_buf->num_data_ppdus_tried_ota));
219 	len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n",
220 			 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_enqued));
221 	len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n",
222 			 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_freed));
223 	len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n",
224 			 le32_to_cpu(htt_stats_buf->local_data_enqued));
225 	len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n",
226 			 le32_to_cpu(htt_stats_buf->local_data_freed));
227 	len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n",
228 			 le32_to_cpu(htt_stats_buf->mpdu_tried));
229 	len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n",
230 			 le32_to_cpu(htt_stats_buf->isr_wait_seq_posted));
231 	len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n",
232 			 le32_to_cpu(htt_stats_buf->tx_active_dur_us_low));
233 	len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n",
234 			 le32_to_cpu(htt_stats_buf->tx_active_dur_us_high));
235 	len += scnprintf(buf + len, buf_len - len, "fes_offsets_err_cnt = %u\n\n",
236 			 le32_to_cpu(htt_stats_buf->fes_offsets_err_cnt));
237 
238 	stats_req->buf_len = len;
239 }
240 
241 static void
htt_print_tx_pdev_stats_urrn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)242 htt_print_tx_pdev_stats_urrn_tlv(const void *tag_buf,
243 				 u16 tag_len,
244 				 struct debug_htt_stats_req *stats_req)
245 {
246 	const struct ath12k_htt_tx_pdev_stats_urrn_tlv *htt_stats_buf = tag_buf;
247 	u8 *buf = stats_req->buf;
248 	u32 len = stats_req->buf_len;
249 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
250 	u16 num_elems = min_t(u16, (tag_len >> 2),
251 			      HTT_TX_PDEV_MAX_URRN_STATS);
252 
253 	len += scnprintf(buf + len, buf_len - len,
254 			"HTT_TX_PDEV_STATS_URRN_TLV:\n");
255 
256 	len += print_array_to_buf(buf, len, "urrn_stats", htt_stats_buf->urrn_stats,
257 				  num_elems, "\n\n");
258 
259 	stats_req->buf_len = len;
260 }
261 
262 static void
htt_print_tx_pdev_stats_flush_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)263 htt_print_tx_pdev_stats_flush_tlv(const void *tag_buf,
264 				  u16 tag_len,
265 				  struct debug_htt_stats_req *stats_req)
266 {
267 	const struct ath12k_htt_tx_pdev_stats_flush_tlv *htt_stats_buf = tag_buf;
268 	u8 *buf = stats_req->buf;
269 	u32 len = stats_req->buf_len;
270 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
271 	u16 num_elems = min_t(u16, (tag_len >> 2),
272 			      ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS);
273 
274 	len += scnprintf(buf + len, buf_len - len,
275 			 "HTT_TX_PDEV_STATS_FLUSH_TLV:\n");
276 
277 	len += print_array_to_buf(buf, len, "flush_errs", htt_stats_buf->flush_errs,
278 				  num_elems, "\n\n");
279 
280 	stats_req->buf_len = len;
281 }
282 
283 static void
htt_print_tx_pdev_stats_sifs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)284 htt_print_tx_pdev_stats_sifs_tlv(const void *tag_buf,
285 				 u16 tag_len,
286 				 struct debug_htt_stats_req *stats_req)
287 {
288 	const struct ath12k_htt_tx_pdev_stats_sifs_tlv *htt_stats_buf = tag_buf;
289 	u8 *buf = stats_req->buf;
290 	u32 len = stats_req->buf_len;
291 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
292 	u16 num_elems = min_t(u16, (tag_len >> 2),
293 			      ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS);
294 
295 	len += scnprintf(buf + len, buf_len - len,
296 			 "HTT_TX_PDEV_STATS_SIFS_TLV:\n");
297 
298 	len += print_array_to_buf(buf, len, "sifs_status", htt_stats_buf->sifs_status,
299 				  num_elems, "\n\n");
300 
301 	stats_req->buf_len = len;
302 }
303 
304 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)305 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void *tag_buf, u16 tag_len,
306 					 struct debug_htt_stats_req *stats_req)
307 {
308 	const struct ath12k_htt_tx_pdev_mu_ppdu_dist_stats_tlv *htt_stats_buf = tag_buf;
309 	char *mode;
310 	u8 j, hw_mode, i, str_buf_len;
311 	u8 *buf = stats_req->buf;
312 	u32 len = stats_req->buf_len;
313 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
314 	u32 stats_value;
315 	u8 max_ppdu = ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST;
316 	u8 max_sched = ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS;
317 	char str_buf[ATH12K_HTT_MAX_STRING_LEN];
318 
319 	if (tag_len < sizeof(*htt_stats_buf))
320 		return;
321 
322 	hw_mode = le32_to_cpu(htt_stats_buf->hw_mode);
323 
324 	switch (hw_mode) {
325 	case ATH12K_HTT_STATS_HWMODE_AC:
326 		len += scnprintf(buf + len, buf_len - len,
327 				 "HTT_TX_PDEV_AC_MU_PPDU_DISTRIBUTION_STATS:\n");
328 		mode = "ac";
329 		break;
330 	case ATH12K_HTT_STATS_HWMODE_AX:
331 		len += scnprintf(buf + len, buf_len - len,
332 				 "HTT_TX_PDEV_AX_MU_PPDU_DISTRIBUTION_STATS:\n");
333 		mode = "ax";
334 		break;
335 	case ATH12K_HTT_STATS_HWMODE_BE:
336 		len += scnprintf(buf + len, buf_len - len,
337 				 "HTT_TX_PDEV_BE_MU_PPDU_DISTRIBUTION_STATS:\n");
338 		mode = "be";
339 		break;
340 	default:
341 		return;
342 	}
343 
344 	for (i = 0; i < ATH12K_HTT_STATS_NUM_NR_BINS ; i++) {
345 		len += scnprintf(buf + len, buf_len - len,
346 				 "%s_mu_mimo_num_seq_posted_nr%u = %u\n", mode,
347 				 ((i + 1) * 4), htt_stats_buf->num_seq_posted[i]);
348 		str_buf_len = 0;
349 		memset(str_buf, 0x0, sizeof(str_buf));
350 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
351 			stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_posted_per_burst
352 						  [i * max_ppdu + j]);
353 			str_buf_len += scnprintf(&str_buf[str_buf_len],
354 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
355 						" %u:%u,", j, stats_value);
356 		}
357 		/* To overwrite the last trailing comma */
358 		str_buf[str_buf_len - 1] = '\0';
359 		len += scnprintf(buf + len, buf_len - len,
360 				 "%s_mu_mimo_num_ppdu_posted_per_burst_nr%u = %s\n",
361 				 mode, ((i + 1) * 4), str_buf);
362 		str_buf_len = 0;
363 		memset(str_buf, 0x0, sizeof(str_buf));
364 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
365 			stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_cmpl_per_burst
366 						  [i * max_ppdu + j]);
367 			str_buf_len += scnprintf(&str_buf[str_buf_len],
368 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
369 						" %u:%u,", j, stats_value);
370 		}
371 		/* To overwrite the last trailing comma */
372 		str_buf[str_buf_len - 1] = '\0';
373 		len += scnprintf(buf + len, buf_len - len,
374 				 "%s_mu_mimo_num_ppdu_completed_per_burst_nr%u = %s\n",
375 				 mode, ((i + 1) * 4), str_buf);
376 		str_buf_len = 0;
377 		memset(str_buf, 0x0, sizeof(str_buf));
378 		for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS ; j++) {
379 			stats_value = le32_to_cpu(htt_stats_buf->num_seq_term_status
380 						  [i * max_sched + j]);
381 			str_buf_len += scnprintf(&str_buf[str_buf_len],
382 						ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
383 						" %u:%u,", j, stats_value);
384 		}
385 		/* To overwrite the last trailing comma */
386 		str_buf[str_buf_len - 1] = '\0';
387 		len += scnprintf(buf + len, buf_len - len,
388 				 "%s_mu_mimo_num_seq_term_status_nr%u = %s\n\n",
389 				 mode, ((i + 1) * 4), str_buf);
390 	}
391 
392 	stats_req->buf_len = len;
393 }
394 
395 static void
htt_print_tx_pdev_stats_sifs_hist_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)396 htt_print_tx_pdev_stats_sifs_hist_tlv(const void *tag_buf,
397 				      u16 tag_len,
398 				      struct debug_htt_stats_req *stats_req)
399 {
400 	const struct ath12k_htt_tx_pdev_stats_sifs_hist_tlv *htt_stats_buf = tag_buf;
401 	u8 *buf = stats_req->buf;
402 	u32 len = stats_req->buf_len;
403 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
404 	u16 num_elems = min_t(u16, (tag_len >> 2),
405 			      ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS);
406 
407 	len += scnprintf(buf + len, buf_len - len,
408 			 "HTT_TX_PDEV_STATS_SIFS_HIST_TLV:\n");
409 
410 	len += print_array_to_buf(buf, len, "sifs_hist_status",
411 				  htt_stats_buf->sifs_hist_status, num_elems, "\n\n");
412 
413 	stats_req->buf_len = len;
414 }
415 
416 static void
htt_print_pdev_ctrl_path_tx_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)417 htt_print_pdev_ctrl_path_tx_stats_tlv(const void *tag_buf, u16 tag_len,
418 				      struct debug_htt_stats_req *stats_req)
419 {
420 	const struct ath12k_htt_pdev_ctrl_path_tx_stats_tlv *htt_stats_buf = tag_buf;
421 	u8 *buf = stats_req->buf;
422 	u32 len = stats_req->buf_len;
423 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
424 
425 	if (len < sizeof(*htt_stats_buf))
426 		return;
427 
428 	len += scnprintf(buf + len, buf_len - len,
429 			 "HTT_TX_PDEV_STATS_CTRL_PATH_TX_STATS:\n");
430 	len += print_array_to_buf(buf, len, "fw_tx_mgmt_subtype",
431 				 htt_stats_buf->fw_tx_mgmt_subtype,
432 				 ATH12K_HTT_STATS_SUBTYPE_MAX, "\n\n");
433 
434 	stats_req->buf_len = len;
435 }
436 
437 static void
ath12k_htt_print_stats_tx_sched_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)438 ath12k_htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf,
439 					u16 tag_len,
440 					struct debug_htt_stats_req *stats_req)
441 {
442 	const struct ath12k_htt_stats_tx_sched_cmn_tlv *htt_stats_buf = tag_buf;
443 	u8 *buf = stats_req->buf;
444 	u32 len = stats_req->buf_len;
445 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
446 	u32 mac_id_word;
447 
448 	if (tag_len < sizeof(*htt_stats_buf))
449 		return;
450 
451 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
452 
453 	len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n");
454 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
455 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
456 	len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n",
457 			 le32_to_cpu(htt_stats_buf->current_timestamp));
458 
459 	stats_req->buf_len = len;
460 }
461 
462 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)463 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf,
464 						 u16 tag_len,
465 						 struct debug_htt_stats_req *stats_req)
466 {
467 	const struct ath12k_htt_tx_pdev_stats_sched_per_txq_tlv *htt_stats_buf = tag_buf;
468 	u8 *buf = stats_req->buf;
469 	u32 len = stats_req->buf_len;
470 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
471 	u32 mac_id_word;
472 
473 	if (tag_len < sizeof(*htt_stats_buf))
474 		return;
475 
476 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
477 
478 	len += scnprintf(buf + len, buf_len - len,
479 			 "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n");
480 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
481 			u32_get_bits(mac_id_word,
482 				     ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID));
483 	len += scnprintf(buf + len, buf_len - len, "txq_id = %u\n",
484 			 u32_get_bits(mac_id_word,
485 				      ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID));
486 	len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n",
487 			 le32_to_cpu(htt_stats_buf->sched_policy));
488 	len += scnprintf(buf + len, buf_len - len,
489 			 "last_sched_cmd_posted_timestamp = %u\n",
490 			 le32_to_cpu(htt_stats_buf->last_sched_cmd_posted_timestamp));
491 	len += scnprintf(buf + len, buf_len - len,
492 			 "last_sched_cmd_compl_timestamp = %u\n",
493 			 le32_to_cpu(htt_stats_buf->last_sched_cmd_compl_timestamp));
494 	len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n",
495 			 le32_to_cpu(htt_stats_buf->sched_2_tac_lwm_count));
496 	len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n",
497 			 le32_to_cpu(htt_stats_buf->sched_2_tac_ring_full));
498 	len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n",
499 			 le32_to_cpu(htt_stats_buf->sched_cmd_post_failure));
500 	len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n",
501 			 le32_to_cpu(htt_stats_buf->num_active_tids));
502 	len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n",
503 			 le32_to_cpu(htt_stats_buf->num_ps_schedules));
504 	len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n",
505 			 le32_to_cpu(htt_stats_buf->sched_cmds_pending));
506 	len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n",
507 			 le32_to_cpu(htt_stats_buf->num_tid_register));
508 	len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n",
509 			 le32_to_cpu(htt_stats_buf->num_tid_unregister));
510 	len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n",
511 			 le32_to_cpu(htt_stats_buf->num_qstats_queried));
512 	len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n",
513 			 le32_to_cpu(htt_stats_buf->qstats_update_pending));
514 	len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n",
515 			 le32_to_cpu(htt_stats_buf->last_qstats_query_timestamp));
516 	len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n",
517 			 le32_to_cpu(htt_stats_buf->num_tqm_cmdq_full));
518 	len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n",
519 			 le32_to_cpu(htt_stats_buf->num_de_sched_algo_trigger));
520 	len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n",
521 			 le32_to_cpu(htt_stats_buf->num_rt_sched_algo_trigger));
522 	len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n",
523 			 le32_to_cpu(htt_stats_buf->num_tqm_sched_algo_trigger));
524 	len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n",
525 			 le32_to_cpu(htt_stats_buf->notify_sched));
526 	len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n",
527 			 le32_to_cpu(htt_stats_buf->dur_based_sendn_term));
528 	len += scnprintf(buf + len, buf_len - len, "su_notify2_sched = %u\n",
529 			 le32_to_cpu(htt_stats_buf->su_notify2_sched));
530 	len += scnprintf(buf + len, buf_len - len, "su_optimal_queued_msdus_sched = %u\n",
531 			 le32_to_cpu(htt_stats_buf->su_optimal_queued_msdus_sched));
532 	len += scnprintf(buf + len, buf_len - len, "su_delay_timeout_sched = %u\n",
533 			 le32_to_cpu(htt_stats_buf->su_delay_timeout_sched));
534 	len += scnprintf(buf + len, buf_len - len, "su_min_txtime_sched_delay = %u\n",
535 			 le32_to_cpu(htt_stats_buf->su_min_txtime_sched_delay));
536 	len += scnprintf(buf + len, buf_len - len, "su_no_delay = %u\n",
537 			 le32_to_cpu(htt_stats_buf->su_no_delay));
538 	len += scnprintf(buf + len, buf_len - len, "num_supercycles = %u\n",
539 			 le32_to_cpu(htt_stats_buf->num_supercycles));
540 	len += scnprintf(buf + len, buf_len - len, "num_subcycles_with_sort = %u\n",
541 			 le32_to_cpu(htt_stats_buf->num_subcycles_with_sort));
542 	len += scnprintf(buf + len, buf_len - len, "num_subcycles_no_sort = %u\n\n",
543 			 le32_to_cpu(htt_stats_buf->num_subcycles_no_sort));
544 
545 	stats_req->buf_len = len;
546 }
547 
548 static void
ath12k_htt_print_sched_txq_cmd_posted_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)549 ath12k_htt_print_sched_txq_cmd_posted_tlv(const void *tag_buf,
550 					  u16 tag_len,
551 					  struct debug_htt_stats_req *stats_req)
552 {
553 	const struct ath12k_htt_sched_txq_cmd_posted_tlv *htt_stats_buf = tag_buf;
554 	u8 *buf = stats_req->buf;
555 	u32 len = stats_req->buf_len;
556 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
557 	u16 num_elements = tag_len >> 2;
558 
559 	len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV:\n");
560 	len += print_array_to_buf(buf, len, "sched_cmd_posted",
561 				  htt_stats_buf->sched_cmd_posted, num_elements, "\n\n");
562 
563 	stats_req->buf_len = len;
564 }
565 
566 static void
ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)567 ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void *tag_buf,
568 					  u16 tag_len,
569 					  struct debug_htt_stats_req *stats_req)
570 {
571 	const struct ath12k_htt_sched_txq_cmd_reaped_tlv *htt_stats_buf = tag_buf;
572 	u8 *buf = stats_req->buf;
573 	u32 len = stats_req->buf_len;
574 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
575 	u16 num_elements = tag_len >> 2;
576 
577 	len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV:\n");
578 	len += print_array_to_buf(buf, len, "sched_cmd_reaped",
579 				  htt_stats_buf->sched_cmd_reaped, num_elements, "\n\n");
580 
581 	stats_req->buf_len = len;
582 }
583 
584 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)585 ath12k_htt_print_sched_txq_sched_order_su_tlv(const void *tag_buf,
586 					      u16 tag_len,
587 					      struct debug_htt_stats_req *stats_req)
588 {
589 	const struct ath12k_htt_sched_txq_sched_order_su_tlv *htt_stats_buf = tag_buf;
590 	u8 *buf = stats_req->buf;
591 	u32 len = stats_req->buf_len;
592 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
593 	u32 sched_order_su_num_entries = min_t(u32, (tag_len >> 2),
594 					       ATH12K_HTT_TX_PDEV_NUM_SCHED_ORDER_LOG);
595 
596 	len += scnprintf(buf + len, buf_len - len,
597 			 "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV:\n");
598 	len += print_array_to_buf(buf, len, "sched_order_su",
599 				  htt_stats_buf->sched_order_su,
600 				  sched_order_su_num_entries, "\n\n");
601 
602 	stats_req->buf_len = len;
603 }
604 
605 static void
ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)606 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void *tag_buf,
607 						   u16 tag_len,
608 						   struct debug_htt_stats_req *stats_req)
609 {
610 	const struct ath12k_htt_sched_txq_sched_ineligibility_tlv *htt_stats_buf =
611 		     tag_buf;
612 	u8 *buf = stats_req->buf;
613 	u32 len = stats_req->buf_len;
614 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
615 	u32 sched_ineligibility_num_entries = tag_len >> 2;
616 
617 	len += scnprintf(buf + len, buf_len - len,
618 			 "HTT_SCHED_TXQ_SCHED_INELIGIBILITY:\n");
619 	len += print_array_to_buf(buf, len, "sched_ineligibility",
620 				  htt_stats_buf->sched_ineligibility,
621 				  sched_ineligibility_num_entries, "\n\n");
622 
623 	stats_req->buf_len = len;
624 }
625 
626 static void
ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)627 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void *tag_buf,
628 						  u16 tag_len,
629 						  struct debug_htt_stats_req *stats_req)
630 {
631 	const struct ath12k_htt_sched_txq_supercycle_triggers_tlv *htt_stats_buf =
632 		     tag_buf;
633 	u8 *buf = stats_req->buf;
634 	u32 len = stats_req->buf_len;
635 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
636 	u16 num_elems = min_t(u16, (tag_len >> 2),
637 			      ATH12K_HTT_SCHED_SUPERCYCLE_TRIGGER_MAX);
638 
639 	len += scnprintf(buf + len, buf_len - len,
640 			 "HTT_SCHED_TXQ_SUPERCYCLE_TRIGGER:\n");
641 	len += print_array_to_buf(buf, len, "supercycle_triggers",
642 				  htt_stats_buf->supercycle_triggers, num_elems, "\n\n");
643 
644 	stats_req->buf_len = len;
645 }
646 
647 static void
ath12k_htt_print_hw_stats_pdev_errs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)648 ath12k_htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf, u16 tag_len,
649 					struct debug_htt_stats_req *stats_req)
650 {
651 	const struct ath12k_htt_hw_stats_pdev_errs_tlv *htt_buf = tag_buf;
652 	u8 *buf = stats_req->buf;
653 	u32 len = stats_req->buf_len;
654 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
655 	u32 mac_id_word;
656 
657 	if (tag_len < sizeof(*htt_buf))
658 		return;
659 
660 	mac_id_word = le32_to_cpu(htt_buf->mac_id__word);
661 
662 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n");
663 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
664 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
665 	len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
666 			 le32_to_cpu(htt_buf->tx_abort));
667 	len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n",
668 			 le32_to_cpu(htt_buf->tx_abort_fail_count));
669 	len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n",
670 			 le32_to_cpu(htt_buf->rx_abort));
671 	len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n",
672 			 le32_to_cpu(htt_buf->rx_abort_fail_count));
673 	len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n",
674 			 le32_to_cpu(htt_buf->rx_flush_cnt));
675 	len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n",
676 			 le32_to_cpu(htt_buf->warm_reset));
677 	len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n",
678 			 le32_to_cpu(htt_buf->cold_reset));
679 	len += scnprintf(buf + len, buf_len - len, "mac_cold_reset_restore_cal = %u\n",
680 			 le32_to_cpu(htt_buf->mac_cold_reset_restore_cal));
681 	len += scnprintf(buf + len, buf_len - len, "mac_cold_reset = %u\n",
682 			 le32_to_cpu(htt_buf->mac_cold_reset));
683 	len += scnprintf(buf + len, buf_len - len, "mac_warm_reset = %u\n",
684 			 le32_to_cpu(htt_buf->mac_warm_reset));
685 	len += scnprintf(buf + len, buf_len - len, "mac_only_reset = %u\n",
686 			 le32_to_cpu(htt_buf->mac_only_reset));
687 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset = %u\n",
688 			 le32_to_cpu(htt_buf->phy_warm_reset));
689 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_ucode_trig = %u\n",
690 			 le32_to_cpu(htt_buf->phy_warm_reset_ucode_trig));
691 	len += scnprintf(buf + len, buf_len - len, "mac_warm_reset_restore_cal = %u\n",
692 			 le32_to_cpu(htt_buf->mac_warm_reset_restore_cal));
693 	len += scnprintf(buf + len, buf_len - len, "mac_sfm_reset = %u\n",
694 			 le32_to_cpu(htt_buf->mac_sfm_reset));
695 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_m3_ssr = %u\n",
696 			 le32_to_cpu(htt_buf->phy_warm_reset_m3_ssr));
697 	len += scnprintf(buf + len, buf_len - len, "fw_rx_rings_reset = %u\n",
698 			 le32_to_cpu(htt_buf->fw_rx_rings_reset));
699 	len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n",
700 			 le32_to_cpu(htt_buf->tx_flush));
701 	len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n",
702 			 le32_to_cpu(htt_buf->tx_glb_reset));
703 	len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n",
704 			 le32_to_cpu(htt_buf->tx_txq_reset));
705 	len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n",
706 			 le32_to_cpu(htt_buf->rx_timeout_reset));
707 
708 	len += scnprintf(buf + len, buf_len - len, "PDEV_PHY_WARM_RESET_REASONS:\n");
709 	len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_reason_phy_m3 = %u\n",
710 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_phy_m3));
711 	len += scnprintf(buf + len, buf_len - len,
712 			 "phy_warm_reset_reason_tx_hw_stuck = %u\n",
713 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hw_stuck));
714 	len += scnprintf(buf + len, buf_len - len,
715 			 "phy_warm_reset_reason_num_cca_rx_frame_stuck = %u\n",
716 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_num_rx_frame_stuck));
717 	len += scnprintf(buf + len, buf_len - len,
718 			 "phy_warm_reset_reason_wal_rx_recovery_rst_rx_busy = %u\n",
719 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_rx_busy));
720 	len += scnprintf(buf + len, buf_len - len,
721 			 "phy_warm_reset_reason_wal_rx_recovery_rst_mac_hang = %u\n",
722 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_mac_hng));
723 	len += scnprintf(buf + len, buf_len - len,
724 			 "phy_warm_reset_reason_mac_reset_converted_phy_reset = %u\n",
725 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_mac_conv_phy_reset));
726 	len += scnprintf(buf + len, buf_len - len,
727 			 "phy_warm_reset_reason_tx_lifetime_expiry_cca_stuck = %u\n",
728 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_exp_cca_stuck));
729 	len += scnprintf(buf + len, buf_len - len,
730 			 "phy_warm_reset_reason_tx_consecutive_flush9_war = %u\n",
731 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_consec_flsh_war));
732 	len += scnprintf(buf + len, buf_len - len,
733 			 "phy_warm_reset_reason_tx_hwsch_reset_war = %u\n",
734 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hwsch_reset_war));
735 	len += scnprintf(buf + len, buf_len - len,
736 			 "phy_warm_reset_reason_hwsch_wdog_or_cca_wdog_war = %u\n\n",
737 			 le32_to_cpu(htt_buf->phy_warm_reset_reason_hwsch_cca_wdog_war));
738 
739 	len += scnprintf(buf + len, buf_len - len, "WAL_RX_RECOVERY_STATS:\n");
740 	len += scnprintf(buf + len, buf_len - len,
741 			 "wal_rx_recovery_rst_mac_hang_count = %u\n",
742 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_mac_hang_cnt));
743 	len += scnprintf(buf + len, buf_len - len,
744 			 "wal_rx_recovery_rst_known_sig_count = %u\n",
745 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_known_sig_cnt));
746 	len += scnprintf(buf + len, buf_len - len,
747 			 "wal_rx_recovery_rst_no_rx_count = %u\n",
748 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_cnt));
749 	len += scnprintf(buf + len, buf_len - len,
750 			 "wal_rx_recovery_rst_no_rx_consecutive_count = %u\n",
751 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_consec_cnt));
752 	len += scnprintf(buf + len, buf_len - len,
753 			 "wal_rx_recovery_rst_rx_busy_count = %u\n",
754 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_rx_busy_cnt));
755 	len += scnprintf(buf + len, buf_len - len,
756 			 "wal_rx_recovery_rst_phy_mac_hang_count = %u\n\n",
757 			 le32_to_cpu(htt_buf->wal_rx_recovery_rst_phy_mac_hang_cnt));
758 
759 	len += scnprintf(buf + len, buf_len - len, "HTT_RX_DEST_DRAIN_STATS:\n");
760 	len += scnprintf(buf + len, buf_len - len,
761 			 "rx_dest_drain_rx_descs_leak_prevention_done = %u\n",
762 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_leak_prevented));
763 	len += scnprintf(buf + len, buf_len - len,
764 			 "rx_dest_drain_rx_descs_saved_cnt = %u\n",
765 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_saved_cnt));
766 	len += scnprintf(buf + len, buf_len - len,
767 			 "rx_dest_drain_rxdma2reo_leak_detected = %u\n",
768 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2reo_leak_detected));
769 	len += scnprintf(buf + len, buf_len - len,
770 			 "rx_dest_drain_rxdma2fw_leak_detected = %u\n",
771 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2fw_leak_detected));
772 	len += scnprintf(buf + len, buf_len - len,
773 			 "rx_dest_drain_rxdma2wbm_leak_detected = %u\n",
774 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2wbm_leak_detected));
775 	len += scnprintf(buf + len, buf_len - len,
776 			 "rx_dest_drain_rxdma1_2sw_leak_detected = %u\n",
777 			 le32_to_cpu(htt_buf->rx_dest_drain_rxdma1_2sw_leak_detected));
778 	len += scnprintf(buf + len, buf_len - len,
779 			 "rx_dest_drain_rx_drain_ok_mac_idle = %u\n",
780 			 le32_to_cpu(htt_buf->rx_dest_drain_rx_drain_ok_mac_idle));
781 	len += scnprintf(buf + len, buf_len - len,
782 			 "rx_dest_drain_ok_mac_not_idle = %u\n",
783 			 le32_to_cpu(htt_buf->rx_dest_drain_ok_mac_not_idle));
784 	len += scnprintf(buf + len, buf_len - len,
785 			 "rx_dest_drain_prerequisite_invld = %u\n",
786 			 le32_to_cpu(htt_buf->rx_dest_drain_prerequisite_invld));
787 	len += scnprintf(buf + len, buf_len - len,
788 			 "rx_dest_drain_skip_for_non_lmac_reset = %u\n",
789 			 le32_to_cpu(htt_buf->rx_dest_drain_skip_non_lmac_reset));
790 	len += scnprintf(buf + len, buf_len - len,
791 			 "rx_dest_drain_hw_fifo_not_empty_post_drain_wait = %u\n\n",
792 			 le32_to_cpu(htt_buf->rx_dest_drain_hw_fifo_notempty_post_wait));
793 
794 	stats_req->buf_len = len;
795 }
796 
797 static void
ath12k_htt_print_hw_stats_intr_misc_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)798 ath12k_htt_print_hw_stats_intr_misc_tlv(const void *tag_buf, u16 tag_len,
799 					struct debug_htt_stats_req *stats_req)
800 {
801 	const struct ath12k_htt_hw_stats_intr_misc_tlv *htt_stats_buf = tag_buf;
802 	u8 *buf = stats_req->buf;
803 	u32 len = stats_req->buf_len;
804 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
805 
806 	if (tag_len < sizeof(*htt_stats_buf))
807 		return;
808 
809 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n");
810 	len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n",
811 			 htt_stats_buf->hw_intr_name);
812 	len += scnprintf(buf + len, buf_len - len, "mask = %u\n",
813 			 le32_to_cpu(htt_stats_buf->mask));
814 	len += scnprintf(buf + len, buf_len - len, "count = %u\n\n",
815 			 le32_to_cpu(htt_stats_buf->count));
816 
817 	stats_req->buf_len = len;
818 }
819 
820 static void
ath12k_htt_print_hw_stats_whal_tx_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)821 ath12k_htt_print_hw_stats_whal_tx_tlv(const void *tag_buf, u16 tag_len,
822 				      struct debug_htt_stats_req *stats_req)
823 {
824 	const struct ath12k_htt_hw_stats_whal_tx_tlv *htt_stats_buf = tag_buf;
825 	u8 *buf = stats_req->buf;
826 	u32 len = stats_req->buf_len;
827 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
828 	u32 mac_id_word;
829 
830 	if (tag_len < sizeof(*htt_stats_buf))
831 		return;
832 
833 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
834 
835 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n");
836 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
837 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
838 	len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n",
839 			 le32_to_cpu(htt_stats_buf->last_unpause_ppdu_id));
840 	len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n",
841 			 le32_to_cpu(htt_stats_buf->hwsch_unpause_wait_tqm_write));
842 	len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n",
843 			 le32_to_cpu(htt_stats_buf->hwsch_dummy_tlv_skipped));
844 	len += scnprintf(buf + len, buf_len - len,
845 			 "hwsch_misaligned_offset_received = %u\n",
846 			 le32_to_cpu(htt_stats_buf->hwsch_misaligned_offset_received));
847 	len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n",
848 			 le32_to_cpu(htt_stats_buf->hwsch_reset_count));
849 	len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n",
850 			 le32_to_cpu(htt_stats_buf->hwsch_dev_reset_war));
851 	len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n",
852 			 le32_to_cpu(htt_stats_buf->hwsch_delayed_pause));
853 	len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n",
854 			 le32_to_cpu(htt_stats_buf->hwsch_long_delayed_pause));
855 	len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n",
856 			 le32_to_cpu(htt_stats_buf->sch_rx_ppdu_no_response));
857 	len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n",
858 			 le32_to_cpu(htt_stats_buf->sch_selfgen_response));
859 	len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n",
860 			 le32_to_cpu(htt_stats_buf->sch_rx_sifs_resp_trigger));
861 
862 	stats_req->buf_len = len;
863 }
864 
865 static void
ath12k_htt_print_hw_war_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)866 ath12k_htt_print_hw_war_tlv(const void *tag_buf, u16 tag_len,
867 			    struct debug_htt_stats_req *stats_req)
868 {
869 	const struct ath12k_htt_hw_war_stats_tlv *htt_stats_buf = tag_buf;
870 	u8 *buf = stats_req->buf;
871 	u32 len = stats_req->buf_len;
872 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
873 	u16 fixed_len, array_len;
874 	u8 i, array_words;
875 	u32 mac_id;
876 
877 	if (tag_len < sizeof(*htt_stats_buf))
878 		return;
879 
880 	mac_id = __le32_to_cpu(htt_stats_buf->mac_id__word);
881 	fixed_len = sizeof(*htt_stats_buf);
882 	array_len = tag_len - fixed_len;
883 	array_words = array_len >> 2;
884 
885 	len += scnprintf(buf + len, buf_len - len, "HTT_HW_WAR_STATS_TLV:\n");
886 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
887 			 u32_get_bits(mac_id, ATH12K_HTT_STATS_MAC_ID));
888 
889 	for (i = 0; i < array_words; i++) {
890 		len += scnprintf(buf + len, buf_len - len, "hw_war %u = %u\n\n",
891 				 i, le32_to_cpu(htt_stats_buf->hw_wars[i]));
892 	}
893 
894 	stats_req->buf_len = len;
895 }
896 
897 static void
ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)898 ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
899 				      struct debug_htt_stats_req *stats_req)
900 {
901 	const struct ath12k_htt_tx_tqm_cmn_stats_tlv *htt_stats_buf = tag_buf;
902 	u8 *buf = stats_req->buf;
903 	u32 len = stats_req->buf_len;
904 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
905 	u32 mac_id_word;
906 
907 	if (tag_len < sizeof(*htt_stats_buf))
908 		return;
909 
910 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
911 
912 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n");
913 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
914 			u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
915 	len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n",
916 			 le32_to_cpu(htt_stats_buf->max_cmdq_id));
917 	len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n",
918 			 le32_to_cpu(htt_stats_buf->list_mpdu_cnt_hist_intvl));
919 	len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n",
920 			 le32_to_cpu(htt_stats_buf->add_msdu));
921 	len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n",
922 			 le32_to_cpu(htt_stats_buf->q_empty));
923 	len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n",
924 			 le32_to_cpu(htt_stats_buf->q_not_empty));
925 	len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n",
926 			 le32_to_cpu(htt_stats_buf->drop_notification));
927 	len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n",
928 			 le32_to_cpu(htt_stats_buf->desc_threshold));
929 	len += scnprintf(buf + len, buf_len - len, "hwsch_tqm_invalid_status = %u\n",
930 			 le32_to_cpu(htt_stats_buf->hwsch_tqm_invalid_status));
931 	len += scnprintf(buf + len, buf_len - len, "missed_tqm_gen_mpdus = %u\n",
932 			 le32_to_cpu(htt_stats_buf->missed_tqm_gen_mpdus));
933 	len += scnprintf(buf + len, buf_len - len,
934 			 "total_msduq_timestamp_updates = %u\n",
935 			 le32_to_cpu(htt_stats_buf->msduq_timestamp_updates));
936 	len += scnprintf(buf + len, buf_len - len,
937 			 "total_msduq_timestamp_updates_by_get_mpdu_head_info_cmd = %u\n",
938 			 le32_to_cpu(htt_stats_buf->msduq_updates_mpdu_head_info_cmd));
939 	len += scnprintf(buf + len, buf_len - len,
940 			 "total_msduq_timestamp_updates_by_emp_to_nonemp_status = %u\n",
941 			 le32_to_cpu(htt_stats_buf->msduq_updates_emp_to_nonemp_status));
942 	len += scnprintf(buf + len, buf_len - len,
943 			 "total_get_mpdu_head_info_cmds_by_sched_algo_la_query = %u\n",
944 			 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_query));
945 	len += scnprintf(buf + len, buf_len - len,
946 			 "total_get_mpdu_head_info_cmds_by_tac = %u\n",
947 			 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_tac));
948 	len += scnprintf(buf + len, buf_len - len,
949 			 "total_gen_mpdu_cmds_by_sched_algo_la_query = %u\n",
950 			 le32_to_cpu(htt_stats_buf->gen_mpdu_cmds_by_query));
951 	len += scnprintf(buf + len, buf_len - len, "active_tqm_tids = %u\n",
952 			 le32_to_cpu(htt_stats_buf->tqm_active_tids));
953 	len += scnprintf(buf + len, buf_len - len, "inactive_tqm_tids = %u\n",
954 			 le32_to_cpu(htt_stats_buf->tqm_inactive_tids));
955 	len += scnprintf(buf + len, buf_len - len, "tqm_active_msduq_flows = %u\n",
956 			 le32_to_cpu(htt_stats_buf->tqm_active_msduq_flows));
957 	len += scnprintf(buf + len, buf_len - len, "hi_prio_q_not_empty = %u\n\n",
958 			 le32_to_cpu(htt_stats_buf->high_prio_q_not_empty));
959 
960 	stats_req->buf_len = len;
961 }
962 
963 static void
ath12k_htt_print_tx_tqm_error_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)964 ath12k_htt_print_tx_tqm_error_stats_tlv(const void *tag_buf, u16 tag_len,
965 					struct debug_htt_stats_req *stats_req)
966 {
967 	const struct ath12k_htt_tx_tqm_error_stats_tlv *htt_stats_buf = tag_buf;
968 	u8 *buf = stats_req->buf;
969 	u32 len = stats_req->buf_len;
970 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
971 
972 	if (tag_len < sizeof(*htt_stats_buf))
973 		return;
974 
975 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n");
976 	len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n",
977 			 le32_to_cpu(htt_stats_buf->q_empty_failure));
978 	len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n",
979 			 le32_to_cpu(htt_stats_buf->q_not_empty_failure));
980 	len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n",
981 			 le32_to_cpu(htt_stats_buf->add_msdu_failure));
982 
983 	len += scnprintf(buf + len, buf_len - len, "TQM_ERROR_RESET_STATS:\n");
984 	len += scnprintf(buf + len, buf_len - len, "tqm_cache_ctl_err = %u\n",
985 			 le32_to_cpu(htt_stats_buf->tqm_cache_ctl_err));
986 	len += scnprintf(buf + len, buf_len - len, "tqm_soft_reset = %u\n",
987 			 le32_to_cpu(htt_stats_buf->tqm_soft_reset));
988 	len += scnprintf(buf + len, buf_len - len,
989 			 "tqm_reset_total_num_in_use_link_descs = %u\n",
990 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_link_descs));
991 	len += scnprintf(buf + len, buf_len - len,
992 			 "tqm_reset_worst_case_num_lost_link_descs = %u\n",
993 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_link_descs));
994 	len += scnprintf(buf + len, buf_len - len,
995 			 "tqm_reset_worst_case_num_lost_host_tx_bufs_count = %u\n",
996 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_host_tx_buf_cnt));
997 	len += scnprintf(buf + len, buf_len - len,
998 			 "tqm_reset_num_in_use_link_descs_internal_tqm = %u\n",
999 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_internal_tqm));
1000 	len += scnprintf(buf + len, buf_len - len,
1001 			 "tqm_reset_num_in_use_link_descs_wbm_idle_link_ring = %u\n",
1002 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_idle_link_rng));
1003 	len += scnprintf(buf + len, buf_len - len,
1004 			 "tqm_reset_time_to_tqm_hang_delta_ms = %u\n",
1005 			 le32_to_cpu(htt_stats_buf->tqm_reset_time_to_tqm_hang_delta_ms));
1006 	len += scnprintf(buf + len, buf_len - len, "tqm_reset_recovery_time_ms = %u\n",
1007 			 le32_to_cpu(htt_stats_buf->tqm_reset_recovery_time_ms));
1008 	len += scnprintf(buf + len, buf_len - len, "tqm_reset_num_peers_hdl = %u\n",
1009 			 le32_to_cpu(htt_stats_buf->tqm_reset_num_peers_hdl));
1010 	len += scnprintf(buf + len, buf_len - len,
1011 			 "tqm_reset_cumm_dirty_hw_mpduq_proc_cnt = %u\n",
1012 			 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_mpduq_cnt));
1013 	len += scnprintf(buf + len, buf_len - len,
1014 			 "tqm_reset_cumm_dirty_hw_msduq_proc = %u\n",
1015 			 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_msduq_proc));
1016 	len += scnprintf(buf + len, buf_len - len,
1017 			 "tqm_reset_flush_cache_cmd_su_cnt = %u\n",
1018 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_su_cnt));
1019 	len += scnprintf(buf + len, buf_len - len,
1020 			 "tqm_reset_flush_cache_cmd_other_cnt = %u\n",
1021 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_other_cnt));
1022 	len += scnprintf(buf + len, buf_len - len,
1023 			 "tqm_reset_flush_cache_cmd_trig_type = %u\n",
1024 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_type));
1025 	len += scnprintf(buf + len, buf_len - len,
1026 			 "tqm_reset_flush_cache_cmd_trig_cfg = %u\n",
1027 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_cfg));
1028 	len += scnprintf(buf + len, buf_len - len,
1029 			 "tqm_reset_flush_cache_cmd_skip_cmd_status_null = %u\n\n",
1030 			 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cmd_skp_status_null));
1031 
1032 	stats_req->buf_len = len;
1033 }
1034 
1035 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)1036 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
1037 					   struct debug_htt_stats_req *stats_req)
1038 {
1039 	const struct ath12k_htt_tx_tqm_gen_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1040 	u8 *buf = stats_req->buf;
1041 	u32 len = stats_req->buf_len;
1042 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1043 	u16 num_elements = tag_len >> 2;
1044 
1045 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV:\n");
1046 	len += print_array_to_buf(buf, len, "gen_mpdu_end_reason",
1047 				  htt_stats_buf->gen_mpdu_end_reason, num_elements,
1048 				  "\n\n");
1049 
1050 	stats_req->buf_len = len;
1051 }
1052 
1053 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)1054 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
1055 					    struct debug_htt_stats_req *stats_req)
1056 {
1057 	const struct ath12k_htt_tx_tqm_list_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1058 	u8 *buf = stats_req->buf;
1059 	u32 len = stats_req->buf_len;
1060 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1061 	u16 num_elems = min_t(u16, (tag_len >> 2),
1062 			      ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_END_REASON);
1063 
1064 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_STATS_TLV:\n");
1065 	len += print_array_to_buf(buf, len, "list_mpdu_end_reason",
1066 				  htt_stats_buf->list_mpdu_end_reason, num_elems, "\n\n");
1067 
1068 	stats_req->buf_len = len;
1069 }
1070 
1071 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)1072 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void *tag_buf, u16 tag_len,
1073 					  struct debug_htt_stats_req *stats_req)
1074 {
1075 	const struct ath12k_htt_tx_tqm_list_mpdu_cnt_tlv *htt_stats_buf = tag_buf;
1076 	u8 *buf = stats_req->buf;
1077 	u32 len = stats_req->buf_len;
1078 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1079 	u16 num_elems = min_t(u16, (tag_len >> 2),
1080 			      ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS);
1081 
1082 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n");
1083 	len += print_array_to_buf(buf, len, "list_mpdu_cnt_hist",
1084 				  htt_stats_buf->list_mpdu_cnt_hist, num_elems, "\n\n");
1085 
1086 	stats_req->buf_len = len;
1087 }
1088 
1089 static void
ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1090 ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void *tag_buf, u16 tag_len,
1091 				       struct debug_htt_stats_req *stats_req)
1092 {
1093 	const struct ath12k_htt_tx_tqm_pdev_stats_tlv *htt_stats_buf = tag_buf;
1094 	u8 *buf = stats_req->buf;
1095 	u32 len = stats_req->buf_len;
1096 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1097 
1098 	if (tag_len < sizeof(*htt_stats_buf))
1099 		return;
1100 
1101 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n");
1102 	len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n",
1103 			 le32_to_cpu(htt_stats_buf->msdu_count));
1104 	len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n",
1105 			 le32_to_cpu(htt_stats_buf->mpdu_count));
1106 	len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n",
1107 			 le32_to_cpu(htt_stats_buf->remove_msdu));
1108 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n",
1109 			 le32_to_cpu(htt_stats_buf->remove_mpdu));
1110 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n",
1111 			 le32_to_cpu(htt_stats_buf->remove_msdu_ttl));
1112 	len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n",
1113 			 le32_to_cpu(htt_stats_buf->send_bar));
1114 	len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n",
1115 			 le32_to_cpu(htt_stats_buf->bar_sync));
1116 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n",
1117 			 le32_to_cpu(htt_stats_buf->notify_mpdu));
1118 	len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
1119 			 le32_to_cpu(htt_stats_buf->sync_cmd));
1120 	len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
1121 			 le32_to_cpu(htt_stats_buf->write_cmd));
1122 	len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n",
1123 			 le32_to_cpu(htt_stats_buf->hwsch_trigger));
1124 	len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
1125 			 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
1126 	len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n",
1127 			 le32_to_cpu(htt_stats_buf->gen_mpdu_cmd));
1128 	len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n",
1129 			 le32_to_cpu(htt_stats_buf->gen_list_cmd));
1130 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n",
1131 			 le32_to_cpu(htt_stats_buf->remove_mpdu_cmd));
1132 	len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n",
1133 			 le32_to_cpu(htt_stats_buf->remove_mpdu_tried_cmd));
1134 	len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n",
1135 			 le32_to_cpu(htt_stats_buf->mpdu_queue_stats_cmd));
1136 	len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n",
1137 			 le32_to_cpu(htt_stats_buf->mpdu_head_info_cmd));
1138 	len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n",
1139 			 le32_to_cpu(htt_stats_buf->msdu_flow_stats_cmd));
1140 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n",
1141 			 le32_to_cpu(htt_stats_buf->remove_msdu_cmd));
1142 	len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n",
1143 			 le32_to_cpu(htt_stats_buf->remove_msdu_ttl_cmd));
1144 	len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n",
1145 			 le32_to_cpu(htt_stats_buf->flush_cache_cmd));
1146 	len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n",
1147 			 le32_to_cpu(htt_stats_buf->update_mpduq_cmd));
1148 	len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n",
1149 			 le32_to_cpu(htt_stats_buf->enqueue));
1150 	len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n",
1151 			 le32_to_cpu(htt_stats_buf->enqueue_notify));
1152 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n",
1153 			 le32_to_cpu(htt_stats_buf->notify_mpdu_at_head));
1154 	len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n",
1155 			 le32_to_cpu(htt_stats_buf->notify_mpdu_state_valid));
1156 	len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n",
1157 			 le32_to_cpu(htt_stats_buf->sched_udp_notify1));
1158 	len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n",
1159 			 le32_to_cpu(htt_stats_buf->sched_udp_notify2));
1160 	len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n",
1161 			 le32_to_cpu(htt_stats_buf->sched_nonudp_notify1));
1162 	len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n",
1163 			 le32_to_cpu(htt_stats_buf->sched_nonudp_notify2));
1164 
1165 	stats_req->buf_len = len;
1166 }
1167 
1168 static void
ath12k_htt_print_tx_de_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1169 ath12k_htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
1170 				     struct debug_htt_stats_req *stats_req)
1171 {
1172 	const struct ath12k_htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf;
1173 	u8 *buf = stats_req->buf;
1174 	u32 len = stats_req->buf_len;
1175 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1176 	u32 mac_id_word;
1177 
1178 	if (tag_len < sizeof(*htt_stats_buf))
1179 		return;
1180 
1181 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
1182 
1183 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
1184 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
1185 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
1186 	len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
1187 			 le32_to_cpu(htt_stats_buf->tcl2fw_entry_count));
1188 	len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
1189 			 le32_to_cpu(htt_stats_buf->not_to_fw));
1190 	len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n",
1191 			 le32_to_cpu(htt_stats_buf->invalid_pdev_vdev_peer));
1192 	len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n",
1193 			 le32_to_cpu(htt_stats_buf->tcl_res_invalid_addrx));
1194 	len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n",
1195 			 le32_to_cpu(htt_stats_buf->wbm2fw_entry_count));
1196 	len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n",
1197 			 le32_to_cpu(htt_stats_buf->invalid_pdev));
1198 	len += scnprintf(buf + len, buf_len - len, "tcl_res_addrx_timeout = %u\n",
1199 			 le32_to_cpu(htt_stats_buf->tcl_res_addrx_timeout));
1200 	len += scnprintf(buf + len, buf_len - len, "invalid_vdev = %u\n",
1201 			 le32_to_cpu(htt_stats_buf->invalid_vdev));
1202 	len += scnprintf(buf + len, buf_len - len, "invalid_tcl_exp_frame_desc = %u\n",
1203 			 le32_to_cpu(htt_stats_buf->invalid_tcl_exp_frame_desc));
1204 	len += scnprintf(buf + len, buf_len - len, "vdev_id_mismatch_count = %u\n\n",
1205 			 le32_to_cpu(htt_stats_buf->vdev_id_mismatch_cnt));
1206 
1207 	stats_req->buf_len = len;
1208 }
1209 
1210 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)1211 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1212 					       struct debug_htt_stats_req *stats_req)
1213 {
1214 	const struct ath12k_htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf;
1215 	u8 *buf = stats_req->buf;
1216 	u32 len = stats_req->buf_len;
1217 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1218 
1219 	if (tag_len < sizeof(*htt_stats_buf))
1220 		return;
1221 
1222 	len += scnprintf(buf + len, buf_len - len,
1223 			 "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n");
1224 	len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n",
1225 			 le32_to_cpu(htt_stats_buf->m1_packets));
1226 	len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n",
1227 			 le32_to_cpu(htt_stats_buf->m2_packets));
1228 	len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n",
1229 			 le32_to_cpu(htt_stats_buf->m3_packets));
1230 	len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n",
1231 			 le32_to_cpu(htt_stats_buf->m4_packets));
1232 	len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n",
1233 			 le32_to_cpu(htt_stats_buf->g1_packets));
1234 	len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n",
1235 			 le32_to_cpu(htt_stats_buf->g2_packets));
1236 	len += scnprintf(buf + len, buf_len - len, "rc4_packets = %u\n",
1237 			 le32_to_cpu(htt_stats_buf->rc4_packets));
1238 	len += scnprintf(buf + len, buf_len - len, "eap_packets = %u\n",
1239 			 le32_to_cpu(htt_stats_buf->eap_packets));
1240 	len += scnprintf(buf + len, buf_len - len, "eapol_start_packets = %u\n",
1241 			 le32_to_cpu(htt_stats_buf->eapol_start_packets));
1242 	len += scnprintf(buf + len, buf_len - len, "eapol_logoff_packets = %u\n",
1243 			 le32_to_cpu(htt_stats_buf->eapol_logoff_packets));
1244 	len += scnprintf(buf + len, buf_len - len, "eapol_encap_asf_packets = %u\n\n",
1245 			 le32_to_cpu(htt_stats_buf->eapol_encap_asf_packets));
1246 
1247 	stats_req->buf_len = len;
1248 }
1249 
1250 static void
ath12k_htt_print_tx_de_classify_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1251 ath12k_htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u16 tag_len,
1252 					  struct debug_htt_stats_req *stats_req)
1253 {
1254 	const struct ath12k_htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf;
1255 	u8 *buf = stats_req->buf;
1256 	u32 len = stats_req->buf_len;
1257 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1258 
1259 	if (tag_len < sizeof(*htt_stats_buf))
1260 		return;
1261 
1262 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n");
1263 	len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n",
1264 			 le32_to_cpu(htt_stats_buf->arp_packets));
1265 	len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n",
1266 			 le32_to_cpu(htt_stats_buf->igmp_packets));
1267 	len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n",
1268 			 le32_to_cpu(htt_stats_buf->dhcp_packets));
1269 	len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n",
1270 			 le32_to_cpu(htt_stats_buf->host_inspected));
1271 	len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n",
1272 			 le32_to_cpu(htt_stats_buf->htt_included));
1273 	len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n",
1274 			 le32_to_cpu(htt_stats_buf->htt_valid_mcs));
1275 	len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n",
1276 			 le32_to_cpu(htt_stats_buf->htt_valid_nss));
1277 	len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n",
1278 			 le32_to_cpu(htt_stats_buf->htt_valid_preamble_type));
1279 	len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n",
1280 			 le32_to_cpu(htt_stats_buf->htt_valid_chainmask));
1281 	len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n",
1282 			 le32_to_cpu(htt_stats_buf->htt_valid_guard_interval));
1283 	len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n",
1284 			 le32_to_cpu(htt_stats_buf->htt_valid_retries));
1285 	len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n",
1286 			 le32_to_cpu(htt_stats_buf->htt_valid_bw_info));
1287 	len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n",
1288 			 le32_to_cpu(htt_stats_buf->htt_valid_power));
1289 	len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n",
1290 			 le32_to_cpu(htt_stats_buf->htt_valid_key_flags));
1291 	len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n",
1292 			 le32_to_cpu(htt_stats_buf->htt_valid_no_encryption));
1293 	len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n",
1294 			 le32_to_cpu(htt_stats_buf->fse_entry_count));
1295 	len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n",
1296 			 le32_to_cpu(htt_stats_buf->fse_priority_be));
1297 	len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n",
1298 			 le32_to_cpu(htt_stats_buf->fse_priority_high));
1299 	len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n",
1300 			 le32_to_cpu(htt_stats_buf->fse_priority_low));
1301 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n",
1302 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_be));
1303 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n",
1304 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_over_sub));
1305 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n",
1306 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_bursty));
1307 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n",
1308 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_interactive));
1309 	len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n",
1310 			 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_periodic));
1311 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n",
1312 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_alloc));
1313 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n",
1314 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_created));
1315 	len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n",
1316 			 le32_to_cpu(htt_stats_buf->fse_hwqueue_send_to_host));
1317 	len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n",
1318 			 le32_to_cpu(htt_stats_buf->mcast_entry));
1319 	len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n",
1320 			 le32_to_cpu(htt_stats_buf->bcast_entry));
1321 	len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n",
1322 			 le32_to_cpu(htt_stats_buf->htt_update_peer_cache));
1323 	len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n",
1324 			 le32_to_cpu(htt_stats_buf->htt_learning_frame));
1325 	len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n",
1326 			 le32_to_cpu(htt_stats_buf->fse_invalid_peer));
1327 	len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n",
1328 			 le32_to_cpu(htt_stats_buf->mec_notify));
1329 
1330 	stats_req->buf_len = len;
1331 }
1332 
1333 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)1334 ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u16 tag_len,
1335 						 struct debug_htt_stats_req *stats_req)
1336 {
1337 	const struct ath12k_htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf;
1338 	u8 *buf = stats_req->buf;
1339 	u32 len = stats_req->buf_len;
1340 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1341 
1342 	if (tag_len < sizeof(*htt_stats_buf))
1343 		return;
1344 
1345 	len += scnprintf(buf + len, buf_len - len,
1346 			 "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n");
1347 	len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n",
1348 			 le32_to_cpu(htt_stats_buf->ap_bss_peer_not_found));
1349 	len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n",
1350 			 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_no_peer));
1351 	len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n",
1352 			 le32_to_cpu(htt_stats_buf->sta_delete_in_progress));
1353 	len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n",
1354 			 le32_to_cpu(htt_stats_buf->ibss_no_bss_peer));
1355 	len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n",
1356 			 le32_to_cpu(htt_stats_buf->invalid_vdev_type));
1357 	len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n",
1358 			 le32_to_cpu(htt_stats_buf->invalid_ast_peer_entry));
1359 	len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n",
1360 			 le32_to_cpu(htt_stats_buf->peer_entry_invalid));
1361 	len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n",
1362 			 le32_to_cpu(htt_stats_buf->ethertype_not_ip));
1363 	len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n",
1364 			 le32_to_cpu(htt_stats_buf->eapol_lookup_failed));
1365 	len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n",
1366 			 le32_to_cpu(htt_stats_buf->qpeer_not_allow_data));
1367 	len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n",
1368 			 le32_to_cpu(htt_stats_buf->fse_tid_override));
1369 	len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n",
1370 			 le32_to_cpu(htt_stats_buf->ipv6_jumbogram_zero_length));
1371 	len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n",
1372 			 le32_to_cpu(htt_stats_buf->qos_to_non_qos_in_prog));
1373 	len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_eapol = %u\n",
1374 			 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_eapol));
1375 	len += scnprintf(buf + len, buf_len - len, "unicast_on_ap_bss_peer = %u\n",
1376 			 le32_to_cpu(htt_stats_buf->unicast_on_ap_bss_peer));
1377 	len += scnprintf(buf + len, buf_len - len, "ap_vdev_invalid = %u\n",
1378 			 le32_to_cpu(htt_stats_buf->ap_vdev_invalid));
1379 	len += scnprintf(buf + len, buf_len - len, "incomplete_llc = %u\n",
1380 			 le32_to_cpu(htt_stats_buf->incomplete_llc));
1381 	len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m3 = %u\n",
1382 			 le32_to_cpu(htt_stats_buf->eapol_duplicate_m3));
1383 	len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m4 = %u\n\n",
1384 			 le32_to_cpu(htt_stats_buf->eapol_duplicate_m4));
1385 
1386 	stats_req->buf_len = len;
1387 }
1388 
1389 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)1390 ath12k_htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u16 tag_len,
1391 						 struct debug_htt_stats_req *stats_req)
1392 {
1393 	const struct ath12k_htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf;
1394 	u8 *buf = stats_req->buf;
1395 	u32 len = stats_req->buf_len;
1396 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1397 
1398 	if (tag_len < sizeof(*htt_stats_buf))
1399 		return;
1400 
1401 	len += scnprintf(buf + len, buf_len - len,
1402 			 "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n");
1403 	len += scnprintf(buf + len, buf_len - len, "eok = %u\n",
1404 			 le32_to_cpu(htt_stats_buf->eok));
1405 	len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n",
1406 			 le32_to_cpu(htt_stats_buf->classify_done));
1407 	len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n",
1408 			 le32_to_cpu(htt_stats_buf->lookup_failed));
1409 	len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n",
1410 			 le32_to_cpu(htt_stats_buf->send_host_dhcp));
1411 	len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n",
1412 			 le32_to_cpu(htt_stats_buf->send_host_mcast));
1413 	len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n",
1414 			 le32_to_cpu(htt_stats_buf->send_host_unknown_dest));
1415 	len += scnprintf(buf + len, buf_len - len, "send_host = %u\n",
1416 			 le32_to_cpu(htt_stats_buf->send_host));
1417 	len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n",
1418 			 le32_to_cpu(htt_stats_buf->status_invalid));
1419 
1420 	stats_req->buf_len = len;
1421 }
1422 
1423 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)1424 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1425 						 struct debug_htt_stats_req *stats_req)
1426 {
1427 	const struct ath12k_htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf;
1428 	u8 *buf = stats_req->buf;
1429 	u32 len = stats_req->buf_len;
1430 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1431 
1432 	if (tag_len < sizeof(*htt_stats_buf))
1433 		return;
1434 
1435 	len += scnprintf(buf + len, buf_len - len,
1436 			 "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n");
1437 	len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n",
1438 			 le32_to_cpu(htt_stats_buf->enqueued_pkts));
1439 	len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n",
1440 			 le32_to_cpu(htt_stats_buf->to_tqm));
1441 	len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n",
1442 			 le32_to_cpu(htt_stats_buf->to_tqm_bypass));
1443 
1444 	stats_req->buf_len = len;
1445 }
1446 
1447 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)1448 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u16 tag_len,
1449 						 struct debug_htt_stats_req *stats_req)
1450 {
1451 	const struct ath12k_htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf;
1452 	u8 *buf = stats_req->buf;
1453 	u32 len = stats_req->buf_len;
1454 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1455 
1456 	if (tag_len < sizeof(*htt_stats_buf))
1457 		return;
1458 
1459 	len += scnprintf(buf + len, buf_len - len,
1460 			 "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n");
1461 	len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n",
1462 			 le32_to_cpu(htt_stats_buf->discarded_pkts));
1463 	len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n",
1464 			 le32_to_cpu(htt_stats_buf->local_frames));
1465 	len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n",
1466 			 le32_to_cpu(htt_stats_buf->is_ext_msdu));
1467 
1468 	stats_req->buf_len = len;
1469 }
1470 
1471 static void
ath12k_htt_print_tx_de_compl_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1472 ath12k_htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u16 tag_len,
1473 				       struct debug_htt_stats_req *stats_req)
1474 {
1475 	const struct ath12k_htt_tx_de_compl_stats_tlv *htt_stats_buf = tag_buf;
1476 	u8 *buf = stats_req->buf;
1477 	u32 len = stats_req->buf_len;
1478 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1479 
1480 	if (tag_len < sizeof(*htt_stats_buf))
1481 		return;
1482 
1483 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n");
1484 	len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n",
1485 			 le32_to_cpu(htt_stats_buf->tcl_dummy_frame));
1486 	len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n",
1487 			 le32_to_cpu(htt_stats_buf->tqm_dummy_frame));
1488 	len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n",
1489 			 le32_to_cpu(htt_stats_buf->tqm_notify_frame));
1490 	len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n",
1491 			 le32_to_cpu(htt_stats_buf->fw2wbm_enq));
1492 	len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n",
1493 			 le32_to_cpu(htt_stats_buf->tqm_bypass_frame));
1494 
1495 	stats_req->buf_len = len;
1496 }
1497 
1498 static void
ath12k_htt_print_tx_selfgen_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1499 ath12k_htt_print_tx_selfgen_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
1500 					  struct debug_htt_stats_req *stats_req)
1501 {
1502 	const struct ath12k_htt_tx_selfgen_cmn_stats_tlv *htt_stats_buf = tag_buf;
1503 	u8 *buf = stats_req->buf;
1504 	u32 len = stats_req->buf_len;
1505 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1506 	u32 mac_id_word;
1507 
1508 	if (tag_len < sizeof(*htt_stats_buf))
1509 		return;
1510 
1511 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
1512 
1513 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:\n");
1514 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
1515 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
1516 	len += scnprintf(buf + len, buf_len - len, "su_bar = %u\n",
1517 			 le32_to_cpu(htt_stats_buf->su_bar));
1518 	len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
1519 			 le32_to_cpu(htt_stats_buf->rts));
1520 	len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
1521 			 le32_to_cpu(htt_stats_buf->cts2self));
1522 	len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
1523 			 le32_to_cpu(htt_stats_buf->qos_null));
1524 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_1 = %u\n",
1525 			 le32_to_cpu(htt_stats_buf->delayed_bar_1));
1526 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_2 = %u\n",
1527 			 le32_to_cpu(htt_stats_buf->delayed_bar_2));
1528 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_3 = %u\n",
1529 			 le32_to_cpu(htt_stats_buf->delayed_bar_3));
1530 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_4 = %u\n",
1531 			 le32_to_cpu(htt_stats_buf->delayed_bar_4));
1532 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_5 = %u\n",
1533 			 le32_to_cpu(htt_stats_buf->delayed_bar_5));
1534 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_6 = %u\n",
1535 			 le32_to_cpu(htt_stats_buf->delayed_bar_6));
1536 	len += scnprintf(buf + len, buf_len - len, "delayed_bar_7 = %u\n\n",
1537 			 le32_to_cpu(htt_stats_buf->delayed_bar_7));
1538 
1539 	stats_req->buf_len = len;
1540 }
1541 
1542 static void
ath12k_htt_print_tx_selfgen_ac_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1543 ath12k_htt_print_tx_selfgen_ac_stats_tlv(const void *tag_buf, u16 tag_len,
1544 					 struct debug_htt_stats_req *stats_req)
1545 {
1546 	const struct ath12k_htt_tx_selfgen_ac_stats_tlv *htt_stats_buf = tag_buf;
1547 	u8 *buf = stats_req->buf;
1548 	u32 len = stats_req->buf_len;
1549 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1550 
1551 	if (tag_len < sizeof(*htt_stats_buf))
1552 		return;
1553 
1554 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_STATS_TLV:\n");
1555 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_tried = %u\n",
1556 			 le32_to_cpu(htt_stats_buf->ac_su_ndpa));
1557 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_tried = %u\n",
1558 			 le32_to_cpu(htt_stats_buf->ac_su_ndp));
1559 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_tried = %u\n",
1560 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndpa));
1561 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_tried = %u\n",
1562 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp));
1563 	len += print_array_to_buf_index(buf, len, "ac_mu_mimo_brpollX_tried = ", 1,
1564 					htt_stats_buf->ac_mu_mimo_brpoll,
1565 					ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS, "\n\n");
1566 
1567 	stats_req->buf_len = len;
1568 }
1569 
1570 static void
ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1571 ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, u16 tag_len,
1572 					 struct debug_htt_stats_req *stats_req)
1573 {
1574 	const struct ath12k_htt_tx_selfgen_ax_stats_tlv *htt_stats_buf = tag_buf;
1575 	u8 *buf = stats_req->buf;
1576 	u32 len = stats_req->buf_len;
1577 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1578 
1579 	if (tag_len < sizeof(*htt_stats_buf))
1580 		return;
1581 
1582 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:\n");
1583 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_tried = %u\n",
1584 			 le32_to_cpu(htt_stats_buf->ax_su_ndpa));
1585 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_tried = %u\n",
1586 			 le32_to_cpu(htt_stats_buf->ax_su_ndp));
1587 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_tried = %u\n",
1588 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa));
1589 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_tried = %u\n",
1590 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp));
1591 	len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpollX_tried = ", 1,
1592 					htt_stats_buf->ax_mu_mimo_brpoll,
1593 					ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS, "\n");
1594 	len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n",
1595 			 le32_to_cpu(htt_stats_buf->ax_basic_trigger));
1596 	len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger = %u\n",
1597 			 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger));
1598 	len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n",
1599 			 le32_to_cpu(htt_stats_buf->ax_bsr_trigger));
1600 	len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n",
1601 			 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger));
1602 	len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n\n",
1603 			 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger));
1604 
1605 	stats_req->buf_len = len;
1606 }
1607 
1608 static void
ath12k_htt_print_tx_selfgen_be_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1609 ath12k_htt_print_tx_selfgen_be_stats_tlv(const void *tag_buf, u16 tag_len,
1610 					 struct debug_htt_stats_req *stats_req)
1611 {
1612 	const struct ath12k_htt_tx_selfgen_be_stats_tlv *htt_stats_buf = tag_buf;
1613 	u8 *buf = stats_req->buf;
1614 	u32 len = stats_req->buf_len;
1615 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1616 
1617 	if (tag_len < sizeof(*htt_stats_buf))
1618 		return;
1619 
1620 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_STATS_TLV:\n");
1621 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_queued = %u\n",
1622 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_queued));
1623 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_tried = %u\n",
1624 			 le32_to_cpu(htt_stats_buf->be_su_ndpa));
1625 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_queued = %u\n",
1626 			 le32_to_cpu(htt_stats_buf->be_su_ndp_queued));
1627 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_tried = %u\n",
1628 			 le32_to_cpu(htt_stats_buf->be_su_ndp));
1629 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_queued = %u\n",
1630 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_queued));
1631 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_tried = %u\n",
1632 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa));
1633 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_queued = %u\n",
1634 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_queued));
1635 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_tried = %u\n",
1636 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp));
1637 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_queued = ", 1,
1638 					htt_stats_buf->be_mu_mimo_brpoll_queued,
1639 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1640 					"\n");
1641 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_tried = ", 1,
1642 					htt_stats_buf->be_mu_mimo_brpoll,
1643 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1644 					"\n");
1645 	len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger = ",
1646 				  htt_stats_buf->be_ul_mumimo_trigger,
1647 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1648 	len += scnprintf(buf + len, buf_len - len, "be_basic_trigger = %u\n",
1649 			 le32_to_cpu(htt_stats_buf->be_basic_trigger));
1650 	len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trigger = %u\n",
1651 			 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger));
1652 	len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger = %u\n",
1653 			 le32_to_cpu(htt_stats_buf->be_bsr_trigger));
1654 	len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger = %u\n",
1655 			 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger));
1656 	len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger = %u\n\n",
1657 			 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger));
1658 
1659 	stats_req->buf_len = len;
1660 }
1661 
1662 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)1663 ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(const void *tag_buf, u16 tag_len,
1664 					     struct debug_htt_stats_req *stats_req)
1665 {
1666 	const struct ath12k_htt_tx_selfgen_ac_err_stats_tlv *htt_stats_buf = tag_buf;
1667 	u8 *buf = stats_req->buf;
1668 	u32 len = stats_req->buf_len;
1669 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1670 
1671 	if (tag_len < sizeof(*htt_stats_buf))
1672 		return;
1673 
1674 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:\n");
1675 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_err = %u\n",
1676 			 le32_to_cpu(htt_stats_buf->ac_su_ndp_err));
1677 	len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_err = %u\n",
1678 			 le32_to_cpu(htt_stats_buf->ac_su_ndpa_err));
1679 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u\n",
1680 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndpa_err));
1681 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u\n",
1682 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp_err));
1683 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u\n",
1684 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp1_err));
1685 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u\n",
1686 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp2_err));
1687 	len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n\n",
1688 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp3_err));
1689 
1690 	stats_req->buf_len = len;
1691 }
1692 
1693 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)1694 ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf, u16 tag_len,
1695 					     struct debug_htt_stats_req *stats_req)
1696 {
1697 	const struct ath12k_htt_tx_selfgen_ax_err_stats_tlv *htt_stats_buf = tag_buf;
1698 	u8 *buf = stats_req->buf;
1699 	u32 len = stats_req->buf_len;
1700 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1701 
1702 	if (tag_len < sizeof(*htt_stats_buf))
1703 		return;
1704 
1705 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:\n");
1706 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_err = %u\n",
1707 			 le32_to_cpu(htt_stats_buf->ax_su_ndp_err));
1708 	len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_err = %u\n",
1709 			 le32_to_cpu(htt_stats_buf->ax_su_ndpa_err));
1710 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u\n",
1711 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa_err));
1712 	len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u\n",
1713 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp_err));
1714 	len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpX_err", 1,
1715 					htt_stats_buf->ax_mu_mimo_brp_err,
1716 					ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1,
1717 					"\n");
1718 	len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n",
1719 			 le32_to_cpu(htt_stats_buf->ax_basic_trigger_err));
1720 	len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger_err = %u\n",
1721 			 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger_err));
1722 	len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n",
1723 			 le32_to_cpu(htt_stats_buf->ax_bsr_trigger_err));
1724 	len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n",
1725 			 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger_err));
1726 	len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n\n",
1727 			 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger_err));
1728 
1729 	stats_req->buf_len = len;
1730 }
1731 
1732 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)1733 ath12k_htt_print_tx_selfgen_be_err_stats_tlv(const void *tag_buf, u16 tag_len,
1734 					     struct debug_htt_stats_req *stats_req)
1735 {
1736 	const struct ath12k_htt_tx_selfgen_be_err_stats_tlv *htt_stats_buf = tag_buf;
1737 	u8 *buf = stats_req->buf;
1738 	u32 len = stats_req->buf_len;
1739 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1740 
1741 	if (tag_len < sizeof(*htt_stats_buf))
1742 		return;
1743 
1744 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_ERR_STATS_TLV:\n");
1745 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_err = %u\n",
1746 			 le32_to_cpu(htt_stats_buf->be_su_ndp_err));
1747 	len += scnprintf(buf + len, buf_len - len, "be_su_ndp_flushed = %u\n",
1748 			 le32_to_cpu(htt_stats_buf->be_su_ndp_flushed));
1749 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_err = %u\n",
1750 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_err));
1751 	len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_flushed = %u\n",
1752 			 le32_to_cpu(htt_stats_buf->be_su_ndpa_flushed));
1753 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_err = %u\n",
1754 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_err));
1755 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_flushed = %u\n",
1756 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_flushed));
1757 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_err = %u\n",
1758 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_err));
1759 	len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_flushed = %u\n",
1760 			 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_flushed));
1761 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpX_err", 1,
1762 					htt_stats_buf->be_mu_mimo_brp_err,
1763 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1764 					"\n");
1765 	len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_flushed", 1,
1766 					htt_stats_buf->be_mu_mimo_brpoll_flushed,
1767 					ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1768 					"\n");
1769 	len += print_array_to_buf(buf, len, "be_mu_mimo_num_cbf_rcvd_on_brp_err",
1770 				  htt_stats_buf->be_mu_mimo_brp_err_num_cbf_rxd,
1771 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1772 	len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger_err",
1773 				  htt_stats_buf->be_ul_mumimo_trigger_err,
1774 				  ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1775 	len += scnprintf(buf + len, buf_len - len, "be_basic_trigger_err = %u\n",
1776 			 le32_to_cpu(htt_stats_buf->be_basic_trigger_err));
1777 	len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trig_err = %u\n",
1778 			 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger_err));
1779 	len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger_err = %u\n",
1780 			 le32_to_cpu(htt_stats_buf->be_bsr_trigger_err));
1781 	len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger_err = %u\n",
1782 			 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger_err));
1783 	len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger_err = %u\n\n",
1784 			 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger_err));
1785 
1786 	stats_req->buf_len = len;
1787 }
1788 
1789 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)1790 ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1791 						      struct debug_htt_stats_req *stats)
1792 {
1793 	const struct ath12k_htt_tx_selfgen_ac_sched_status_stats_tlv *htt_stats_buf =
1794 		     tag_buf;
1795 	u8 *buf = stats->buf;
1796 	u32 len = stats->buf_len;
1797 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1798 
1799 	if (tag_len < sizeof(*htt_stats_buf))
1800 		return;
1801 
1802 	len += scnprintf(buf + len, buf_len - len,
1803 			 "HTT_TX_SELFGEN_AC_SCHED_STATUS_STATS_TLV:\n");
1804 	len += print_array_to_buf(buf, len, "ac_su_ndpa_sch_status",
1805 				  htt_stats_buf->ac_su_ndpa_sch_status,
1806 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1807 	len += print_array_to_buf(buf, len, "ac_su_ndp_sch_status",
1808 				  htt_stats_buf->ac_su_ndp_sch_status,
1809 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1810 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndpa_sch_status",
1811 				  htt_stats_buf->ac_mu_mimo_ndpa_sch_status,
1812 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1813 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_status",
1814 				  htt_stats_buf->ac_mu_mimo_ndp_sch_status,
1815 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1816 	len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_status",
1817 				  htt_stats_buf->ac_mu_mimo_brp_sch_status,
1818 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1819 	len += print_array_to_buf(buf, len, "ac_su_ndp_sch_flag_err",
1820 				  htt_stats_buf->ac_su_ndp_sch_flag_err,
1821 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1822 	len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_flag_err",
1823 				  htt_stats_buf->ac_mu_mimo_ndp_sch_flag_err,
1824 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1825 	len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_flag_err",
1826 				  htt_stats_buf->ac_mu_mimo_brp_sch_flag_err,
1827 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1828 
1829 	stats->buf_len = len;
1830 }
1831 
1832 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)1833 ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1834 						      struct debug_htt_stats_req *stats)
1835 {
1836 	const struct ath12k_htt_tx_selfgen_ax_sched_status_stats_tlv *htt_stats_buf =
1837 		     tag_buf;
1838 	u8 *buf = stats->buf;
1839 	u32 len = stats->buf_len;
1840 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1841 
1842 	if (tag_len < sizeof(*htt_stats_buf))
1843 		return;
1844 
1845 	len += scnprintf(buf + len, buf_len - len,
1846 			 "HTT_TX_SELFGEN_AX_SCHED_STATUS_STATS_TLV:\n");
1847 	len += print_array_to_buf(buf, len, "ax_su_ndpa_sch_status",
1848 				  htt_stats_buf->ax_su_ndpa_sch_status,
1849 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1850 	len += print_array_to_buf(buf, len, "ax_su_ndp_sch_status",
1851 				  htt_stats_buf->ax_su_ndp_sch_status,
1852 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1853 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndpa_sch_status",
1854 				  htt_stats_buf->ax_mu_mimo_ndpa_sch_status,
1855 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1856 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_status",
1857 				  htt_stats_buf->ax_mu_mimo_ndp_sch_status,
1858 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1859 	len += print_array_to_buf(buf, len, "ax_mu_brp_sch_status",
1860 				  htt_stats_buf->ax_mu_brp_sch_status,
1861 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1862 	len += print_array_to_buf(buf, len, "ax_mu_bar_sch_status",
1863 				  htt_stats_buf->ax_mu_bar_sch_status,
1864 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1865 	len += print_array_to_buf(buf, len, "ax_basic_trig_sch_status",
1866 				  htt_stats_buf->ax_basic_trig_sch_status,
1867 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1868 	len += print_array_to_buf(buf, len, "ax_su_ndp_sch_flag_err",
1869 				  htt_stats_buf->ax_su_ndp_sch_flag_err,
1870 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1871 	len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_flag_err",
1872 				  htt_stats_buf->ax_mu_mimo_ndp_sch_flag_err,
1873 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1874 	len += print_array_to_buf(buf, len, "ax_mu_brp_sch_flag_err",
1875 				  htt_stats_buf->ax_mu_brp_sch_flag_err,
1876 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1877 	len += print_array_to_buf(buf, len, "ax_mu_bar_sch_flag_err",
1878 				  htt_stats_buf->ax_mu_bar_sch_flag_err,
1879 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1880 	len += print_array_to_buf(buf, len, "ax_basic_trig_sch_flag_err",
1881 				  htt_stats_buf->ax_basic_trig_sch_flag_err,
1882 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1883 	len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_status",
1884 				  htt_stats_buf->ax_ulmumimo_trig_sch_status,
1885 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1886 	len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_flag_err",
1887 				  htt_stats_buf->ax_ulmumimo_trig_sch_flag_err,
1888 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1889 
1890 	stats->buf_len = len;
1891 }
1892 
1893 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)1894 ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1895 						      struct debug_htt_stats_req *stats)
1896 {
1897 	const struct ath12k_htt_tx_selfgen_be_sched_status_stats_tlv *htt_stats_buf =
1898 		     tag_buf;
1899 	u8 *buf = stats->buf;
1900 	u32 len = stats->buf_len;
1901 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1902 
1903 	if (tag_len < sizeof(*htt_stats_buf))
1904 		return;
1905 
1906 	len += scnprintf(buf + len, buf_len - len,
1907 			 "HTT_TX_SELFGEN_BE_SCHED_STATUS_STATS_TLV:\n");
1908 	len += print_array_to_buf(buf, len, "be_su_ndpa_sch_status",
1909 				  htt_stats_buf->be_su_ndpa_sch_status,
1910 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1911 	len += print_array_to_buf(buf, len, "be_su_ndp_sch_status",
1912 				  htt_stats_buf->be_su_ndp_sch_status,
1913 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1914 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndpa_sch_status",
1915 				  htt_stats_buf->be_mu_mimo_ndpa_sch_status,
1916 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1917 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_status",
1918 				  htt_stats_buf->be_mu_mimo_ndp_sch_status,
1919 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1920 	len += print_array_to_buf(buf, len, "be_mu_brp_sch_status",
1921 				  htt_stats_buf->be_mu_brp_sch_status,
1922 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1923 	len += print_array_to_buf(buf, len, "be_mu_bar_sch_status",
1924 				  htt_stats_buf->be_mu_bar_sch_status,
1925 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1926 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_status",
1927 				  htt_stats_buf->be_basic_trig_sch_status,
1928 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1929 	len += print_array_to_buf(buf, len, "be_su_ndp_sch_flag_err",
1930 				  htt_stats_buf->be_su_ndp_sch_flag_err,
1931 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1932 	len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_flag_err",
1933 				  htt_stats_buf->be_mu_mimo_ndp_sch_flag_err,
1934 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1935 	len += print_array_to_buf(buf, len, "be_mu_brp_sch_flag_err",
1936 				  htt_stats_buf->be_mu_brp_sch_flag_err,
1937 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1938 	len += print_array_to_buf(buf, len, "be_mu_bar_sch_flag_err",
1939 				  htt_stats_buf->be_mu_bar_sch_flag_err,
1940 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1941 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1942 				  htt_stats_buf->be_basic_trig_sch_flag_err,
1943 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1944 	len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1945 				  htt_stats_buf->be_basic_trig_sch_flag_err,
1946 				  ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1947 	len += print_array_to_buf(buf, len, "be_ulmumimo_trig_sch_flag_err",
1948 				  htt_stats_buf->be_ulmumimo_trig_sch_flag_err,
1949 				  ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1950 
1951 	stats->buf_len = len;
1952 }
1953 
1954 static void
ath12k_htt_print_stats_string_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1955 ath12k_htt_print_stats_string_tlv(const void *tag_buf, u16 tag_len,
1956 				  struct debug_htt_stats_req *stats_req)
1957 {
1958 	const struct ath12k_htt_stats_string_tlv *htt_stats_buf = tag_buf;
1959 	u8 *buf = stats_req->buf;
1960 	u32 len = stats_req->buf_len;
1961 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1962 	u8 i;
1963 	u16 index = 0;
1964 	u32 datum;
1965 	char data[ATH12K_HTT_MAX_STRING_LEN] = {0};
1966 
1967 	tag_len = tag_len >> 2;
1968 
1969 	len += scnprintf(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:\n");
1970 	for (i = 0; i < tag_len; i++) {
1971 		datum = __le32_to_cpu(htt_stats_buf->data[i]);
1972 		index += scnprintf(&data[index], ATH12K_HTT_MAX_STRING_LEN - index,
1973 				   "%.*s", 4, (char *)&datum);
1974 		if (index >= ATH12K_HTT_MAX_STRING_LEN)
1975 			break;
1976 	}
1977 	len += scnprintf(buf + len, buf_len - len, "data = %s\n\n", data);
1978 
1979 	stats_req->buf_len = len;
1980 }
1981 
1982 static void
ath12k_htt_print_sring_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1983 ath12k_htt_print_sring_stats_tlv(const void *tag_buf, u16 tag_len,
1984 				 struct debug_htt_stats_req *stats_req)
1985 {
1986 	const struct ath12k_htt_sring_stats_tlv *htt_stats_buf = tag_buf;
1987 	u8 *buf = stats_req->buf;
1988 	u32 len = stats_req->buf_len;
1989 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1990 	u32 mac_id_word;
1991 	u32 avail_words;
1992 	u32 head_tail_ptr;
1993 	u32 sring_stat;
1994 	u32 tail_ptr;
1995 
1996 	if (tag_len < sizeof(*htt_stats_buf))
1997 		return;
1998 
1999 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__ring_id__arena__ep);
2000 	avail_words = __le32_to_cpu(htt_stats_buf->num_avail_words__num_valid_words);
2001 	head_tail_ptr = __le32_to_cpu(htt_stats_buf->head_ptr__tail_ptr);
2002 	sring_stat = __le32_to_cpu(htt_stats_buf->consumer_empty__producer_full);
2003 	tail_ptr = __le32_to_cpu(htt_stats_buf->prefetch_count__internal_tail_ptr);
2004 
2005 	len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n");
2006 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2007 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_MAC_ID));
2008 	len += scnprintf(buf + len, buf_len - len, "ring_id = %u\n",
2009 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_RING_ID));
2010 	len += scnprintf(buf + len, buf_len - len, "arena = %u\n",
2011 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_ARENA));
2012 	len += scnprintf(buf + len, buf_len - len, "ep = %u\n",
2013 			 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_EP));
2014 	len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n",
2015 			 le32_to_cpu(htt_stats_buf->base_addr_lsb));
2016 	len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n",
2017 			 le32_to_cpu(htt_stats_buf->base_addr_msb));
2018 	len += scnprintf(buf + len, buf_len - len, "ring_size = %u\n",
2019 			 le32_to_cpu(htt_stats_buf->ring_size));
2020 	len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
2021 			 le32_to_cpu(htt_stats_buf->elem_size));
2022 	len += scnprintf(buf + len, buf_len - len, "num_avail_words = %u\n",
2023 			 u32_get_bits(avail_words,
2024 				      ATH12K_HTT_SRING_STATS_NUM_AVAIL_WORDS));
2025 	len += scnprintf(buf + len, buf_len - len, "num_valid_words = %u\n",
2026 			 u32_get_bits(avail_words,
2027 				      ATH12K_HTT_SRING_STATS_NUM_VALID_WORDS));
2028 	len += scnprintf(buf + len, buf_len - len, "head_ptr = %u\n",
2029 			 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_HEAD_PTR));
2030 	len += scnprintf(buf + len, buf_len - len, "tail_ptr = %u\n",
2031 			 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_TAIL_PTR));
2032 	len += scnprintf(buf + len, buf_len - len, "consumer_empty = %u\n",
2033 			 u32_get_bits(sring_stat,
2034 				      ATH12K_HTT_SRING_STATS_CONSUMER_EMPTY));
2035 	len += scnprintf(buf + len, buf_len - len, "producer_full = %u\n",
2036 			 u32_get_bits(head_tail_ptr,
2037 				      ATH12K_HTT_SRING_STATS_PRODUCER_FULL));
2038 	len += scnprintf(buf + len, buf_len - len, "prefetch_count = %u\n",
2039 			 u32_get_bits(tail_ptr, ATH12K_HTT_SRING_STATS_PREFETCH_COUNT));
2040 	len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %u\n\n",
2041 			 u32_get_bits(tail_ptr,
2042 				      ATH12K_HTT_SRING_STATS_INTERNAL_TAIL_PTR));
2043 
2044 	stats_req->buf_len = len;
2045 }
2046 
2047 static void
ath12k_htt_print_sfm_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2048 ath12k_htt_print_sfm_cmn_tlv(const void *tag_buf, u16 tag_len,
2049 			     struct debug_htt_stats_req *stats_req)
2050 {
2051 	const struct ath12k_htt_sfm_cmn_tlv *htt_stats_buf = tag_buf;
2052 	u8 *buf = stats_req->buf;
2053 	u32 len = stats_req->buf_len;
2054 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2055 	u32 mac_id_word;
2056 
2057 	if (tag_len < sizeof(*htt_stats_buf))
2058 		return;
2059 
2060 	mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
2061 
2062 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n");
2063 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2064 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2065 	len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n",
2066 			 le32_to_cpu(htt_stats_buf->buf_total));
2067 	len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n",
2068 			 le32_to_cpu(htt_stats_buf->mem_empty));
2069 	len += scnprintf(buf + len, buf_len - len, "deallocate_bufs = %u\n",
2070 			 le32_to_cpu(htt_stats_buf->deallocate_bufs));
2071 	len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2072 			 le32_to_cpu(htt_stats_buf->num_records));
2073 
2074 	stats_req->buf_len = len;
2075 }
2076 
2077 static void
ath12k_htt_print_sfm_client_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2078 ath12k_htt_print_sfm_client_tlv(const void *tag_buf, u16 tag_len,
2079 				struct debug_htt_stats_req *stats_req)
2080 {
2081 	const struct ath12k_htt_sfm_client_tlv *htt_stats_buf = tag_buf;
2082 	u8 *buf = stats_req->buf;
2083 	u32 len = stats_req->buf_len;
2084 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2085 
2086 	if (tag_len < sizeof(*htt_stats_buf))
2087 		return;
2088 
2089 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:\n");
2090 	len += scnprintf(buf + len, buf_len - len, "client_id = %u\n",
2091 			 le32_to_cpu(htt_stats_buf->client_id));
2092 	len += scnprintf(buf + len, buf_len - len, "buf_min = %u\n",
2093 			 le32_to_cpu(htt_stats_buf->buf_min));
2094 	len += scnprintf(buf + len, buf_len - len, "buf_max = %u\n",
2095 			 le32_to_cpu(htt_stats_buf->buf_max));
2096 	len += scnprintf(buf + len, buf_len - len, "buf_busy = %u\n",
2097 			 le32_to_cpu(htt_stats_buf->buf_busy));
2098 	len += scnprintf(buf + len, buf_len - len, "buf_alloc = %u\n",
2099 			 le32_to_cpu(htt_stats_buf->buf_alloc));
2100 	len += scnprintf(buf + len, buf_len - len, "buf_avail = %u\n",
2101 			 le32_to_cpu(htt_stats_buf->buf_avail));
2102 	len += scnprintf(buf + len, buf_len - len, "num_users = %u\n\n",
2103 			 le32_to_cpu(htt_stats_buf->num_users));
2104 
2105 	stats_req->buf_len = len;
2106 }
2107 
2108 static void
ath12k_htt_print_sfm_client_user_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2109 ath12k_htt_print_sfm_client_user_tlv(const void *tag_buf, u16 tag_len,
2110 				     struct debug_htt_stats_req *stats_req)
2111 {
2112 	const struct ath12k_htt_sfm_client_user_tlv *htt_stats_buf = tag_buf;
2113 	u8 *buf = stats_req->buf;
2114 	u32 len = stats_req->buf_len;
2115 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2116 	u16 num_elems = tag_len >> 2;
2117 
2118 	len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV:\n");
2119 	len += print_array_to_buf(buf, len, "dwords_used_by_user_n",
2120 				  htt_stats_buf->dwords_used_by_user_n,
2121 				  num_elems, "\n\n");
2122 
2123 	stats_req->buf_len = len;
2124 }
2125 
2126 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)2127 ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, u16 tag_len,
2128 					       struct debug_htt_stats_req *stats_req)
2129 {
2130 	const struct ath12k_htt_tx_pdev_mu_mimo_sch_stats_tlv *htt_stats_buf = tag_buf;
2131 	u8 *buf = stats_req->buf;
2132 	u32 len = stats_req->buf_len;
2133 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2134 	u8 i;
2135 
2136 	if (tag_len < sizeof(*htt_stats_buf))
2137 		return;
2138 
2139 	len += scnprintf(buf + len, buf_len - len,
2140 			 "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:\n");
2141 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n",
2142 			 le32_to_cpu(htt_stats_buf->mu_mimo_sch_posted));
2143 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n",
2144 			 le32_to_cpu(htt_stats_buf->mu_mimo_sch_failed));
2145 	len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n",
2146 			 le32_to_cpu(htt_stats_buf->mu_mimo_ppdu_posted));
2147 	len += scnprintf(buf + len, buf_len - len,
2148 			 "\nac_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2149 			 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[0]));
2150 	for (i = 1; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2151 		len += scnprintf(buf + len, buf_len - len,
2152 				 "ac_mu_mimo_sch_posted_per_group_index %u ", i);
2153 		len += scnprintf(buf + len, buf_len - len,
2154 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2155 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[i]));
2156 	}
2157 
2158 	for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2159 		len += scnprintf(buf + len, buf_len - len,
2160 				 "ac_mu_mimo_sch_posted_per_group_index %u ",
2161 				 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS);
2162 		len += scnprintf(buf + len, buf_len - len,
2163 				 "(TOTAL STREAMS = %u) = %u\n",
2164 				 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS + 1,
2165 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_grp_sz_ext[i]));
2166 	}
2167 
2168 	len += scnprintf(buf + len, buf_len - len,
2169 			 "\nax_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2170 			 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[0]));
2171 	for (i = 1; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2172 		len += scnprintf(buf + len, buf_len - len,
2173 				 "ax_mu_mimo_sch_posted_per_group_index %u ", i);
2174 		len += scnprintf(buf + len, buf_len - len,
2175 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2176 				 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[i]));
2177 	}
2178 
2179 	len += scnprintf(buf + len, buf_len - len,
2180 			"\nbe_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2181 			le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[0]));
2182 	for (i = 1; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2183 		len += scnprintf(buf + len, buf_len - len,
2184 				 "be_mu_mimo_sch_posted_per_group_index %u ", i);
2185 		len += scnprintf(buf + len, buf_len - len,
2186 				 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2187 				 le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[i]));
2188 	}
2189 
2190 	len += scnprintf(buf + len, buf_len - len, "\n11ac MU_MIMO SCH STATS:\n");
2191 	for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2192 		len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_sch_nusers_");
2193 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2194 				 le32_to_cpu(htt_stats_buf->ac_mu_mimo_sch_nusers[i]));
2195 	}
2196 
2197 	len += scnprintf(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:\n");
2198 	for (i = 0; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2199 		len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_sch_nusers_");
2200 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2201 				 le32_to_cpu(htt_stats_buf->ax_mu_mimo_sch_nusers[i]));
2202 	}
2203 
2204 	len += scnprintf(buf + len, buf_len - len, "\n11be MU_MIMO SCH STATS:\n");
2205 	for (i = 0; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2206 		len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_sch_nusers_");
2207 		len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2208 				 le32_to_cpu(htt_stats_buf->be_mu_mimo_sch_nusers[i]));
2209 	}
2210 
2211 	len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n");
2212 	for (i = 0; i < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS; i++) {
2213 		len += scnprintf(buf + len, buf_len - len,
2214 				 "ax_ofdma_sch_nusers_%u = %u\n", i,
2215 				 le32_to_cpu(htt_stats_buf->ax_ofdma_sch_nusers[i]));
2216 		len += scnprintf(buf + len, buf_len - len,
2217 				 "ax_ul_ofdma_basic_sch_nusers_%u = %u\n", i,
2218 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_nusers[i]));
2219 		len += scnprintf(buf + len, buf_len - len,
2220 				 "ax_ul_ofdma_bsr_sch_nusers_%u = %u\n", i,
2221 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bsr_nusers[i]));
2222 		len += scnprintf(buf + len, buf_len - len,
2223 				 "ax_ul_ofdma_bar_sch_nusers_%u = %u\n", i,
2224 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bar_nusers[i]));
2225 		len += scnprintf(buf + len, buf_len - len,
2226 				 "ax_ul_ofdma_brp_sch_nusers_%u = %u\n\n", i,
2227 				 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_brp_nusers[i]));
2228 	}
2229 
2230 	len += scnprintf(buf + len, buf_len - len, "11ax UL MUMIMO SCH STATS:\n");
2231 	for (i = 0; i < ATH12K_HTT_TX_NUM_UL_MUMIMO_USER_STATS; i++) {
2232 		len += scnprintf(buf + len, buf_len - len,
2233 				 "ax_ul_mumimo_basic_sch_nusers_%u = %u\n", i,
2234 				 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_nusers[i]));
2235 		len += scnprintf(buf + len, buf_len - len,
2236 				 "ax_ul_mumimo_brp_sch_nusers_%u = %u\n\n", i,
2237 				 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_brp_nusers[i]));
2238 	}
2239 
2240 	stats_req->buf_len = len;
2241 }
2242 
2243 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)2244 ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(const void *tag_buf, u16 tag_len,
2245 					      struct debug_htt_stats_req *stats_req)
2246 {
2247 	const struct ath12k_htt_tx_pdev_mumimo_grp_stats_tlv *htt_stats_buf = tag_buf;
2248 	u8 *buf = stats_req->buf;
2249 	u32 len = stats_req->buf_len;
2250 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2251 	int j;
2252 
2253 	if (tag_len < sizeof(*htt_stats_buf))
2254 		return;
2255 
2256 	len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_MUMIMO_GRP_STATS:\n");
2257 	len += print_array_to_buf(buf, len,
2258 				  "dl_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2259 				  htt_stats_buf->dl_mumimo_grp_tputs,
2260 				  ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n");
2261 	len += print_array_to_buf(buf, len, "dl_mumimo_grp eligible",
2262 				  htt_stats_buf->dl_mumimo_grp_eligible,
2263 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2264 	len += print_array_to_buf(buf, len, "dl_mumimo_grp_ineligible",
2265 				  htt_stats_buf->dl_mumimo_grp_ineligible,
2266 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2267 	len += scnprintf(buf + len, buf_len - len, "dl_mumimo_grp_invalid:\n");
2268 	for (j = 0; j < ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ; j++) {
2269 		len += scnprintf(buf + len, buf_len - len, "grp_id = %u", j);
2270 		len += print_array_to_buf(buf, len, "",
2271 					  htt_stats_buf->dl_mumimo_grp_invalid,
2272 					  ATH12K_HTT_STATS_MAX_INVALID_REASON_CODE,
2273 					  "\n");
2274 	}
2275 
2276 	len += print_array_to_buf(buf, len, "ul_mumimo_grp_best_grp_size",
2277 				  htt_stats_buf->ul_mumimo_grp_best_grp_size,
2278 				  ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2279 	len += print_array_to_buf_index(buf, len, "ul_mumimo_grp_best_num_usrs = ", 1,
2280 					htt_stats_buf->ul_mumimo_grp_best_usrs,
2281 					ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS, "\n");
2282 	len += print_array_to_buf(buf, len,
2283 				  "ul_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2284 				  htt_stats_buf->ul_mumimo_grp_tputs,
2285 				  ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n\n");
2286 
2287 	stats_req->buf_len = len;
2288 }
2289 
2290 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)2291 ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
2292 						struct debug_htt_stats_req *stats_req)
2293 {
2294 	const struct ath12k_htt_tx_pdev_mpdu_stats_tlv *htt_stats_buf = tag_buf;
2295 	u8 *buf = stats_req->buf;
2296 	u32 len = stats_req->buf_len;
2297 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2298 	u32 user_index;
2299 	u32 tx_sched_mode;
2300 
2301 	if (tag_len < sizeof(*htt_stats_buf))
2302 		return;
2303 
2304 	user_index = __le32_to_cpu(htt_stats_buf->user_index);
2305 	tx_sched_mode = __le32_to_cpu(htt_stats_buf->tx_sched_mode);
2306 
2307 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AC) {
2308 		if (!user_index)
2309 			len += scnprintf(buf + len, buf_len - len,
2310 					 "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n");
2311 
2312 		if (user_index < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS) {
2313 			len += scnprintf(buf + len, buf_len - len,
2314 					 "ac_mu_mimo_mpdus_queued_usr_%u = %u\n",
2315 					 user_index,
2316 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2317 			len += scnprintf(buf + len, buf_len - len,
2318 					 "ac_mu_mimo_mpdus_tried_usr_%u = %u\n",
2319 					 user_index,
2320 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2321 			len += scnprintf(buf + len, buf_len - len,
2322 					 "ac_mu_mimo_mpdus_failed_usr_%u = %u\n",
2323 					 user_index,
2324 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2325 			len += scnprintf(buf + len, buf_len - len,
2326 					 "ac_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2327 					 user_index,
2328 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2329 			len += scnprintf(buf + len, buf_len - len,
2330 					 "ac_mu_mimo_err_no_ba_usr_%u = %u\n",
2331 					 user_index,
2332 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2333 			len += scnprintf(buf + len, buf_len - len,
2334 					 "ac_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2335 					 user_index,
2336 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2337 			len += scnprintf(buf + len, buf_len - len,
2338 					"ac_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2339 					 user_index,
2340 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2341 		}
2342 	}
2343 
2344 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AX) {
2345 		if (!user_index)
2346 			len += scnprintf(buf + len, buf_len - len,
2347 					 "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n");
2348 
2349 		if (user_index < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS) {
2350 			len += scnprintf(buf + len, buf_len - len,
2351 					 "ax_mu_mimo_mpdus_queued_usr_%u = %u\n",
2352 					 user_index,
2353 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2354 			len += scnprintf(buf + len, buf_len - len,
2355 					 "ax_mu_mimo_mpdus_tried_usr_%u = %u\n",
2356 					 user_index,
2357 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2358 			len += scnprintf(buf + len, buf_len - len,
2359 					 "ax_mu_mimo_mpdus_failed_usr_%u = %u\n",
2360 					 user_index,
2361 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2362 			len += scnprintf(buf + len, buf_len - len,
2363 					 "ax_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2364 					 user_index,
2365 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2366 			len += scnprintf(buf + len, buf_len - len,
2367 					 "ax_mu_mimo_err_no_ba_usr_%u = %u\n",
2368 					 user_index,
2369 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2370 			len += scnprintf(buf + len, buf_len - len,
2371 					 "ax_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2372 					 user_index,
2373 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2374 			len += scnprintf(buf + len, buf_len - len,
2375 					 "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2376 					 user_index,
2377 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2378 		}
2379 	}
2380 
2381 	if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_OFDMA_AX) {
2382 		if (!user_index)
2383 			len += scnprintf(buf + len, buf_len - len,
2384 					 "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n");
2385 
2386 		if (user_index < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS) {
2387 			len += scnprintf(buf + len, buf_len - len,
2388 					 "ax_mu_ofdma_mpdus_queued_usr_%u = %u\n",
2389 					 user_index,
2390 					 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2391 			len += scnprintf(buf + len, buf_len - len,
2392 					 "ax_mu_ofdma_mpdus_tried_usr_%u = %u\n",
2393 					 user_index,
2394 					 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2395 			len += scnprintf(buf + len, buf_len - len,
2396 					 "ax_mu_ofdma_mpdus_failed_usr_%u = %u\n",
2397 					 user_index,
2398 					 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2399 			len += scnprintf(buf + len, buf_len - len,
2400 					 "ax_mu_ofdma_mpdus_requeued_usr_%u = %u\n",
2401 					 user_index,
2402 					 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2403 			len += scnprintf(buf + len, buf_len - len,
2404 					 "ax_mu_ofdma_err_no_ba_usr_%u = %u\n",
2405 					 user_index,
2406 					 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2407 			len += scnprintf(buf + len, buf_len - len,
2408 					 "ax_mu_ofdma_mpdu_underrun_usr_%u = %u\n",
2409 					 user_index,
2410 					 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2411 			len += scnprintf(buf + len, buf_len - len,
2412 					 "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n\n",
2413 					 user_index,
2414 					 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2415 		}
2416 	}
2417 
2418 	stats_req->buf_len = len;
2419 }
2420 
2421 static void
ath12k_htt_print_pdev_cca_stats_hist_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2422 ath12k_htt_print_pdev_cca_stats_hist_tlv(const void *tag_buf, u16 tag_len,
2423 					 struct debug_htt_stats_req *stats_req)
2424 {
2425 	const struct ath12k_htt_pdev_cca_stats_hist_v1_tlv *htt_stats_buf = tag_buf;
2426 	u8 *buf = stats_req->buf;
2427 	u32 len = stats_req->buf_len;
2428 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2429 
2430 	if (tag_len < sizeof(*htt_stats_buf))
2431 		return;
2432 
2433 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_CCA_STATS_HIST_TLV :\n");
2434 	len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
2435 			 le32_to_cpu(htt_stats_buf->chan_num));
2436 	len += scnprintf(buf + len, buf_len - len, "num_records = %u\n",
2437 			 le32_to_cpu(htt_stats_buf->num_records));
2438 	len += scnprintf(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x\n",
2439 			 le32_to_cpu(htt_stats_buf->valid_cca_counters_bitmap));
2440 	len += scnprintf(buf + len, buf_len - len, "collection_interval = %u\n\n",
2441 			 le32_to_cpu(htt_stats_buf->collection_interval));
2442 
2443 	stats_req->buf_len = len;
2444 }
2445 
2446 static void
ath12k_htt_print_pdev_stats_cca_counters_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2447 ath12k_htt_print_pdev_stats_cca_counters_tlv(const void *tag_buf, u16 tag_len,
2448 					     struct debug_htt_stats_req *stats_req)
2449 {
2450 	const struct ath12k_htt_pdev_stats_cca_counters_tlv *htt_stats_buf = tag_buf;
2451 	u8 *buf = stats_req->buf;
2452 	u32 len = stats_req->buf_len;
2453 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2454 
2455 	if (tag_len < sizeof(*htt_stats_buf))
2456 		return;
2457 
2458 	len += scnprintf(buf + len, buf_len - len,
2459 			 "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)\n");
2460 	len += scnprintf(buf + len, buf_len - len, "tx_frame_usec = %u\n",
2461 			 le32_to_cpu(htt_stats_buf->tx_frame_usec));
2462 	len += scnprintf(buf + len, buf_len - len, "rx_frame_usec = %u\n",
2463 			 le32_to_cpu(htt_stats_buf->rx_frame_usec));
2464 	len += scnprintf(buf + len, buf_len - len, "rx_clear_usec = %u\n",
2465 			 le32_to_cpu(htt_stats_buf->rx_clear_usec));
2466 	len += scnprintf(buf + len, buf_len - len, "my_rx_frame_usec = %u\n",
2467 			 le32_to_cpu(htt_stats_buf->my_rx_frame_usec));
2468 	len += scnprintf(buf + len, buf_len - len, "usec_cnt = %u\n",
2469 			 le32_to_cpu(htt_stats_buf->usec_cnt));
2470 	len += scnprintf(buf + len, buf_len - len, "med_rx_idle_usec = %u\n",
2471 			 le32_to_cpu(htt_stats_buf->med_rx_idle_usec));
2472 	len += scnprintf(buf + len, buf_len - len, "med_tx_idle_global_usec = %u\n",
2473 			 le32_to_cpu(htt_stats_buf->med_tx_idle_global_usec));
2474 	len += scnprintf(buf + len, buf_len - len, "cca_obss_usec = %u\n\n",
2475 			 le32_to_cpu(htt_stats_buf->cca_obss_usec));
2476 
2477 	stats_req->buf_len = len;
2478 }
2479 
2480 static void
ath12k_htt_print_pdev_obss_pd_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2481 ath12k_htt_print_pdev_obss_pd_stats_tlv(const void *tag_buf, u16 tag_len,
2482 					struct debug_htt_stats_req *stats_req)
2483 {
2484 	const struct ath12k_htt_pdev_obss_pd_stats_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 	u8 i;
2489 	static const char *access_cat_names[ATH12K_HTT_NUM_AC_WMM] = {"best effort",
2490 								      "background",
2491 								      "video", "voice"};
2492 
2493 	if (tag_len < sizeof(*htt_stats_buf))
2494 		return;
2495 
2496 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_STATS_TLV:\n");
2497 	len += scnprintf(buf + len, buf_len - len, "num_spatial_reuse_tx = %u\n",
2498 			 le32_to_cpu(htt_stats_buf->num_sr_tx_transmissions));
2499 	len += scnprintf(buf + len, buf_len - len,
2500 			 "num_spatial_reuse_opportunities = %u\n",
2501 			 le32_to_cpu(htt_stats_buf->num_spatial_reuse_opportunities));
2502 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_opportunities = %u\n",
2503 			 le32_to_cpu(htt_stats_buf->num_non_srg_opportunities));
2504 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_tried = %u\n",
2505 			 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_tried));
2506 	len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_success = %u\n",
2507 			 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_success));
2508 	len += scnprintf(buf + len, buf_len - len, "num_srg_opportunities = %u\n",
2509 			 le32_to_cpu(htt_stats_buf->num_srg_opportunities));
2510 	len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2511 			 le32_to_cpu(htt_stats_buf->num_srg_ppdu_tried));
2512 	len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_success = %u\n",
2513 			 le32_to_cpu(htt_stats_buf->num_srg_ppdu_success));
2514 	len += scnprintf(buf + len, buf_len - len, "num_psr_opportunities = %u\n",
2515 			 le32_to_cpu(htt_stats_buf->num_psr_opportunities));
2516 	len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_tried = %u\n",
2517 			 le32_to_cpu(htt_stats_buf->num_psr_ppdu_tried));
2518 	len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_success = %u\n",
2519 			 le32_to_cpu(htt_stats_buf->num_psr_ppdu_success));
2520 	len += scnprintf(buf + len, buf_len - len, "min_duration_check_flush_cnt = %u\n",
2521 			 le32_to_cpu(htt_stats_buf->num_obss_min_dur_check_flush_cnt));
2522 	len += scnprintf(buf + len, buf_len - len, "sr_ppdu_abort_flush_cnt = %u\n\n",
2523 			 le32_to_cpu(htt_stats_buf->num_sr_ppdu_abort_flush_cnt));
2524 
2525 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_PER_AC_STATS:\n");
2526 	for (i = 0; i < ATH12K_HTT_NUM_AC_WMM; i++) {
2527 		len += scnprintf(buf + len, buf_len - len, "Access Category %u (%s)\n",
2528 				 i, access_cat_names[i]);
2529 		len += scnprintf(buf + len, buf_len - len,
2530 				 "num_non_srg_ppdu_tried = %u\n",
2531 				 le32_to_cpu(htt_stats_buf->num_non_srg_tried_per_ac[i]));
2532 		len += scnprintf(buf + len, buf_len - len,
2533 				 "num_non_srg_ppdu_success = %u\n",
2534 				 le32_to_cpu(htt_stats_buf->num_non_srg_success_ac[i]));
2535 		len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2536 				 le32_to_cpu(htt_stats_buf->num_srg_tried_per_ac[i]));
2537 		len += scnprintf(buf + len, buf_len - len,
2538 				 "num_srg_ppdu_success = %u\n\n",
2539 				 le32_to_cpu(htt_stats_buf->num_srg_success_per_ac[i]));
2540 	}
2541 
2542 	stats_req->buf_len = len;
2543 }
2544 
2545 static void
ath12k_htt_print_dmac_reset_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)2546 ath12k_htt_print_dmac_reset_stats_tlv(const void *tag_buf, u16 tag_len,
2547 				      struct debug_htt_stats_req *stats_req)
2548 {
2549 	const struct ath12k_htt_dmac_reset_stats_tlv *htt_stats_buf = tag_buf;
2550 	u8 *buf = stats_req->buf;
2551 	u32 len = stats_req->buf_len;
2552 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2553 	u64 time;
2554 
2555 	if (tag_len < sizeof(*htt_stats_buf))
2556 		return;
2557 
2558 	len += scnprintf(buf + len, buf_len - len, "HTT_DMAC_RESET_STATS_TLV:\n");
2559 	len += scnprintf(buf + len, buf_len - len, "reset_count = %u\n",
2560 			 le32_to_cpu(htt_stats_buf->reset_count));
2561 	time = ath12k_le32hilo_to_u64(htt_stats_buf->reset_time_hi_ms,
2562 				      htt_stats_buf->reset_time_lo_ms);
2563 	len += scnprintf(buf + len, buf_len - len, "reset_time_ms = %llu\n", time);
2564 
2565 	time = ath12k_le32hilo_to_u64(htt_stats_buf->disengage_time_hi_ms,
2566 				      htt_stats_buf->disengage_time_lo_ms);
2567 	len += scnprintf(buf + len, buf_len - len, "disengage_time_ms = %llu\n", time);
2568 
2569 	time = ath12k_le32hilo_to_u64(htt_stats_buf->engage_time_hi_ms,
2570 				      htt_stats_buf->engage_time_lo_ms);
2571 	len += scnprintf(buf + len, buf_len - len, "engage_time_ms = %llu\n", time);
2572 
2573 	len += scnprintf(buf + len, buf_len - len, "disengage_count = %u\n",
2574 			 le32_to_cpu(htt_stats_buf->disengage_count));
2575 	len += scnprintf(buf + len, buf_len - len, "engage_count = %u\n",
2576 			 le32_to_cpu(htt_stats_buf->engage_count));
2577 	len += scnprintf(buf + len, buf_len - len, "drain_dest_ring_mask = 0x%x\n\n",
2578 			 le32_to_cpu(htt_stats_buf->drain_dest_ring_mask));
2579 
2580 	stats_req->buf_len = len;
2581 }
2582 
2583 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)2584 ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(const void *tag_buf, u16 tag_len,
2585 						 struct debug_htt_stats_req *stats_req)
2586 {
2587 	const struct ath12k_htt_pdev_sched_algo_ofdma_stats_tlv *htt_stats_buf = tag_buf;
2588 	u8 *buf = stats_req->buf;
2589 	u32 len = stats_req->buf_len;
2590 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2591 	u32 mac_id_word;
2592 
2593 	if (tag_len < sizeof(*htt_stats_buf))
2594 		return;
2595 
2596 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
2597 
2598 	len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_SCHED_ALGO_TLV:\n");
2599 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2600 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2601 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_enabled_count",
2602 				  htt_stats_buf->rate_based_dlofdma_enabled_cnt,
2603 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2604 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_disabled_count",
2605 				  htt_stats_buf->rate_based_dlofdma_disabled_cnt,
2606 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2607 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_probing_count",
2608 				  htt_stats_buf->rate_based_dlofdma_disabled_cnt,
2609 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2610 	len += print_array_to_buf(buf, len, "rate_based_dlofdma_monitoring_count",
2611 				  htt_stats_buf->rate_based_dlofdma_monitor_cnt,
2612 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2613 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_enabled_count",
2614 				  htt_stats_buf->chan_acc_lat_based_dlofdma_enabled_cnt,
2615 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2616 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_disabled_count",
2617 				  htt_stats_buf->chan_acc_lat_based_dlofdma_disabled_cnt,
2618 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2619 	len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_monitoring_count",
2620 				  htt_stats_buf->chan_acc_lat_based_dlofdma_monitor_cnt,
2621 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2622 	len += print_array_to_buf(buf, len, "downgrade_to_dl_su_ru_alloc_fail",
2623 				  htt_stats_buf->downgrade_to_dl_su_ru_alloc_fail,
2624 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2625 	len += print_array_to_buf(buf, len, "candidate_list_single_user_disable_ofdma",
2626 				  htt_stats_buf->candidate_list_single_user_disable_ofdma,
2627 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2628 	len += print_array_to_buf(buf, len, "dl_cand_list_dropped_high_ul_qos_weight",
2629 				  htt_stats_buf->dl_cand_list_dropped_high_ul_qos_weight,
2630 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2631 	len += print_array_to_buf(buf, len, "ax_dlofdma_disabled_due_to_pipelining",
2632 				  htt_stats_buf->ax_dlofdma_disabled_due_to_pipelining,
2633 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2634 	len += print_array_to_buf(buf, len, "dlofdma_disabled_su_only_eligible",
2635 				  htt_stats_buf->dlofdma_disabled_su_only_eligible,
2636 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2637 	len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_tried",
2638 				  htt_stats_buf->dlofdma_disabled_consec_no_mpdus_tried,
2639 				  ATH12K_HTT_NUM_AC_WMM, "\n");
2640 	len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_success",
2641 				  htt_stats_buf->dlofdma_disabled_consec_no_mpdus_success,
2642 				  ATH12K_HTT_NUM_AC_WMM, "\n\n");
2643 
2644 	stats_req->buf_len = len;
2645 }
2646 
2647 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)2648 ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(const void *tag_buf, u16 tag_len,
2649 						 struct debug_htt_stats_req *stats_req)
2650 {
2651 	const struct ath12k_htt_tx_pdev_rate_stats_be_ofdma_tlv *htt_stats_buf = tag_buf;
2652 	u8 *buf = stats_req->buf;
2653 	u32 len = stats_req->buf_len;
2654 	u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2655 	u32 mac_id_word;
2656 	u8 i;
2657 
2658 	if (tag_len < sizeof(*htt_stats_buf))
2659 		return;
2660 
2661 	mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
2662 
2663 	len += scnprintf(buf + len, buf_len - len,
2664 			 "HTT_TX_PDEV_RATE_STATS_BE_OFDMA_TLV:\n");
2665 	len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2666 			 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2667 	len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ldpc = %u\n",
2668 			 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ldpc));
2669 	len += print_array_to_buf(buf, len, "be_ofdma_tx_mcs",
2670 				  htt_stats_buf->be_ofdma_tx_mcs,
2671 				  ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
2672 	len += print_array_to_buf(buf, len, "be_ofdma_eht_sig_mcs",
2673 				  htt_stats_buf->be_ofdma_eht_sig_mcs,
2674 				  ATH12K_HTT_TX_PDEV_NUM_EHT_SIG_MCS_CNTRS, "\n");
2675 	len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ru_size = ");
2676 	for (i = 0; i < ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS; i++)
2677 		len += scnprintf(buf + len, buf_len - len, " %s:%u ",
2678 				 ath12k_htt_be_tx_rx_ru_size_to_str(i),
2679 				 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ru_size[i]));
2680 	len += scnprintf(buf + len, buf_len - len, "\n");
2681 	len += print_array_to_buf_index(buf, len, "be_ofdma_tx_nss = ", 1,
2682 					htt_stats_buf->be_ofdma_tx_nss,
2683 					ATH12K_HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS,
2684 					"\n");
2685 	len += print_array_to_buf(buf, len, "be_ofdma_tx_bw",
2686 				  htt_stats_buf->be_ofdma_tx_bw,
2687 				  ATH12K_HTT_TX_PDEV_NUM_BE_BW_CNTRS, "\n");
2688 	for (i = 0; i < ATH12K_HTT_TX_PDEV_NUM_GI_CNTRS; i++) {
2689 		len += scnprintf(buf + len, buf_len - len,
2690 				 "be_ofdma_tx_gi[%u]", i);
2691 		len += print_array_to_buf(buf, len, "", htt_stats_buf->gi[i],
2692 					  ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
2693 	}
2694 	len += scnprintf(buf + len, buf_len - len, "\n");
2695 
2696 	stats_req->buf_len = len;
2697 }
2698 
ath12k_dbg_htt_ext_stats_parse(struct ath12k_base * ab,u16 tag,u16 len,const void * tag_buf,void * user_data)2699 static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
2700 					  u16 tag, u16 len, const void *tag_buf,
2701 					  void *user_data)
2702 {
2703 	struct debug_htt_stats_req *stats_req = user_data;
2704 
2705 	switch (tag) {
2706 	case HTT_STATS_TX_PDEV_CMN_TAG:
2707 		htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req);
2708 		break;
2709 	case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
2710 		htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req);
2711 		break;
2712 	case HTT_STATS_TX_PDEV_SIFS_TAG:
2713 		htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req);
2714 		break;
2715 	case HTT_STATS_TX_PDEV_FLUSH_TAG:
2716 		htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req);
2717 		break;
2718 	case HTT_STATS_TX_PDEV_SIFS_HIST_TAG:
2719 		htt_print_tx_pdev_stats_sifs_hist_tlv(tag_buf, len, stats_req);
2720 		break;
2721 	case HTT_STATS_PDEV_CTRL_PATH_TX_STATS_TAG:
2722 		htt_print_pdev_ctrl_path_tx_stats_tlv(tag_buf, len, stats_req);
2723 		break;
2724 	case HTT_STATS_MU_PPDU_DIST_TAG:
2725 		htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(tag_buf, len, stats_req);
2726 		break;
2727 	case HTT_STATS_TX_SCHED_CMN_TAG:
2728 		ath12k_htt_print_stats_tx_sched_cmn_tlv(tag_buf, len, stats_req);
2729 		break;
2730 	case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG:
2731 		ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, len, stats_req);
2732 		break;
2733 	case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG:
2734 		ath12k_htt_print_sched_txq_cmd_posted_tlv(tag_buf, len, stats_req);
2735 		break;
2736 	case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG:
2737 		ath12k_htt_print_sched_txq_cmd_reaped_tlv(tag_buf, len, stats_req);
2738 		break;
2739 	case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG:
2740 		ath12k_htt_print_sched_txq_sched_order_su_tlv(tag_buf, len, stats_req);
2741 		break;
2742 	case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG:
2743 		ath12k_htt_print_sched_txq_sched_ineligibility_tlv(tag_buf, len,
2744 								   stats_req);
2745 		break;
2746 	case HTT_STATS_SCHED_TXQ_SUPERCYCLE_TRIGGER_TAG:
2747 		ath12k_htt_print_sched_txq_supercycle_trigger_tlv(tag_buf, len,
2748 								  stats_req);
2749 		break;
2750 	case HTT_STATS_HW_PDEV_ERRS_TAG:
2751 		ath12k_htt_print_hw_stats_pdev_errs_tlv(tag_buf, len, stats_req);
2752 		break;
2753 	case HTT_STATS_HW_INTR_MISC_TAG:
2754 		ath12k_htt_print_hw_stats_intr_misc_tlv(tag_buf, len, stats_req);
2755 		break;
2756 	case HTT_STATS_WHAL_TX_TAG:
2757 		ath12k_htt_print_hw_stats_whal_tx_tlv(tag_buf, len, stats_req);
2758 		break;
2759 	case HTT_STATS_HW_WAR_TAG:
2760 		ath12k_htt_print_hw_war_tlv(tag_buf, len, stats_req);
2761 		break;
2762 	case HTT_STATS_TX_TQM_CMN_TAG:
2763 		ath12k_htt_print_tx_tqm_cmn_stats_tlv(tag_buf, len, stats_req);
2764 		break;
2765 	case HTT_STATS_TX_TQM_ERROR_STATS_TAG:
2766 		ath12k_htt_print_tx_tqm_error_stats_tlv(tag_buf, len, stats_req);
2767 		break;
2768 	case HTT_STATS_TX_TQM_GEN_MPDU_TAG:
2769 		ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(tag_buf, len, stats_req);
2770 		break;
2771 	case HTT_STATS_TX_TQM_LIST_MPDU_TAG:
2772 		ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(tag_buf, len, stats_req);
2773 		break;
2774 	case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG:
2775 		ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(tag_buf, len, stats_req);
2776 		break;
2777 	case HTT_STATS_TX_TQM_PDEV_TAG:
2778 		ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req);
2779 		break;
2780 	case HTT_STATS_TX_DE_CMN_TAG:
2781 		ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req);
2782 		break;
2783 	case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
2784 		ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req);
2785 		break;
2786 	case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
2787 		ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req);
2788 		break;
2789 	case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
2790 		ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req);
2791 		break;
2792 	case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
2793 		ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req);
2794 		break;
2795 	case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
2796 		ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req);
2797 		break;
2798 	case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
2799 		ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req);
2800 		break;
2801 	case HTT_STATS_TX_DE_COMPL_STATS_TAG:
2802 		ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
2803 		break;
2804 	case HTT_STATS_TX_SELFGEN_CMN_STATS_TAG:
2805 		ath12k_htt_print_tx_selfgen_cmn_stats_tlv(tag_buf, len, stats_req);
2806 		break;
2807 	case HTT_STATS_TX_SELFGEN_AC_STATS_TAG:
2808 		ath12k_htt_print_tx_selfgen_ac_stats_tlv(tag_buf, len, stats_req);
2809 		break;
2810 	case HTT_STATS_TX_SELFGEN_AX_STATS_TAG:
2811 		ath12k_htt_print_tx_selfgen_ax_stats_tlv(tag_buf, len, stats_req);
2812 		break;
2813 	case HTT_STATS_TX_SELFGEN_BE_STATS_TAG:
2814 		ath12k_htt_print_tx_selfgen_be_stats_tlv(tag_buf, len, stats_req);
2815 		break;
2816 	case HTT_STATS_TX_SELFGEN_AC_ERR_STATS_TAG:
2817 		ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(tag_buf, len, stats_req);
2818 		break;
2819 	case HTT_STATS_TX_SELFGEN_AX_ERR_STATS_TAG:
2820 		ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(tag_buf, len, stats_req);
2821 		break;
2822 	case HTT_STATS_TX_SELFGEN_BE_ERR_STATS_TAG:
2823 		ath12k_htt_print_tx_selfgen_be_err_stats_tlv(tag_buf, len, stats_req);
2824 		break;
2825 	case HTT_STATS_TX_SELFGEN_AC_SCHED_STATUS_STATS_TAG:
2826 		ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(tag_buf, len,
2827 								      stats_req);
2828 		break;
2829 	case HTT_STATS_TX_SELFGEN_AX_SCHED_STATUS_STATS_TAG:
2830 		ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(tag_buf, len,
2831 								      stats_req);
2832 		break;
2833 	case HTT_STATS_TX_SELFGEN_BE_SCHED_STATUS_STATS_TAG:
2834 		ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(tag_buf, len,
2835 								      stats_req);
2836 		break;
2837 	case HTT_STATS_STRING_TAG:
2838 		ath12k_htt_print_stats_string_tlv(tag_buf, len, stats_req);
2839 		break;
2840 	case HTT_STATS_SRING_STATS_TAG:
2841 		ath12k_htt_print_sring_stats_tlv(tag_buf, len, stats_req);
2842 		break;
2843 	case HTT_STATS_SFM_CMN_TAG:
2844 		ath12k_htt_print_sfm_cmn_tlv(tag_buf, len, stats_req);
2845 		break;
2846 	case HTT_STATS_SFM_CLIENT_TAG:
2847 		ath12k_htt_print_sfm_client_tlv(tag_buf, len, stats_req);
2848 		break;
2849 	case HTT_STATS_SFM_CLIENT_USER_TAG:
2850 		ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req);
2851 		break;
2852 	case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG:
2853 		ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req);
2854 		break;
2855 	case HTT_STATS_TX_PDEV_MUMIMO_GRP_STATS_TAG:
2856 		ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(tag_buf, len, stats_req);
2857 		break;
2858 	case HTT_STATS_TX_PDEV_MPDU_STATS_TAG:
2859 		ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(tag_buf, len, stats_req);
2860 		break;
2861 	case HTT_STATS_PDEV_CCA_1SEC_HIST_TAG:
2862 	case HTT_STATS_PDEV_CCA_100MSEC_HIST_TAG:
2863 	case HTT_STATS_PDEV_CCA_STAT_CUMULATIVE_TAG:
2864 		ath12k_htt_print_pdev_cca_stats_hist_tlv(tag_buf, len, stats_req);
2865 		break;
2866 	case HTT_STATS_PDEV_CCA_COUNTERS_TAG:
2867 		ath12k_htt_print_pdev_stats_cca_counters_tlv(tag_buf, len, stats_req);
2868 		break;
2869 	case HTT_STATS_PDEV_OBSS_PD_TAG:
2870 		ath12k_htt_print_pdev_obss_pd_stats_tlv(tag_buf, len, stats_req);
2871 		break;
2872 	case HTT_STATS_DMAC_RESET_STATS_TAG:
2873 		ath12k_htt_print_dmac_reset_stats_tlv(tag_buf, len, stats_req);
2874 		break;
2875 	case HTT_STATS_PDEV_SCHED_ALGO_OFDMA_STATS_TAG:
2876 		ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(tag_buf, len, stats_req);
2877 		break;
2878 	case HTT_STATS_TX_PDEV_RATE_STATS_BE_OFDMA_TAG:
2879 		ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(tag_buf, len, stats_req);
2880 		break;
2881 	default:
2882 		break;
2883 	}
2884 
2885 	return 0;
2886 }
2887 
ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base * ab,struct sk_buff * skb)2888 void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
2889 					  struct sk_buff *skb)
2890 {
2891 	struct ath12k_htt_extd_stats_msg *msg;
2892 	struct debug_htt_stats_req *stats_req;
2893 	struct ath12k *ar;
2894 	u32 len, pdev_id, stats_info;
2895 	u64 cookie;
2896 	int ret;
2897 	bool send_completion = false;
2898 
2899 	msg = (struct ath12k_htt_extd_stats_msg *)skb->data;
2900 	cookie = le64_to_cpu(msg->cookie);
2901 
2902 	if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) !=
2903 			 ATH12K_HTT_STATS_MAGIC_VALUE) {
2904 		ath12k_warn(ab, "received invalid htt ext stats event\n");
2905 		return;
2906 	}
2907 
2908 	pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB);
2909 	rcu_read_lock();
2910 	ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
2911 	if (!ar) {
2912 		ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
2913 		goto exit;
2914 	}
2915 
2916 	stats_req = ar->debug.htt_stats.stats_req;
2917 	if (!stats_req)
2918 		goto exit;
2919 
2920 	spin_lock_bh(&ar->data_lock);
2921 
2922 	stats_info = le32_to_cpu(msg->info1);
2923 	stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE);
2924 	if (stats_req->done)
2925 		send_completion = true;
2926 
2927 	spin_unlock_bh(&ar->data_lock);
2928 
2929 	len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH);
2930 	if (len > skb->len) {
2931 		ath12k_warn(ab, "invalid length %d for HTT stats", len);
2932 		goto exit;
2933 	}
2934 
2935 	ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
2936 				     ath12k_dbg_htt_ext_stats_parse,
2937 				     stats_req);
2938 	if (ret)
2939 		ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
2940 
2941 	if (send_completion)
2942 		complete(&stats_req->htt_stats_rcvd);
2943 exit:
2944 	rcu_read_unlock();
2945 }
2946 
ath12k_read_htt_stats_type(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)2947 static ssize_t ath12k_read_htt_stats_type(struct file *file,
2948 					  char __user *user_buf,
2949 					  size_t count, loff_t *ppos)
2950 {
2951 	struct ath12k *ar = file->private_data;
2952 	enum ath12k_dbg_htt_ext_stats_type type;
2953 	char buf[32];
2954 	size_t len;
2955 
2956 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
2957 	type = ar->debug.htt_stats.type;
2958 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
2959 
2960 	len = scnprintf(buf, sizeof(buf), "%u\n", type);
2961 
2962 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2963 }
2964 
ath12k_write_htt_stats_type(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)2965 static ssize_t ath12k_write_htt_stats_type(struct file *file,
2966 					   const char __user *user_buf,
2967 					   size_t count, loff_t *ppos)
2968 {
2969 	struct ath12k *ar = file->private_data;
2970 	enum ath12k_dbg_htt_ext_stats_type type;
2971 	unsigned int cfg_param[4] = {0};
2972 	const int size = 32;
2973 	int num_args;
2974 
2975 	char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
2976 	if (!buf)
2977 		return -ENOMEM;
2978 
2979 	if (copy_from_user(buf, user_buf, count))
2980 		return -EFAULT;
2981 
2982 	num_args = sscanf(buf, "%u %u %u %u %u\n", &type, &cfg_param[0],
2983 			  &cfg_param[1], &cfg_param[2], &cfg_param[3]);
2984 	if (!num_args || num_args > 5)
2985 		return -EINVAL;
2986 
2987 	if (type == ATH12K_DBG_HTT_EXT_STATS_RESET ||
2988 	    type >= ATH12K_DBG_HTT_NUM_EXT_STATS)
2989 		return -EINVAL;
2990 
2991 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
2992 
2993 	ar->debug.htt_stats.type = type;
2994 	ar->debug.htt_stats.cfg_param[0] = cfg_param[0];
2995 	ar->debug.htt_stats.cfg_param[1] = cfg_param[1];
2996 	ar->debug.htt_stats.cfg_param[2] = cfg_param[2];
2997 	ar->debug.htt_stats.cfg_param[3] = cfg_param[3];
2998 
2999 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3000 
3001 	return count;
3002 }
3003 
3004 static const struct file_operations fops_htt_stats_type = {
3005 	.read = ath12k_read_htt_stats_type,
3006 	.write = ath12k_write_htt_stats_type,
3007 	.open = simple_open,
3008 	.owner = THIS_MODULE,
3009 	.llseek = default_llseek,
3010 };
3011 
ath12k_debugfs_htt_stats_req(struct ath12k * ar)3012 static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
3013 {
3014 	struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
3015 	enum ath12k_dbg_htt_ext_stats_type type = stats_req->type;
3016 	u64 cookie;
3017 	int ret, pdev_id;
3018 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
3019 
3020 	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
3021 
3022 	init_completion(&stats_req->htt_stats_rcvd);
3023 
3024 	pdev_id = ath12k_mac_get_target_pdev_id(ar);
3025 	stats_req->done = false;
3026 	stats_req->pdev_id = pdev_id;
3027 
3028 	cookie = u64_encode_bits(ATH12K_HTT_STATS_MAGIC_VALUE,
3029 				 ATH12K_HTT_STATS_COOKIE_MSB);
3030 	cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB);
3031 
3032 	if (stats_req->override_cfg_param) {
3033 		cfg_params.cfg0 = stats_req->cfg_param[0];
3034 		cfg_params.cfg1 = stats_req->cfg_param[1];
3035 		cfg_params.cfg2 = stats_req->cfg_param[2];
3036 		cfg_params.cfg3 = stats_req->cfg_param[3];
3037 	}
3038 
3039 	ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
3040 	if (ret) {
3041 		ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
3042 		return ret;
3043 	}
3044 	if (!wait_for_completion_timeout(&stats_req->htt_stats_rcvd, 3 * HZ)) {
3045 		spin_lock_bh(&ar->data_lock);
3046 		if (!stats_req->done) {
3047 			stats_req->done = true;
3048 			spin_unlock_bh(&ar->data_lock);
3049 			ath12k_warn(ar->ab, "stats request timed out\n");
3050 			return -ETIMEDOUT;
3051 		}
3052 		spin_unlock_bh(&ar->data_lock);
3053 	}
3054 
3055 	return 0;
3056 }
3057 
ath12k_open_htt_stats(struct inode * inode,struct file * file)3058 static int ath12k_open_htt_stats(struct inode *inode,
3059 				 struct file *file)
3060 {
3061 	struct ath12k *ar = inode->i_private;
3062 	struct debug_htt_stats_req *stats_req;
3063 	enum ath12k_dbg_htt_ext_stats_type type = ar->debug.htt_stats.type;
3064 	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
3065 	int ret;
3066 
3067 	if (type == ATH12K_DBG_HTT_EXT_STATS_RESET)
3068 		return -EPERM;
3069 
3070 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3071 
3072 	if (ah->state != ATH12K_HW_STATE_ON) {
3073 		ret = -ENETDOWN;
3074 		goto err_unlock;
3075 	}
3076 
3077 	if (ar->debug.htt_stats.stats_req) {
3078 		ret = -EAGAIN;
3079 		goto err_unlock;
3080 	}
3081 
3082 	stats_req = kzalloc(sizeof(*stats_req) + ATH12K_HTT_STATS_BUF_SIZE, GFP_KERNEL);
3083 	if (!stats_req) {
3084 		ret = -ENOMEM;
3085 		goto err_unlock;
3086 	}
3087 
3088 	ar->debug.htt_stats.stats_req = stats_req;
3089 	stats_req->type = type;
3090 	stats_req->cfg_param[0] = ar->debug.htt_stats.cfg_param[0];
3091 	stats_req->cfg_param[1] = ar->debug.htt_stats.cfg_param[1];
3092 	stats_req->cfg_param[2] = ar->debug.htt_stats.cfg_param[2];
3093 	stats_req->cfg_param[3] = ar->debug.htt_stats.cfg_param[3];
3094 	stats_req->override_cfg_param = !!stats_req->cfg_param[0] ||
3095 					!!stats_req->cfg_param[1] ||
3096 					!!stats_req->cfg_param[2] ||
3097 					!!stats_req->cfg_param[3];
3098 
3099 	ret = ath12k_debugfs_htt_stats_req(ar);
3100 	if (ret < 0)
3101 		goto out;
3102 
3103 	file->private_data = stats_req;
3104 
3105 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3106 
3107 	return 0;
3108 out:
3109 	kfree(stats_req);
3110 	ar->debug.htt_stats.stats_req = NULL;
3111 err_unlock:
3112 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3113 
3114 	return ret;
3115 }
3116 
ath12k_release_htt_stats(struct inode * inode,struct file * file)3117 static int ath12k_release_htt_stats(struct inode *inode,
3118 				    struct file *file)
3119 {
3120 	struct ath12k *ar = inode->i_private;
3121 
3122 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3123 	kfree(file->private_data);
3124 	ar->debug.htt_stats.stats_req = NULL;
3125 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3126 
3127 	return 0;
3128 }
3129 
ath12k_read_htt_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)3130 static ssize_t ath12k_read_htt_stats(struct file *file,
3131 				     char __user *user_buf,
3132 				     size_t count, loff_t *ppos)
3133 {
3134 	struct debug_htt_stats_req *stats_req = file->private_data;
3135 	char *buf;
3136 	u32 length;
3137 
3138 	buf = stats_req->buf;
3139 	length = min_t(u32, stats_req->buf_len, ATH12K_HTT_STATS_BUF_SIZE);
3140 	return simple_read_from_buffer(user_buf, count, ppos, buf, length);
3141 }
3142 
3143 static const struct file_operations fops_dump_htt_stats = {
3144 	.open = ath12k_open_htt_stats,
3145 	.release = ath12k_release_htt_stats,
3146 	.read = ath12k_read_htt_stats,
3147 	.owner = THIS_MODULE,
3148 	.llseek = default_llseek,
3149 };
3150 
ath12k_write_htt_stats_reset(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)3151 static ssize_t ath12k_write_htt_stats_reset(struct file *file,
3152 					    const char __user *user_buf,
3153 					    size_t count, loff_t *ppos)
3154 {
3155 	struct ath12k *ar = file->private_data;
3156 	enum ath12k_dbg_htt_ext_stats_type type;
3157 	struct htt_ext_stats_cfg_params cfg_params = { 0 };
3158 	u8 param_pos;
3159 	int ret;
3160 
3161 	ret = kstrtou32_from_user(user_buf, count, 0, &type);
3162 	if (ret)
3163 		return ret;
3164 
3165 	if (type >= ATH12K_DBG_HTT_NUM_EXT_STATS ||
3166 	    type == ATH12K_DBG_HTT_EXT_STATS_RESET)
3167 		return -E2BIG;
3168 
3169 	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3170 	cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET;
3171 	param_pos = (type >> 5) + 1;
3172 
3173 	switch (param_pos) {
3174 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES:
3175 		cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type);
3176 		break;
3177 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES:
3178 		cfg_params.cfg2 = ATH12K_HTT_STATS_RESET_BITMAP32_BIT(cfg_params.cfg0 +
3179 								      type);
3180 		break;
3181 	case ATH12K_HTT_STATS_RESET_PARAM_CFG_128_BYTES:
3182 		cfg_params.cfg3 = ATH12K_HTT_STATS_RESET_BITMAP64_BIT(cfg_params.cfg0 +
3183 								      type);
3184 		break;
3185 	default:
3186 		break;
3187 	}
3188 
3189 	ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar,
3190 						 ATH12K_DBG_HTT_EXT_STATS_RESET,
3191 						 &cfg_params,
3192 						 0ULL);
3193 	if (ret) {
3194 		ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
3195 		wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3196 		return ret;
3197 	}
3198 
3199 	ar->debug.htt_stats.reset = type;
3200 	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3201 
3202 	return count;
3203 }
3204 
3205 static const struct file_operations fops_htt_stats_reset = {
3206 	.write = ath12k_write_htt_stats_reset,
3207 	.open = simple_open,
3208 	.owner = THIS_MODULE,
3209 	.llseek = default_llseek,
3210 };
3211 
ath12k_debugfs_htt_stats_register(struct ath12k * ar)3212 void ath12k_debugfs_htt_stats_register(struct ath12k *ar)
3213 {
3214 	debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev,
3215 			    ar, &fops_htt_stats_type);
3216 	debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev,
3217 			    ar, &fops_dump_htt_stats);
3218 	debugfs_create_file("htt_stats_reset", 0200, ar->debug.debugfs_pdev,
3219 			    ar, &fops_htt_stats_reset);
3220 }
3221