Loading...
Note: File does not exist in v6.8.
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
14static u32
15print_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
43static u32
44print_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
51static 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
91static void
92htt_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
241static void
242htt_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
262static void
263htt_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
283static void
284htt_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
304static void
305htt_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
395static void
396htt_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
416static void
417htt_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
437static void
438ath12k_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
462static void
463ath12k_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
548static void
549ath12k_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
566static void
567ath12k_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
584static void
585ath12k_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
605static void
606ath12k_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
626static void
627ath12k_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
647static void
648ath12k_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
797static void
798ath12k_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
820static void
821ath12k_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
865static void
866ath12k_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
897static void
898ath12k_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
963static void
964ath12k_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
1035static void
1036ath12k_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
1053static void
1054ath12k_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
1071static void
1072ath12k_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
1089static void
1090ath12k_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
1168static void
1169ath12k_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
1210static void
1211ath12k_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
1250static void
1251ath12k_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
1333static void
1334ath12k_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
1389static void
1390ath12k_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
1423static void
1424ath12k_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
1447static void
1448ath12k_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
1471static void
1472ath12k_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
1498static void
1499ath12k_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
1542static void
1543ath12k_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 - 1,
1566 "\n\n");
1567
1568 stats_req->buf_len = len;
1569}
1570
1571static void
1572ath12k_htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, u16 tag_len,
1573 struct debug_htt_stats_req *stats_req)
1574{
1575 const struct ath12k_htt_tx_selfgen_ax_stats_tlv *htt_stats_buf = tag_buf;
1576 u8 *buf = stats_req->buf;
1577 u32 len = stats_req->buf_len;
1578 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1579
1580 if (tag_len < sizeof(*htt_stats_buf))
1581 return;
1582
1583 len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:\n");
1584 len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_tried = %u\n",
1585 le32_to_cpu(htt_stats_buf->ax_su_ndpa));
1586 len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_tried = %u\n",
1587 le32_to_cpu(htt_stats_buf->ax_su_ndp));
1588 len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_tried = %u\n",
1589 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa));
1590 len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_tried = %u\n",
1591 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp));
1592 len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpollX_tried = ", 1,
1593 htt_stats_buf->ax_mu_mimo_brpoll,
1594 ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1, "\n");
1595 len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n",
1596 le32_to_cpu(htt_stats_buf->ax_basic_trigger));
1597 len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger = %u\n",
1598 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger));
1599 len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n",
1600 le32_to_cpu(htt_stats_buf->ax_bsr_trigger));
1601 len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n",
1602 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger));
1603 len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n\n",
1604 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger));
1605
1606 stats_req->buf_len = len;
1607}
1608
1609static void
1610ath12k_htt_print_tx_selfgen_be_stats_tlv(const void *tag_buf, u16 tag_len,
1611 struct debug_htt_stats_req *stats_req)
1612{
1613 const struct ath12k_htt_tx_selfgen_be_stats_tlv *htt_stats_buf = tag_buf;
1614 u8 *buf = stats_req->buf;
1615 u32 len = stats_req->buf_len;
1616 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1617
1618 if (tag_len < sizeof(*htt_stats_buf))
1619 return;
1620
1621 len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_STATS_TLV:\n");
1622 len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_queued = %u\n",
1623 le32_to_cpu(htt_stats_buf->be_su_ndpa_queued));
1624 len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_tried = %u\n",
1625 le32_to_cpu(htt_stats_buf->be_su_ndpa));
1626 len += scnprintf(buf + len, buf_len - len, "be_su_ndp_queued = %u\n",
1627 le32_to_cpu(htt_stats_buf->be_su_ndp_queued));
1628 len += scnprintf(buf + len, buf_len - len, "be_su_ndp_tried = %u\n",
1629 le32_to_cpu(htt_stats_buf->be_su_ndp));
1630 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_queued = %u\n",
1631 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_queued));
1632 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_tried = %u\n",
1633 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa));
1634 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_queued = %u\n",
1635 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_queued));
1636 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_tried = %u\n",
1637 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp));
1638 len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_queued = ", 1,
1639 htt_stats_buf->be_mu_mimo_brpoll_queued,
1640 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1641 "\n");
1642 len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_tried = ", 1,
1643 htt_stats_buf->be_mu_mimo_brpoll,
1644 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1645 "\n");
1646 len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger = ",
1647 htt_stats_buf->be_ul_mumimo_trigger,
1648 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1649 len += scnprintf(buf + len, buf_len - len, "be_basic_trigger = %u\n",
1650 le32_to_cpu(htt_stats_buf->be_basic_trigger));
1651 len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trigger = %u\n",
1652 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger));
1653 len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger = %u\n",
1654 le32_to_cpu(htt_stats_buf->be_bsr_trigger));
1655 len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger = %u\n",
1656 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger));
1657 len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger = %u\n\n",
1658 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger));
1659
1660 stats_req->buf_len = len;
1661}
1662
1663static void
1664ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(const void *tag_buf, u16 tag_len,
1665 struct debug_htt_stats_req *stats_req)
1666{
1667 const struct ath12k_htt_tx_selfgen_ac_err_stats_tlv *htt_stats_buf = tag_buf;
1668 u8 *buf = stats_req->buf;
1669 u32 len = stats_req->buf_len;
1670 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1671
1672 if (tag_len < sizeof(*htt_stats_buf))
1673 return;
1674
1675 len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:\n");
1676 len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_err = %u\n",
1677 le32_to_cpu(htt_stats_buf->ac_su_ndp_err));
1678 len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_err = %u\n",
1679 le32_to_cpu(htt_stats_buf->ac_su_ndpa_err));
1680 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u\n",
1681 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndpa_err));
1682 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u\n",
1683 le32_to_cpu(htt_stats_buf->ac_mu_mimo_ndp_err));
1684 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u\n",
1685 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp1_err));
1686 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u\n",
1687 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp2_err));
1688 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n\n",
1689 le32_to_cpu(htt_stats_buf->ac_mu_mimo_brp3_err));
1690
1691 stats_req->buf_len = len;
1692}
1693
1694static void
1695ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf, u16 tag_len,
1696 struct debug_htt_stats_req *stats_req)
1697{
1698 const struct ath12k_htt_tx_selfgen_ax_err_stats_tlv *htt_stats_buf = tag_buf;
1699 u8 *buf = stats_req->buf;
1700 u32 len = stats_req->buf_len;
1701 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1702
1703 if (tag_len < sizeof(*htt_stats_buf))
1704 return;
1705
1706 len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:\n");
1707 len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_err = %u\n",
1708 le32_to_cpu(htt_stats_buf->ax_su_ndp_err));
1709 len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_err = %u\n",
1710 le32_to_cpu(htt_stats_buf->ax_su_ndpa_err));
1711 len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u\n",
1712 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndpa_err));
1713 len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u\n",
1714 le32_to_cpu(htt_stats_buf->ax_mu_mimo_ndp_err));
1715 len += print_array_to_buf_index(buf, len, "ax_mu_mimo_brpX_err", 1,
1716 htt_stats_buf->ax_mu_mimo_brp_err,
1717 ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS - 1,
1718 "\n");
1719 len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n",
1720 le32_to_cpu(htt_stats_buf->ax_basic_trigger_err));
1721 len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_total_trigger_err = %u\n",
1722 le32_to_cpu(htt_stats_buf->ax_ulmumimo_trigger_err));
1723 len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n",
1724 le32_to_cpu(htt_stats_buf->ax_bsr_trigger_err));
1725 len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n",
1726 le32_to_cpu(htt_stats_buf->ax_mu_bar_trigger_err));
1727 len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n\n",
1728 le32_to_cpu(htt_stats_buf->ax_mu_rts_trigger_err));
1729
1730 stats_req->buf_len = len;
1731}
1732
1733static void
1734ath12k_htt_print_tx_selfgen_be_err_stats_tlv(const void *tag_buf, u16 tag_len,
1735 struct debug_htt_stats_req *stats_req)
1736{
1737 const struct ath12k_htt_tx_selfgen_be_err_stats_tlv *htt_stats_buf = tag_buf;
1738 u8 *buf = stats_req->buf;
1739 u32 len = stats_req->buf_len;
1740 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1741
1742 if (tag_len < sizeof(*htt_stats_buf))
1743 return;
1744
1745 len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_BE_ERR_STATS_TLV:\n");
1746 len += scnprintf(buf + len, buf_len - len, "be_su_ndp_err = %u\n",
1747 le32_to_cpu(htt_stats_buf->be_su_ndp_err));
1748 len += scnprintf(buf + len, buf_len - len, "be_su_ndp_flushed = %u\n",
1749 le32_to_cpu(htt_stats_buf->be_su_ndp_flushed));
1750 len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_err = %u\n",
1751 le32_to_cpu(htt_stats_buf->be_su_ndpa_err));
1752 len += scnprintf(buf + len, buf_len - len, "be_su_ndpa_flushed = %u\n",
1753 le32_to_cpu(htt_stats_buf->be_su_ndpa_flushed));
1754 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_err = %u\n",
1755 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_err));
1756 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndpa_flushed = %u\n",
1757 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndpa_flushed));
1758 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_err = %u\n",
1759 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_err));
1760 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_ndp_flushed = %u\n",
1761 le32_to_cpu(htt_stats_buf->be_mu_mimo_ndp_flushed));
1762 len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpX_err", 1,
1763 htt_stats_buf->be_mu_mimo_brp_err,
1764 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1765 "\n");
1766 len += print_array_to_buf_index(buf, len, "be_mu_mimo_brpollX_flushed", 1,
1767 htt_stats_buf->be_mu_mimo_brpoll_flushed,
1768 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS - 1,
1769 "\n");
1770 len += print_array_to_buf(buf, len, "be_mu_mimo_num_cbf_rcvd_on_brp_err",
1771 htt_stats_buf->be_mu_mimo_brp_err_num_cbf_rxd,
1772 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1773 len += print_array_to_buf(buf, len, "be_ul_mumimo_trigger_err",
1774 htt_stats_buf->be_ul_mumimo_trigger_err,
1775 ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS, "\n");
1776 len += scnprintf(buf + len, buf_len - len, "be_basic_trigger_err = %u\n",
1777 le32_to_cpu(htt_stats_buf->be_basic_trigger_err));
1778 len += scnprintf(buf + len, buf_len - len, "be_ulmumimo_total_trig_err = %u\n",
1779 le32_to_cpu(htt_stats_buf->be_ulmumimo_trigger_err));
1780 len += scnprintf(buf + len, buf_len - len, "be_bsr_trigger_err = %u\n",
1781 le32_to_cpu(htt_stats_buf->be_bsr_trigger_err));
1782 len += scnprintf(buf + len, buf_len - len, "be_mu_bar_trigger_err = %u\n",
1783 le32_to_cpu(htt_stats_buf->be_mu_bar_trigger_err));
1784 len += scnprintf(buf + len, buf_len - len, "be_mu_rts_trigger_err = %u\n\n",
1785 le32_to_cpu(htt_stats_buf->be_mu_rts_trigger_err));
1786
1787 stats_req->buf_len = len;
1788}
1789
1790static void
1791ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1792 struct debug_htt_stats_req *stats)
1793{
1794 const struct ath12k_htt_tx_selfgen_ac_sched_status_stats_tlv *htt_stats_buf =
1795 tag_buf;
1796 u8 *buf = stats->buf;
1797 u32 len = stats->buf_len;
1798 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1799
1800 if (tag_len < sizeof(*htt_stats_buf))
1801 return;
1802
1803 len += scnprintf(buf + len, buf_len - len,
1804 "HTT_TX_SELFGEN_AC_SCHED_STATUS_STATS_TLV:\n");
1805 len += print_array_to_buf(buf, len, "ac_su_ndpa_sch_status",
1806 htt_stats_buf->ac_su_ndpa_sch_status,
1807 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1808 len += print_array_to_buf(buf, len, "ac_su_ndp_sch_status",
1809 htt_stats_buf->ac_su_ndp_sch_status,
1810 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1811 len += print_array_to_buf(buf, len, "ac_mu_mimo_ndpa_sch_status",
1812 htt_stats_buf->ac_mu_mimo_ndpa_sch_status,
1813 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1814 len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_status",
1815 htt_stats_buf->ac_mu_mimo_ndp_sch_status,
1816 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1817 len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_status",
1818 htt_stats_buf->ac_mu_mimo_brp_sch_status,
1819 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1820 len += print_array_to_buf(buf, len, "ac_su_ndp_sch_flag_err",
1821 htt_stats_buf->ac_su_ndp_sch_flag_err,
1822 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1823 len += print_array_to_buf(buf, len, "ac_mu_mimo_ndp_sch_flag_err",
1824 htt_stats_buf->ac_mu_mimo_ndp_sch_flag_err,
1825 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1826 len += print_array_to_buf(buf, len, "ac_mu_mimo_brp_sch_flag_err",
1827 htt_stats_buf->ac_mu_mimo_brp_sch_flag_err,
1828 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1829
1830 stats->buf_len = len;
1831}
1832
1833static void
1834ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1835 struct debug_htt_stats_req *stats)
1836{
1837 const struct ath12k_htt_tx_selfgen_ax_sched_status_stats_tlv *htt_stats_buf =
1838 tag_buf;
1839 u8 *buf = stats->buf;
1840 u32 len = stats->buf_len;
1841 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1842
1843 if (tag_len < sizeof(*htt_stats_buf))
1844 return;
1845
1846 len += scnprintf(buf + len, buf_len - len,
1847 "HTT_TX_SELFGEN_AX_SCHED_STATUS_STATS_TLV:\n");
1848 len += print_array_to_buf(buf, len, "ax_su_ndpa_sch_status",
1849 htt_stats_buf->ax_su_ndpa_sch_status,
1850 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1851 len += print_array_to_buf(buf, len, "ax_su_ndp_sch_status",
1852 htt_stats_buf->ax_su_ndp_sch_status,
1853 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1854 len += print_array_to_buf(buf, len, "ax_mu_mimo_ndpa_sch_status",
1855 htt_stats_buf->ax_mu_mimo_ndpa_sch_status,
1856 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1857 len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_status",
1858 htt_stats_buf->ax_mu_mimo_ndp_sch_status,
1859 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1860 len += print_array_to_buf(buf, len, "ax_mu_brp_sch_status",
1861 htt_stats_buf->ax_mu_brp_sch_status,
1862 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1863 len += print_array_to_buf(buf, len, "ax_mu_bar_sch_status",
1864 htt_stats_buf->ax_mu_bar_sch_status,
1865 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1866 len += print_array_to_buf(buf, len, "ax_basic_trig_sch_status",
1867 htt_stats_buf->ax_basic_trig_sch_status,
1868 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1869 len += print_array_to_buf(buf, len, "ax_su_ndp_sch_flag_err",
1870 htt_stats_buf->ax_su_ndp_sch_flag_err,
1871 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1872 len += print_array_to_buf(buf, len, "ax_mu_mimo_ndp_sch_flag_err",
1873 htt_stats_buf->ax_mu_mimo_ndp_sch_flag_err,
1874 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1875 len += print_array_to_buf(buf, len, "ax_mu_brp_sch_flag_err",
1876 htt_stats_buf->ax_mu_brp_sch_flag_err,
1877 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1878 len += print_array_to_buf(buf, len, "ax_mu_bar_sch_flag_err",
1879 htt_stats_buf->ax_mu_bar_sch_flag_err,
1880 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1881 len += print_array_to_buf(buf, len, "ax_basic_trig_sch_flag_err",
1882 htt_stats_buf->ax_basic_trig_sch_flag_err,
1883 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1884 len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_status",
1885 htt_stats_buf->ax_ulmumimo_trig_sch_status,
1886 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1887 len += print_array_to_buf(buf, len, "ax_ulmumimo_trig_sch_flag_err",
1888 htt_stats_buf->ax_ulmumimo_trig_sch_flag_err,
1889 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1890
1891 stats->buf_len = len;
1892}
1893
1894static void
1895ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(const void *tag_buf, u16 tag_len,
1896 struct debug_htt_stats_req *stats)
1897{
1898 const struct ath12k_htt_tx_selfgen_be_sched_status_stats_tlv *htt_stats_buf =
1899 tag_buf;
1900 u8 *buf = stats->buf;
1901 u32 len = stats->buf_len;
1902 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1903
1904 if (tag_len < sizeof(*htt_stats_buf))
1905 return;
1906
1907 len += scnprintf(buf + len, buf_len - len,
1908 "HTT_TX_SELFGEN_BE_SCHED_STATUS_STATS_TLV:\n");
1909 len += print_array_to_buf(buf, len, "be_su_ndpa_sch_status",
1910 htt_stats_buf->be_su_ndpa_sch_status,
1911 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1912 len += print_array_to_buf(buf, len, "be_su_ndp_sch_status",
1913 htt_stats_buf->be_su_ndp_sch_status,
1914 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1915 len += print_array_to_buf(buf, len, "be_mu_mimo_ndpa_sch_status",
1916 htt_stats_buf->be_mu_mimo_ndpa_sch_status,
1917 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1918 len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_status",
1919 htt_stats_buf->be_mu_mimo_ndp_sch_status,
1920 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1921 len += print_array_to_buf(buf, len, "be_mu_brp_sch_status",
1922 htt_stats_buf->be_mu_brp_sch_status,
1923 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1924 len += print_array_to_buf(buf, len, "be_mu_bar_sch_status",
1925 htt_stats_buf->be_mu_bar_sch_status,
1926 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1927 len += print_array_to_buf(buf, len, "be_basic_trig_sch_status",
1928 htt_stats_buf->be_basic_trig_sch_status,
1929 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1930 len += print_array_to_buf(buf, len, "be_su_ndp_sch_flag_err",
1931 htt_stats_buf->be_su_ndp_sch_flag_err,
1932 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1933 len += print_array_to_buf(buf, len, "be_mu_mimo_ndp_sch_flag_err",
1934 htt_stats_buf->be_mu_mimo_ndp_sch_flag_err,
1935 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1936 len += print_array_to_buf(buf, len, "be_mu_brp_sch_flag_err",
1937 htt_stats_buf->be_mu_brp_sch_flag_err,
1938 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1939 len += print_array_to_buf(buf, len, "be_mu_bar_sch_flag_err",
1940 htt_stats_buf->be_mu_bar_sch_flag_err,
1941 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1942 len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1943 htt_stats_buf->be_basic_trig_sch_flag_err,
1944 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n");
1945 len += print_array_to_buf(buf, len, "be_basic_trig_sch_flag_err",
1946 htt_stats_buf->be_basic_trig_sch_flag_err,
1947 ATH12K_HTT_TX_PDEV_STATS_NUM_TX_ERR_STATUS, "\n");
1948 len += print_array_to_buf(buf, len, "be_ulmumimo_trig_sch_flag_err",
1949 htt_stats_buf->be_ulmumimo_trig_sch_flag_err,
1950 ATH12K_HTT_TX_SELFGEN_SCH_TSFLAG_ERR_STATS, "\n\n");
1951
1952 stats->buf_len = len;
1953}
1954
1955static void
1956ath12k_htt_print_stats_string_tlv(const void *tag_buf, u16 tag_len,
1957 struct debug_htt_stats_req *stats_req)
1958{
1959 const struct ath12k_htt_stats_string_tlv *htt_stats_buf = tag_buf;
1960 u8 *buf = stats_req->buf;
1961 u32 len = stats_req->buf_len;
1962 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1963 u8 i;
1964 u16 index = 0;
1965 u32 datum;
1966 char data[ATH12K_HTT_MAX_STRING_LEN] = {0};
1967
1968 tag_len = tag_len >> 2;
1969
1970 len += scnprintf(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:\n");
1971 for (i = 0; i < tag_len; i++) {
1972 datum = __le32_to_cpu(htt_stats_buf->data[i]);
1973 index += scnprintf(&data[index], ATH12K_HTT_MAX_STRING_LEN - index,
1974 "%.*s", 4, (char *)&datum);
1975 if (index >= ATH12K_HTT_MAX_STRING_LEN)
1976 break;
1977 }
1978 len += scnprintf(buf + len, buf_len - len, "data = %s\n\n", data);
1979
1980 stats_req->buf_len = len;
1981}
1982
1983static void
1984ath12k_htt_print_sring_stats_tlv(const void *tag_buf, u16 tag_len,
1985 struct debug_htt_stats_req *stats_req)
1986{
1987 const struct ath12k_htt_sring_stats_tlv *htt_stats_buf = tag_buf;
1988 u8 *buf = stats_req->buf;
1989 u32 len = stats_req->buf_len;
1990 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1991 u32 mac_id_word;
1992 u32 avail_words;
1993 u32 head_tail_ptr;
1994 u32 sring_stat;
1995 u32 tail_ptr;
1996
1997 if (tag_len < sizeof(*htt_stats_buf))
1998 return;
1999
2000 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__ring_id__arena__ep);
2001 avail_words = __le32_to_cpu(htt_stats_buf->num_avail_words__num_valid_words);
2002 head_tail_ptr = __le32_to_cpu(htt_stats_buf->head_ptr__tail_ptr);
2003 sring_stat = __le32_to_cpu(htt_stats_buf->consumer_empty__producer_full);
2004 tail_ptr = __le32_to_cpu(htt_stats_buf->prefetch_count__internal_tail_ptr);
2005
2006 len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n");
2007 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2008 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_MAC_ID));
2009 len += scnprintf(buf + len, buf_len - len, "ring_id = %u\n",
2010 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_RING_ID));
2011 len += scnprintf(buf + len, buf_len - len, "arena = %u\n",
2012 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_ARENA));
2013 len += scnprintf(buf + len, buf_len - len, "ep = %u\n",
2014 u32_get_bits(mac_id_word, ATH12K_HTT_SRING_STATS_EP));
2015 len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n",
2016 le32_to_cpu(htt_stats_buf->base_addr_lsb));
2017 len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n",
2018 le32_to_cpu(htt_stats_buf->base_addr_msb));
2019 len += scnprintf(buf + len, buf_len - len, "ring_size = %u\n",
2020 le32_to_cpu(htt_stats_buf->ring_size));
2021 len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
2022 le32_to_cpu(htt_stats_buf->elem_size));
2023 len += scnprintf(buf + len, buf_len - len, "num_avail_words = %u\n",
2024 u32_get_bits(avail_words,
2025 ATH12K_HTT_SRING_STATS_NUM_AVAIL_WORDS));
2026 len += scnprintf(buf + len, buf_len - len, "num_valid_words = %u\n",
2027 u32_get_bits(avail_words,
2028 ATH12K_HTT_SRING_STATS_NUM_VALID_WORDS));
2029 len += scnprintf(buf + len, buf_len - len, "head_ptr = %u\n",
2030 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_HEAD_PTR));
2031 len += scnprintf(buf + len, buf_len - len, "tail_ptr = %u\n",
2032 u32_get_bits(head_tail_ptr, ATH12K_HTT_SRING_STATS_TAIL_PTR));
2033 len += scnprintf(buf + len, buf_len - len, "consumer_empty = %u\n",
2034 u32_get_bits(sring_stat,
2035 ATH12K_HTT_SRING_STATS_CONSUMER_EMPTY));
2036 len += scnprintf(buf + len, buf_len - len, "producer_full = %u\n",
2037 u32_get_bits(head_tail_ptr,
2038 ATH12K_HTT_SRING_STATS_PRODUCER_FULL));
2039 len += scnprintf(buf + len, buf_len - len, "prefetch_count = %u\n",
2040 u32_get_bits(tail_ptr, ATH12K_HTT_SRING_STATS_PREFETCH_COUNT));
2041 len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %u\n\n",
2042 u32_get_bits(tail_ptr,
2043 ATH12K_HTT_SRING_STATS_INTERNAL_TAIL_PTR));
2044
2045 stats_req->buf_len = len;
2046}
2047
2048static void
2049ath12k_htt_print_sfm_cmn_tlv(const void *tag_buf, u16 tag_len,
2050 struct debug_htt_stats_req *stats_req)
2051{
2052 const struct ath12k_htt_sfm_cmn_tlv *htt_stats_buf = tag_buf;
2053 u8 *buf = stats_req->buf;
2054 u32 len = stats_req->buf_len;
2055 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2056 u32 mac_id_word;
2057
2058 if (tag_len < sizeof(*htt_stats_buf))
2059 return;
2060
2061 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
2062
2063 len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n");
2064 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2065 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2066 len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n",
2067 le32_to_cpu(htt_stats_buf->buf_total));
2068 len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n",
2069 le32_to_cpu(htt_stats_buf->mem_empty));
2070 len += scnprintf(buf + len, buf_len - len, "deallocate_bufs = %u\n",
2071 le32_to_cpu(htt_stats_buf->deallocate_bufs));
2072 len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2073 le32_to_cpu(htt_stats_buf->num_records));
2074
2075 stats_req->buf_len = len;
2076}
2077
2078static void
2079ath12k_htt_print_sfm_client_tlv(const void *tag_buf, u16 tag_len,
2080 struct debug_htt_stats_req *stats_req)
2081{
2082 const struct ath12k_htt_sfm_client_tlv *htt_stats_buf = tag_buf;
2083 u8 *buf = stats_req->buf;
2084 u32 len = stats_req->buf_len;
2085 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2086
2087 if (tag_len < sizeof(*htt_stats_buf))
2088 return;
2089
2090 len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:\n");
2091 len += scnprintf(buf + len, buf_len - len, "client_id = %u\n",
2092 le32_to_cpu(htt_stats_buf->client_id));
2093 len += scnprintf(buf + len, buf_len - len, "buf_min = %u\n",
2094 le32_to_cpu(htt_stats_buf->buf_min));
2095 len += scnprintf(buf + len, buf_len - len, "buf_max = %u\n",
2096 le32_to_cpu(htt_stats_buf->buf_max));
2097 len += scnprintf(buf + len, buf_len - len, "buf_busy = %u\n",
2098 le32_to_cpu(htt_stats_buf->buf_busy));
2099 len += scnprintf(buf + len, buf_len - len, "buf_alloc = %u\n",
2100 le32_to_cpu(htt_stats_buf->buf_alloc));
2101 len += scnprintf(buf + len, buf_len - len, "buf_avail = %u\n",
2102 le32_to_cpu(htt_stats_buf->buf_avail));
2103 len += scnprintf(buf + len, buf_len - len, "num_users = %u\n\n",
2104 le32_to_cpu(htt_stats_buf->num_users));
2105
2106 stats_req->buf_len = len;
2107}
2108
2109static void
2110ath12k_htt_print_sfm_client_user_tlv(const void *tag_buf, u16 tag_len,
2111 struct debug_htt_stats_req *stats_req)
2112{
2113 const struct ath12k_htt_sfm_client_user_tlv *htt_stats_buf = tag_buf;
2114 u8 *buf = stats_req->buf;
2115 u32 len = stats_req->buf_len;
2116 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2117 u16 num_elems = tag_len >> 2;
2118
2119 len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV:\n");
2120 len += print_array_to_buf(buf, len, "dwords_used_by_user_n",
2121 htt_stats_buf->dwords_used_by_user_n,
2122 num_elems, "\n\n");
2123
2124 stats_req->buf_len = len;
2125}
2126
2127static void
2128ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, u16 tag_len,
2129 struct debug_htt_stats_req *stats_req)
2130{
2131 const struct ath12k_htt_tx_pdev_mu_mimo_sch_stats_tlv *htt_stats_buf = tag_buf;
2132 u8 *buf = stats_req->buf;
2133 u32 len = stats_req->buf_len;
2134 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2135 u8 i;
2136
2137 if (tag_len < sizeof(*htt_stats_buf))
2138 return;
2139
2140 len += scnprintf(buf + len, buf_len - len,
2141 "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:\n");
2142 len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n",
2143 le32_to_cpu(htt_stats_buf->mu_mimo_sch_posted));
2144 len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n",
2145 le32_to_cpu(htt_stats_buf->mu_mimo_sch_failed));
2146 len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n",
2147 le32_to_cpu(htt_stats_buf->mu_mimo_ppdu_posted));
2148 len += scnprintf(buf + len, buf_len - len,
2149 "\nac_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2150 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[0]));
2151 for (i = 1; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2152 len += scnprintf(buf + len, buf_len - len,
2153 "ac_mu_mimo_sch_posted_per_group_index %u ", i);
2154 len += scnprintf(buf + len, buf_len - len,
2155 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2156 le32_to_cpu(htt_stats_buf->ac_mu_mimo_per_grp_sz[i]));
2157 }
2158
2159 for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2160 len += scnprintf(buf + len, buf_len - len,
2161 "ac_mu_mimo_sch_posted_per_group_index %u ",
2162 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS);
2163 len += scnprintf(buf + len, buf_len - len,
2164 "(TOTAL STREAMS = %u) = %u\n",
2165 i + ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS + 1,
2166 le32_to_cpu(htt_stats_buf->ac_mu_mimo_grp_sz_ext[i]));
2167 }
2168
2169 len += scnprintf(buf + len, buf_len - len,
2170 "\nax_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2171 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[0]));
2172 for (i = 1; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2173 len += scnprintf(buf + len, buf_len - len,
2174 "ax_mu_mimo_sch_posted_per_group_index %u ", i);
2175 len += scnprintf(buf + len, buf_len - len,
2176 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2177 le32_to_cpu(htt_stats_buf->ax_mu_mimo_per_grp_sz[i]));
2178 }
2179
2180 len += scnprintf(buf + len, buf_len - len,
2181 "\nbe_mu_mimo_sch_posted_per_group_index %u (SU) = %u\n", 0,
2182 le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[0]));
2183 for (i = 1; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2184 len += scnprintf(buf + len, buf_len - len,
2185 "be_mu_mimo_sch_posted_per_group_index %u ", i);
2186 len += scnprintf(buf + len, buf_len - len,
2187 "(TOTAL STREAMS = %u) = %u\n", i + 1,
2188 le32_to_cpu(htt_stats_buf->be_mu_mimo_per_grp_sz[i]));
2189 }
2190
2191 len += scnprintf(buf + len, buf_len - len, "\n11ac MU_MIMO SCH STATS:\n");
2192 for (i = 0; i < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS; i++) {
2193 len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_sch_nusers_");
2194 len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2195 le32_to_cpu(htt_stats_buf->ac_mu_mimo_sch_nusers[i]));
2196 }
2197
2198 len += scnprintf(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:\n");
2199 for (i = 0; i < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS; i++) {
2200 len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_sch_nusers_");
2201 len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2202 le32_to_cpu(htt_stats_buf->ax_mu_mimo_sch_nusers[i]));
2203 }
2204
2205 len += scnprintf(buf + len, buf_len - len, "\n11be MU_MIMO SCH STATS:\n");
2206 for (i = 0; i < ATH12K_HTT_TX_NUM_BE_MUMIMO_USER_STATS; i++) {
2207 len += scnprintf(buf + len, buf_len - len, "be_mu_mimo_sch_nusers_");
2208 len += scnprintf(buf + len, buf_len - len, "%u = %u\n", i,
2209 le32_to_cpu(htt_stats_buf->be_mu_mimo_sch_nusers[i]));
2210 }
2211
2212 len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n");
2213 for (i = 0; i < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS; i++) {
2214 len += scnprintf(buf + len, buf_len - len,
2215 "ax_ofdma_sch_nusers_%u = %u\n", i,
2216 le32_to_cpu(htt_stats_buf->ax_ofdma_sch_nusers[i]));
2217 len += scnprintf(buf + len, buf_len - len,
2218 "ax_ul_ofdma_basic_sch_nusers_%u = %u\n", i,
2219 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_nusers[i]));
2220 len += scnprintf(buf + len, buf_len - len,
2221 "ax_ul_ofdma_bsr_sch_nusers_%u = %u\n", i,
2222 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bsr_nusers[i]));
2223 len += scnprintf(buf + len, buf_len - len,
2224 "ax_ul_ofdma_bar_sch_nusers_%u = %u\n", i,
2225 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_bar_nusers[i]));
2226 len += scnprintf(buf + len, buf_len - len,
2227 "ax_ul_ofdma_brp_sch_nusers_%u = %u\n\n", i,
2228 le32_to_cpu(htt_stats_buf->ax_ul_ofdma_brp_nusers[i]));
2229 }
2230
2231 len += scnprintf(buf + len, buf_len - len, "11ax UL MUMIMO SCH STATS:\n");
2232 for (i = 0; i < ATH12K_HTT_TX_NUM_UL_MUMIMO_USER_STATS; i++) {
2233 len += scnprintf(buf + len, buf_len - len,
2234 "ax_ul_mumimo_basic_sch_nusers_%u = %u\n", i,
2235 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_nusers[i]));
2236 len += scnprintf(buf + len, buf_len - len,
2237 "ax_ul_mumimo_brp_sch_nusers_%u = %u\n\n", i,
2238 le32_to_cpu(htt_stats_buf->ax_ul_mumimo_brp_nusers[i]));
2239 }
2240
2241 stats_req->buf_len = len;
2242}
2243
2244static void
2245ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(const void *tag_buf, u16 tag_len,
2246 struct debug_htt_stats_req *stats_req)
2247{
2248 const struct ath12k_htt_tx_pdev_mumimo_grp_stats_tlv *htt_stats_buf = tag_buf;
2249 u8 *buf = stats_req->buf;
2250 u32 len = stats_req->buf_len;
2251 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2252 int j;
2253
2254 if (tag_len < sizeof(*htt_stats_buf))
2255 return;
2256
2257 len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_MUMIMO_GRP_STATS:\n");
2258 len += print_array_to_buf(buf, len,
2259 "dl_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2260 htt_stats_buf->dl_mumimo_grp_tputs,
2261 ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n");
2262 len += print_array_to_buf(buf, len, "dl_mumimo_grp eligible",
2263 htt_stats_buf->dl_mumimo_grp_eligible,
2264 ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2265 len += print_array_to_buf(buf, len, "dl_mumimo_grp_ineligible",
2266 htt_stats_buf->dl_mumimo_grp_ineligible,
2267 ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2268 len += scnprintf(buf + len, buf_len - len, "dl_mumimo_grp_invalid:\n");
2269 for (j = 0; j < ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ; j++) {
2270 len += scnprintf(buf + len, buf_len - len, "grp_id = %u", j);
2271 len += print_array_to_buf(buf, len, "",
2272 htt_stats_buf->dl_mumimo_grp_invalid,
2273 ATH12K_HTT_STATS_MAX_INVALID_REASON_CODE,
2274 "\n");
2275 }
2276
2277 len += print_array_to_buf(buf, len, "ul_mumimo_grp_best_grp_size",
2278 htt_stats_buf->ul_mumimo_grp_best_grp_size,
2279 ATH12K_HTT_STATS_NUM_MAX_MUMIMO_SZ, "\n");
2280 len += print_array_to_buf_index(buf, len, "ul_mumimo_grp_best_num_usrs = ", 1,
2281 htt_stats_buf->ul_mumimo_grp_best_usrs,
2282 ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS, "\n");
2283 len += print_array_to_buf(buf, len,
2284 "ul_mumimo_grp_tputs_observed (per bin = 300 mbps)",
2285 htt_stats_buf->ul_mumimo_grp_tputs,
2286 ATH12K_HTT_STATS_MUMIMO_TPUT_NUM_BINS, "\n\n");
2287
2288 stats_req->buf_len = len;
2289}
2290
2291static void
2292ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
2293 struct debug_htt_stats_req *stats_req)
2294{
2295 const struct ath12k_htt_tx_pdev_mpdu_stats_tlv *htt_stats_buf = tag_buf;
2296 u8 *buf = stats_req->buf;
2297 u32 len = stats_req->buf_len;
2298 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2299 u32 user_index;
2300 u32 tx_sched_mode;
2301
2302 if (tag_len < sizeof(*htt_stats_buf))
2303 return;
2304
2305 user_index = __le32_to_cpu(htt_stats_buf->user_index);
2306 tx_sched_mode = __le32_to_cpu(htt_stats_buf->tx_sched_mode);
2307
2308 if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AC) {
2309 if (!user_index)
2310 len += scnprintf(buf + len, buf_len - len,
2311 "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n");
2312
2313 if (user_index < ATH12K_HTT_TX_NUM_AC_MUMIMO_USER_STATS) {
2314 len += scnprintf(buf + len, buf_len - len,
2315 "ac_mu_mimo_mpdus_queued_usr_%u = %u\n",
2316 user_index,
2317 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2318 len += scnprintf(buf + len, buf_len - len,
2319 "ac_mu_mimo_mpdus_tried_usr_%u = %u\n",
2320 user_index,
2321 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2322 len += scnprintf(buf + len, buf_len - len,
2323 "ac_mu_mimo_mpdus_failed_usr_%u = %u\n",
2324 user_index,
2325 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2326 len += scnprintf(buf + len, buf_len - len,
2327 "ac_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2328 user_index,
2329 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2330 len += scnprintf(buf + len, buf_len - len,
2331 "ac_mu_mimo_err_no_ba_usr_%u = %u\n",
2332 user_index,
2333 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2334 len += scnprintf(buf + len, buf_len - len,
2335 "ac_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2336 user_index,
2337 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2338 len += scnprintf(buf + len, buf_len - len,
2339 "ac_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2340 user_index,
2341 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2342 }
2343 }
2344
2345 if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_MIMO_AX) {
2346 if (!user_index)
2347 len += scnprintf(buf + len, buf_len - len,
2348 "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n");
2349
2350 if (user_index < ATH12K_HTT_TX_NUM_AX_MUMIMO_USER_STATS) {
2351 len += scnprintf(buf + len, buf_len - len,
2352 "ax_mu_mimo_mpdus_queued_usr_%u = %u\n",
2353 user_index,
2354 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2355 len += scnprintf(buf + len, buf_len - len,
2356 "ax_mu_mimo_mpdus_tried_usr_%u = %u\n",
2357 user_index,
2358 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2359 len += scnprintf(buf + len, buf_len - len,
2360 "ax_mu_mimo_mpdus_failed_usr_%u = %u\n",
2361 user_index,
2362 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2363 len += scnprintf(buf + len, buf_len - len,
2364 "ax_mu_mimo_mpdus_requeued_usr_%u = %u\n",
2365 user_index,
2366 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2367 len += scnprintf(buf + len, buf_len - len,
2368 "ax_mu_mimo_err_no_ba_usr_%u = %u\n",
2369 user_index,
2370 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2371 len += scnprintf(buf + len, buf_len - len,
2372 "ax_mu_mimo_mpdu_underrun_usr_%u = %u\n",
2373 user_index,
2374 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2375 len += scnprintf(buf + len, buf_len - len,
2376 "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
2377 user_index,
2378 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2379 }
2380 }
2381
2382 if (tx_sched_mode == ATH12K_HTT_STATS_TX_SCHED_MODE_MU_OFDMA_AX) {
2383 if (!user_index)
2384 len += scnprintf(buf + len, buf_len - len,
2385 "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n");
2386
2387 if (user_index < ATH12K_HTT_TX_NUM_OFDMA_USER_STATS) {
2388 len += scnprintf(buf + len, buf_len - len,
2389 "ax_mu_ofdma_mpdus_queued_usr_%u = %u\n",
2390 user_index,
2391 le32_to_cpu(htt_stats_buf->mpdus_queued_usr));
2392 len += scnprintf(buf + len, buf_len - len,
2393 "ax_mu_ofdma_mpdus_tried_usr_%u = %u\n",
2394 user_index,
2395 le32_to_cpu(htt_stats_buf->mpdus_tried_usr));
2396 len += scnprintf(buf + len, buf_len - len,
2397 "ax_mu_ofdma_mpdus_failed_usr_%u = %u\n",
2398 user_index,
2399 le32_to_cpu(htt_stats_buf->mpdus_failed_usr));
2400 len += scnprintf(buf + len, buf_len - len,
2401 "ax_mu_ofdma_mpdus_requeued_usr_%u = %u\n",
2402 user_index,
2403 le32_to_cpu(htt_stats_buf->mpdus_requeued_usr));
2404 len += scnprintf(buf + len, buf_len - len,
2405 "ax_mu_ofdma_err_no_ba_usr_%u = %u\n",
2406 user_index,
2407 le32_to_cpu(htt_stats_buf->err_no_ba_usr));
2408 len += scnprintf(buf + len, buf_len - len,
2409 "ax_mu_ofdma_mpdu_underrun_usr_%u = %u\n",
2410 user_index,
2411 le32_to_cpu(htt_stats_buf->mpdu_underrun_usr));
2412 len += scnprintf(buf + len, buf_len - len,
2413 "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n\n",
2414 user_index,
2415 le32_to_cpu(htt_stats_buf->ampdu_underrun_usr));
2416 }
2417 }
2418
2419 stats_req->buf_len = len;
2420}
2421
2422static void
2423ath12k_htt_print_pdev_cca_stats_hist_tlv(const void *tag_buf, u16 tag_len,
2424 struct debug_htt_stats_req *stats_req)
2425{
2426 const struct ath12k_htt_pdev_cca_stats_hist_v1_tlv *htt_stats_buf = tag_buf;
2427 u8 *buf = stats_req->buf;
2428 u32 len = stats_req->buf_len;
2429 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2430
2431 if (tag_len < sizeof(*htt_stats_buf))
2432 return;
2433
2434 len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_CCA_STATS_HIST_TLV :\n");
2435 len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
2436 le32_to_cpu(htt_stats_buf->chan_num));
2437 len += scnprintf(buf + len, buf_len - len, "num_records = %u\n",
2438 le32_to_cpu(htt_stats_buf->num_records));
2439 len += scnprintf(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x\n",
2440 le32_to_cpu(htt_stats_buf->valid_cca_counters_bitmap));
2441 len += scnprintf(buf + len, buf_len - len, "collection_interval = %u\n\n",
2442 le32_to_cpu(htt_stats_buf->collection_interval));
2443
2444 stats_req->buf_len = len;
2445}
2446
2447static void
2448ath12k_htt_print_pdev_stats_cca_counters_tlv(const void *tag_buf, u16 tag_len,
2449 struct debug_htt_stats_req *stats_req)
2450{
2451 const struct ath12k_htt_pdev_stats_cca_counters_tlv *htt_stats_buf = tag_buf;
2452 u8 *buf = stats_req->buf;
2453 u32 len = stats_req->buf_len;
2454 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2455
2456 if (tag_len < sizeof(*htt_stats_buf))
2457 return;
2458
2459 len += scnprintf(buf + len, buf_len - len,
2460 "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)\n");
2461 len += scnprintf(buf + len, buf_len - len, "tx_frame_usec = %u\n",
2462 le32_to_cpu(htt_stats_buf->tx_frame_usec));
2463 len += scnprintf(buf + len, buf_len - len, "rx_frame_usec = %u\n",
2464 le32_to_cpu(htt_stats_buf->rx_frame_usec));
2465 len += scnprintf(buf + len, buf_len - len, "rx_clear_usec = %u\n",
2466 le32_to_cpu(htt_stats_buf->rx_clear_usec));
2467 len += scnprintf(buf + len, buf_len - len, "my_rx_frame_usec = %u\n",
2468 le32_to_cpu(htt_stats_buf->my_rx_frame_usec));
2469 len += scnprintf(buf + len, buf_len - len, "usec_cnt = %u\n",
2470 le32_to_cpu(htt_stats_buf->usec_cnt));
2471 len += scnprintf(buf + len, buf_len - len, "med_rx_idle_usec = %u\n",
2472 le32_to_cpu(htt_stats_buf->med_rx_idle_usec));
2473 len += scnprintf(buf + len, buf_len - len, "med_tx_idle_global_usec = %u\n",
2474 le32_to_cpu(htt_stats_buf->med_tx_idle_global_usec));
2475 len += scnprintf(buf + len, buf_len - len, "cca_obss_usec = %u\n\n",
2476 le32_to_cpu(htt_stats_buf->cca_obss_usec));
2477
2478 stats_req->buf_len = len;
2479}
2480
2481static void
2482ath12k_htt_print_pdev_obss_pd_stats_tlv(const void *tag_buf, u16 tag_len,
2483 struct debug_htt_stats_req *stats_req)
2484{
2485 const struct ath12k_htt_pdev_obss_pd_stats_tlv *htt_stats_buf = tag_buf;
2486 u8 *buf = stats_req->buf;
2487 u32 len = stats_req->buf_len;
2488 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2489 u8 i;
2490 static const char *access_cat_names[ATH12K_HTT_NUM_AC_WMM] = {"best effort",
2491 "background",
2492 "video", "voice"};
2493
2494 if (tag_len < sizeof(*htt_stats_buf))
2495 return;
2496
2497 len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_STATS_TLV:\n");
2498 len += scnprintf(buf + len, buf_len - len, "num_spatial_reuse_tx = %u\n",
2499 le32_to_cpu(htt_stats_buf->num_sr_tx_transmissions));
2500 len += scnprintf(buf + len, buf_len - len,
2501 "num_spatial_reuse_opportunities = %u\n",
2502 le32_to_cpu(htt_stats_buf->num_spatial_reuse_opportunities));
2503 len += scnprintf(buf + len, buf_len - len, "num_non_srg_opportunities = %u\n",
2504 le32_to_cpu(htt_stats_buf->num_non_srg_opportunities));
2505 len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_tried = %u\n",
2506 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_tried));
2507 len += scnprintf(buf + len, buf_len - len, "num_non_srg_ppdu_success = %u\n",
2508 le32_to_cpu(htt_stats_buf->num_non_srg_ppdu_success));
2509 len += scnprintf(buf + len, buf_len - len, "num_srg_opportunities = %u\n",
2510 le32_to_cpu(htt_stats_buf->num_srg_opportunities));
2511 len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2512 le32_to_cpu(htt_stats_buf->num_srg_ppdu_tried));
2513 len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_success = %u\n",
2514 le32_to_cpu(htt_stats_buf->num_srg_ppdu_success));
2515 len += scnprintf(buf + len, buf_len - len, "num_psr_opportunities = %u\n",
2516 le32_to_cpu(htt_stats_buf->num_psr_opportunities));
2517 len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_tried = %u\n",
2518 le32_to_cpu(htt_stats_buf->num_psr_ppdu_tried));
2519 len += scnprintf(buf + len, buf_len - len, "num_psr_ppdu_success = %u\n",
2520 le32_to_cpu(htt_stats_buf->num_psr_ppdu_success));
2521 len += scnprintf(buf + len, buf_len - len, "min_duration_check_flush_cnt = %u\n",
2522 le32_to_cpu(htt_stats_buf->num_obss_min_dur_check_flush_cnt));
2523 len += scnprintf(buf + len, buf_len - len, "sr_ppdu_abort_flush_cnt = %u\n\n",
2524 le32_to_cpu(htt_stats_buf->num_sr_ppdu_abort_flush_cnt));
2525
2526 len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_OBSS_PD_PER_AC_STATS:\n");
2527 for (i = 0; i < ATH12K_HTT_NUM_AC_WMM; i++) {
2528 len += scnprintf(buf + len, buf_len - len, "Access Category %u (%s)\n",
2529 i, access_cat_names[i]);
2530 len += scnprintf(buf + len, buf_len - len,
2531 "num_non_srg_ppdu_tried = %u\n",
2532 le32_to_cpu(htt_stats_buf->num_non_srg_tried_per_ac[i]));
2533 len += scnprintf(buf + len, buf_len - len,
2534 "num_non_srg_ppdu_success = %u\n",
2535 le32_to_cpu(htt_stats_buf->num_non_srg_success_ac[i]));
2536 len += scnprintf(buf + len, buf_len - len, "num_srg_ppdu_tried = %u\n",
2537 le32_to_cpu(htt_stats_buf->num_srg_tried_per_ac[i]));
2538 len += scnprintf(buf + len, buf_len - len,
2539 "num_srg_ppdu_success = %u\n\n",
2540 le32_to_cpu(htt_stats_buf->num_srg_success_per_ac[i]));
2541 }
2542
2543 stats_req->buf_len = len;
2544}
2545
2546static void
2547ath12k_htt_print_dmac_reset_stats_tlv(const void *tag_buf, u16 tag_len,
2548 struct debug_htt_stats_req *stats_req)
2549{
2550 const struct ath12k_htt_dmac_reset_stats_tlv *htt_stats_buf = tag_buf;
2551 u8 *buf = stats_req->buf;
2552 u32 len = stats_req->buf_len;
2553 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2554 u64 time;
2555
2556 if (tag_len < sizeof(*htt_stats_buf))
2557 return;
2558
2559 len += scnprintf(buf + len, buf_len - len, "HTT_DMAC_RESET_STATS_TLV:\n");
2560 len += scnprintf(buf + len, buf_len - len, "reset_count = %u\n",
2561 le32_to_cpu(htt_stats_buf->reset_count));
2562 time = ath12k_le32hilo_to_u64(htt_stats_buf->reset_time_hi_ms,
2563 htt_stats_buf->reset_time_lo_ms);
2564 len += scnprintf(buf + len, buf_len - len, "reset_time_ms = %llu\n", time);
2565
2566 time = ath12k_le32hilo_to_u64(htt_stats_buf->disengage_time_hi_ms,
2567 htt_stats_buf->disengage_time_lo_ms);
2568 len += scnprintf(buf + len, buf_len - len, "disengage_time_ms = %llu\n", time);
2569
2570 time = ath12k_le32hilo_to_u64(htt_stats_buf->engage_time_hi_ms,
2571 htt_stats_buf->engage_time_lo_ms);
2572 len += scnprintf(buf + len, buf_len - len, "engage_time_ms = %llu\n", time);
2573
2574 len += scnprintf(buf + len, buf_len - len, "disengage_count = %u\n",
2575 le32_to_cpu(htt_stats_buf->disengage_count));
2576 len += scnprintf(buf + len, buf_len - len, "engage_count = %u\n",
2577 le32_to_cpu(htt_stats_buf->engage_count));
2578 len += scnprintf(buf + len, buf_len - len, "drain_dest_ring_mask = 0x%x\n\n",
2579 le32_to_cpu(htt_stats_buf->drain_dest_ring_mask));
2580
2581 stats_req->buf_len = len;
2582}
2583
2584static void
2585ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(const void *tag_buf, u16 tag_len,
2586 struct debug_htt_stats_req *stats_req)
2587{
2588 const struct ath12k_htt_pdev_sched_algo_ofdma_stats_tlv *htt_stats_buf = tag_buf;
2589 u8 *buf = stats_req->buf;
2590 u32 len = stats_req->buf_len;
2591 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2592 u32 mac_id_word;
2593
2594 if (tag_len < sizeof(*htt_stats_buf))
2595 return;
2596
2597 mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
2598
2599 len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_SCHED_ALGO_TLV:\n");
2600 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2601 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2602 len += print_array_to_buf(buf, len, "rate_based_dlofdma_enabled_count",
2603 htt_stats_buf->rate_based_dlofdma_enabled_cnt,
2604 ATH12K_HTT_NUM_AC_WMM, "\n");
2605 len += print_array_to_buf(buf, len, "rate_based_dlofdma_disabled_count",
2606 htt_stats_buf->rate_based_dlofdma_disabled_cnt,
2607 ATH12K_HTT_NUM_AC_WMM, "\n");
2608 len += print_array_to_buf(buf, len, "rate_based_dlofdma_probing_count",
2609 htt_stats_buf->rate_based_dlofdma_disabled_cnt,
2610 ATH12K_HTT_NUM_AC_WMM, "\n");
2611 len += print_array_to_buf(buf, len, "rate_based_dlofdma_monitoring_count",
2612 htt_stats_buf->rate_based_dlofdma_monitor_cnt,
2613 ATH12K_HTT_NUM_AC_WMM, "\n");
2614 len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_enabled_count",
2615 htt_stats_buf->chan_acc_lat_based_dlofdma_enabled_cnt,
2616 ATH12K_HTT_NUM_AC_WMM, "\n");
2617 len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_disabled_count",
2618 htt_stats_buf->chan_acc_lat_based_dlofdma_disabled_cnt,
2619 ATH12K_HTT_NUM_AC_WMM, "\n");
2620 len += print_array_to_buf(buf, len, "chan_acc_lat_based_dlofdma_monitoring_count",
2621 htt_stats_buf->chan_acc_lat_based_dlofdma_monitor_cnt,
2622 ATH12K_HTT_NUM_AC_WMM, "\n");
2623 len += print_array_to_buf(buf, len, "downgrade_to_dl_su_ru_alloc_fail",
2624 htt_stats_buf->downgrade_to_dl_su_ru_alloc_fail,
2625 ATH12K_HTT_NUM_AC_WMM, "\n");
2626 len += print_array_to_buf(buf, len, "candidate_list_single_user_disable_ofdma",
2627 htt_stats_buf->candidate_list_single_user_disable_ofdma,
2628 ATH12K_HTT_NUM_AC_WMM, "\n");
2629 len += print_array_to_buf(buf, len, "dl_cand_list_dropped_high_ul_qos_weight",
2630 htt_stats_buf->dl_cand_list_dropped_high_ul_qos_weight,
2631 ATH12K_HTT_NUM_AC_WMM, "\n");
2632 len += print_array_to_buf(buf, len, "ax_dlofdma_disabled_due_to_pipelining",
2633 htt_stats_buf->ax_dlofdma_disabled_due_to_pipelining,
2634 ATH12K_HTT_NUM_AC_WMM, "\n");
2635 len += print_array_to_buf(buf, len, "dlofdma_disabled_su_only_eligible",
2636 htt_stats_buf->dlofdma_disabled_su_only_eligible,
2637 ATH12K_HTT_NUM_AC_WMM, "\n");
2638 len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_tried",
2639 htt_stats_buf->dlofdma_disabled_consec_no_mpdus_tried,
2640 ATH12K_HTT_NUM_AC_WMM, "\n");
2641 len += print_array_to_buf(buf, len, "dlofdma_disabled_consec_no_mpdus_success",
2642 htt_stats_buf->dlofdma_disabled_consec_no_mpdus_success,
2643 ATH12K_HTT_NUM_AC_WMM, "\n\n");
2644
2645 stats_req->buf_len = len;
2646}
2647
2648static void
2649ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(const void *tag_buf, u16 tag_len,
2650 struct debug_htt_stats_req *stats_req)
2651{
2652 const struct ath12k_htt_tx_pdev_rate_stats_be_ofdma_tlv *htt_stats_buf = tag_buf;
2653 u8 *buf = stats_req->buf;
2654 u32 len = stats_req->buf_len;
2655 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
2656 u32 mac_id_word;
2657 u8 i;
2658
2659 if (tag_len < sizeof(*htt_stats_buf))
2660 return;
2661
2662 mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
2663
2664 len += scnprintf(buf + len, buf_len - len,
2665 "HTT_TX_PDEV_RATE_STATS_BE_OFDMA_TLV:\n");
2666 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
2667 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
2668 len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ldpc = %u\n",
2669 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ldpc));
2670 len += print_array_to_buf(buf, len, "be_ofdma_tx_mcs",
2671 htt_stats_buf->be_ofdma_tx_mcs,
2672 ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
2673 len += print_array_to_buf(buf, len, "be_ofdma_eht_sig_mcs",
2674 htt_stats_buf->be_ofdma_eht_sig_mcs,
2675 ATH12K_HTT_TX_PDEV_NUM_EHT_SIG_MCS_CNTRS, "\n");
2676 len += scnprintf(buf + len, buf_len - len, "be_ofdma_tx_ru_size = ");
2677 for (i = 0; i < ATH12K_HTT_TX_RX_PDEV_NUM_BE_RU_SIZE_CNTRS; i++)
2678 len += scnprintf(buf + len, buf_len - len, " %s:%u ",
2679 ath12k_htt_be_tx_rx_ru_size_to_str(i),
2680 le32_to_cpu(htt_stats_buf->be_ofdma_tx_ru_size[i]));
2681 len += scnprintf(buf + len, buf_len - len, "\n");
2682 len += print_array_to_buf_index(buf, len, "be_ofdma_tx_nss = ", 1,
2683 htt_stats_buf->be_ofdma_tx_nss,
2684 ATH12K_HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS,
2685 "\n");
2686 len += print_array_to_buf(buf, len, "be_ofdma_tx_bw",
2687 htt_stats_buf->be_ofdma_tx_bw,
2688 ATH12K_HTT_TX_PDEV_NUM_BE_BW_CNTRS, "\n");
2689 for (i = 0; i < ATH12K_HTT_TX_PDEV_NUM_GI_CNTRS; i++) {
2690 len += scnprintf(buf + len, buf_len - len,
2691 "be_ofdma_tx_gi[%u]", i);
2692 len += print_array_to_buf(buf, len, "", htt_stats_buf->gi[i],
2693 ATH12K_HTT_TX_PDEV_NUM_BE_MCS_CNTRS, "\n");
2694 }
2695 len += scnprintf(buf + len, buf_len - len, "\n");
2696
2697 stats_req->buf_len = len;
2698}
2699
2700static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
2701 u16 tag, u16 len, const void *tag_buf,
2702 void *user_data)
2703{
2704 struct debug_htt_stats_req *stats_req = user_data;
2705
2706 switch (tag) {
2707 case HTT_STATS_TX_PDEV_CMN_TAG:
2708 htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req);
2709 break;
2710 case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
2711 htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req);
2712 break;
2713 case HTT_STATS_TX_PDEV_SIFS_TAG:
2714 htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req);
2715 break;
2716 case HTT_STATS_TX_PDEV_FLUSH_TAG:
2717 htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req);
2718 break;
2719 case HTT_STATS_TX_PDEV_SIFS_HIST_TAG:
2720 htt_print_tx_pdev_stats_sifs_hist_tlv(tag_buf, len, stats_req);
2721 break;
2722 case HTT_STATS_PDEV_CTRL_PATH_TX_STATS_TAG:
2723 htt_print_pdev_ctrl_path_tx_stats_tlv(tag_buf, len, stats_req);
2724 break;
2725 case HTT_STATS_MU_PPDU_DIST_TAG:
2726 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(tag_buf, len, stats_req);
2727 break;
2728 case HTT_STATS_TX_SCHED_CMN_TAG:
2729 ath12k_htt_print_stats_tx_sched_cmn_tlv(tag_buf, len, stats_req);
2730 break;
2731 case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG:
2732 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, len, stats_req);
2733 break;
2734 case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG:
2735 ath12k_htt_print_sched_txq_cmd_posted_tlv(tag_buf, len, stats_req);
2736 break;
2737 case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG:
2738 ath12k_htt_print_sched_txq_cmd_reaped_tlv(tag_buf, len, stats_req);
2739 break;
2740 case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG:
2741 ath12k_htt_print_sched_txq_sched_order_su_tlv(tag_buf, len, stats_req);
2742 break;
2743 case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG:
2744 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(tag_buf, len,
2745 stats_req);
2746 break;
2747 case HTT_STATS_SCHED_TXQ_SUPERCYCLE_TRIGGER_TAG:
2748 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(tag_buf, len,
2749 stats_req);
2750 break;
2751 case HTT_STATS_HW_PDEV_ERRS_TAG:
2752 ath12k_htt_print_hw_stats_pdev_errs_tlv(tag_buf, len, stats_req);
2753 break;
2754 case HTT_STATS_HW_INTR_MISC_TAG:
2755 ath12k_htt_print_hw_stats_intr_misc_tlv(tag_buf, len, stats_req);
2756 break;
2757 case HTT_STATS_WHAL_TX_TAG:
2758 ath12k_htt_print_hw_stats_whal_tx_tlv(tag_buf, len, stats_req);
2759 break;
2760 case HTT_STATS_HW_WAR_TAG:
2761 ath12k_htt_print_hw_war_tlv(tag_buf, len, stats_req);
2762 break;
2763 case HTT_STATS_TX_TQM_CMN_TAG:
2764 ath12k_htt_print_tx_tqm_cmn_stats_tlv(tag_buf, len, stats_req);
2765 break;
2766 case HTT_STATS_TX_TQM_ERROR_STATS_TAG:
2767 ath12k_htt_print_tx_tqm_error_stats_tlv(tag_buf, len, stats_req);
2768 break;
2769 case HTT_STATS_TX_TQM_GEN_MPDU_TAG:
2770 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(tag_buf, len, stats_req);
2771 break;
2772 case HTT_STATS_TX_TQM_LIST_MPDU_TAG:
2773 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(tag_buf, len, stats_req);
2774 break;
2775 case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG:
2776 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(tag_buf, len, stats_req);
2777 break;
2778 case HTT_STATS_TX_TQM_PDEV_TAG:
2779 ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req);
2780 break;
2781 case HTT_STATS_TX_DE_CMN_TAG:
2782 ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req);
2783 break;
2784 case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
2785 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req);
2786 break;
2787 case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
2788 ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req);
2789 break;
2790 case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
2791 ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req);
2792 break;
2793 case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
2794 ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req);
2795 break;
2796 case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
2797 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req);
2798 break;
2799 case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
2800 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req);
2801 break;
2802 case HTT_STATS_TX_DE_COMPL_STATS_TAG:
2803 ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
2804 break;
2805 case HTT_STATS_TX_SELFGEN_CMN_STATS_TAG:
2806 ath12k_htt_print_tx_selfgen_cmn_stats_tlv(tag_buf, len, stats_req);
2807 break;
2808 case HTT_STATS_TX_SELFGEN_AC_STATS_TAG:
2809 ath12k_htt_print_tx_selfgen_ac_stats_tlv(tag_buf, len, stats_req);
2810 break;
2811 case HTT_STATS_TX_SELFGEN_AX_STATS_TAG:
2812 ath12k_htt_print_tx_selfgen_ax_stats_tlv(tag_buf, len, stats_req);
2813 break;
2814 case HTT_STATS_TX_SELFGEN_BE_STATS_TAG:
2815 ath12k_htt_print_tx_selfgen_be_stats_tlv(tag_buf, len, stats_req);
2816 break;
2817 case HTT_STATS_TX_SELFGEN_AC_ERR_STATS_TAG:
2818 ath12k_htt_print_tx_selfgen_ac_err_stats_tlv(tag_buf, len, stats_req);
2819 break;
2820 case HTT_STATS_TX_SELFGEN_AX_ERR_STATS_TAG:
2821 ath12k_htt_print_tx_selfgen_ax_err_stats_tlv(tag_buf, len, stats_req);
2822 break;
2823 case HTT_STATS_TX_SELFGEN_BE_ERR_STATS_TAG:
2824 ath12k_htt_print_tx_selfgen_be_err_stats_tlv(tag_buf, len, stats_req);
2825 break;
2826 case HTT_STATS_TX_SELFGEN_AC_SCHED_STATUS_STATS_TAG:
2827 ath12k_htt_print_tx_selfgen_ac_sched_status_stats_tlv(tag_buf, len,
2828 stats_req);
2829 break;
2830 case HTT_STATS_TX_SELFGEN_AX_SCHED_STATUS_STATS_TAG:
2831 ath12k_htt_print_tx_selfgen_ax_sched_status_stats_tlv(tag_buf, len,
2832 stats_req);
2833 break;
2834 case HTT_STATS_TX_SELFGEN_BE_SCHED_STATUS_STATS_TAG:
2835 ath12k_htt_print_tx_selfgen_be_sched_status_stats_tlv(tag_buf, len,
2836 stats_req);
2837 break;
2838 case HTT_STATS_STRING_TAG:
2839 ath12k_htt_print_stats_string_tlv(tag_buf, len, stats_req);
2840 break;
2841 case HTT_STATS_SRING_STATS_TAG:
2842 ath12k_htt_print_sring_stats_tlv(tag_buf, len, stats_req);
2843 break;
2844 case HTT_STATS_SFM_CMN_TAG:
2845 ath12k_htt_print_sfm_cmn_tlv(tag_buf, len, stats_req);
2846 break;
2847 case HTT_STATS_SFM_CLIENT_TAG:
2848 ath12k_htt_print_sfm_client_tlv(tag_buf, len, stats_req);
2849 break;
2850 case HTT_STATS_SFM_CLIENT_USER_TAG:
2851 ath12k_htt_print_sfm_client_user_tlv(tag_buf, len, stats_req);
2852 break;
2853 case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG:
2854 ath12k_htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, len, stats_req);
2855 break;
2856 case HTT_STATS_TX_PDEV_MUMIMO_GRP_STATS_TAG:
2857 ath12k_htt_print_tx_pdev_mumimo_grp_stats_tlv(tag_buf, len, stats_req);
2858 break;
2859 case HTT_STATS_TX_PDEV_MPDU_STATS_TAG:
2860 ath12k_htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(tag_buf, len, stats_req);
2861 break;
2862 case HTT_STATS_PDEV_CCA_1SEC_HIST_TAG:
2863 case HTT_STATS_PDEV_CCA_100MSEC_HIST_TAG:
2864 case HTT_STATS_PDEV_CCA_STAT_CUMULATIVE_TAG:
2865 ath12k_htt_print_pdev_cca_stats_hist_tlv(tag_buf, len, stats_req);
2866 break;
2867 case HTT_STATS_PDEV_CCA_COUNTERS_TAG:
2868 ath12k_htt_print_pdev_stats_cca_counters_tlv(tag_buf, len, stats_req);
2869 break;
2870 case HTT_STATS_PDEV_OBSS_PD_TAG:
2871 ath12k_htt_print_pdev_obss_pd_stats_tlv(tag_buf, len, stats_req);
2872 break;
2873 case HTT_STATS_DMAC_RESET_STATS_TAG:
2874 ath12k_htt_print_dmac_reset_stats_tlv(tag_buf, len, stats_req);
2875 break;
2876 case HTT_STATS_PDEV_SCHED_ALGO_OFDMA_STATS_TAG:
2877 ath12k_htt_print_pdev_sched_algo_ofdma_stats_tlv(tag_buf, len, stats_req);
2878 break;
2879 case HTT_STATS_TX_PDEV_RATE_STATS_BE_OFDMA_TAG:
2880 ath12k_htt_print_tx_pdev_rate_stats_be_ofdma_tlv(tag_buf, len, stats_req);
2881 break;
2882 default:
2883 break;
2884 }
2885
2886 return 0;
2887}
2888
2889void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
2890 struct sk_buff *skb)
2891{
2892 struct ath12k_htt_extd_stats_msg *msg;
2893 struct debug_htt_stats_req *stats_req;
2894 struct ath12k *ar;
2895 u32 len, pdev_id, stats_info;
2896 u64 cookie;
2897 int ret;
2898 bool send_completion = false;
2899
2900 msg = (struct ath12k_htt_extd_stats_msg *)skb->data;
2901 cookie = le64_to_cpu(msg->cookie);
2902
2903 if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) !=
2904 ATH12K_HTT_STATS_MAGIC_VALUE) {
2905 ath12k_warn(ab, "received invalid htt ext stats event\n");
2906 return;
2907 }
2908
2909 pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB);
2910 rcu_read_lock();
2911 ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
2912 if (!ar) {
2913 ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
2914 goto exit;
2915 }
2916
2917 stats_req = ar->debug.htt_stats.stats_req;
2918 if (!stats_req)
2919 goto exit;
2920
2921 spin_lock_bh(&ar->data_lock);
2922
2923 stats_info = le32_to_cpu(msg->info1);
2924 stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE);
2925 if (stats_req->done)
2926 send_completion = true;
2927
2928 spin_unlock_bh(&ar->data_lock);
2929
2930 len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH);
2931 if (len > skb->len) {
2932 ath12k_warn(ab, "invalid length %d for HTT stats", len);
2933 goto exit;
2934 }
2935
2936 ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
2937 ath12k_dbg_htt_ext_stats_parse,
2938 stats_req);
2939 if (ret)
2940 ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
2941
2942 if (send_completion)
2943 complete(&stats_req->htt_stats_rcvd);
2944exit:
2945 rcu_read_unlock();
2946}
2947
2948static ssize_t ath12k_read_htt_stats_type(struct file *file,
2949 char __user *user_buf,
2950 size_t count, loff_t *ppos)
2951{
2952 struct ath12k *ar = file->private_data;
2953 enum ath12k_dbg_htt_ext_stats_type type;
2954 char buf[32];
2955 size_t len;
2956
2957 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
2958 type = ar->debug.htt_stats.type;
2959 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
2960
2961 len = scnprintf(buf, sizeof(buf), "%u\n", type);
2962
2963 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2964}
2965
2966static ssize_t ath12k_write_htt_stats_type(struct file *file,
2967 const char __user *user_buf,
2968 size_t count, loff_t *ppos)
2969{
2970 struct ath12k *ar = file->private_data;
2971 enum ath12k_dbg_htt_ext_stats_type type;
2972 unsigned int cfg_param[4] = {0};
2973 const int size = 32;
2974 int num_args;
2975
2976 char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
2977 if (!buf)
2978 return -ENOMEM;
2979
2980 if (copy_from_user(buf, user_buf, count))
2981 return -EFAULT;
2982
2983 num_args = sscanf(buf, "%u %u %u %u %u\n", &type, &cfg_param[0],
2984 &cfg_param[1], &cfg_param[2], &cfg_param[3]);
2985 if (!num_args || num_args > 5)
2986 return -EINVAL;
2987
2988 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET ||
2989 type >= ATH12K_DBG_HTT_NUM_EXT_STATS)
2990 return -EINVAL;
2991
2992 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
2993
2994 ar->debug.htt_stats.type = type;
2995 ar->debug.htt_stats.cfg_param[0] = cfg_param[0];
2996 ar->debug.htt_stats.cfg_param[1] = cfg_param[1];
2997 ar->debug.htt_stats.cfg_param[2] = cfg_param[2];
2998 ar->debug.htt_stats.cfg_param[3] = cfg_param[3];
2999
3000 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3001
3002 return count;
3003}
3004
3005static const struct file_operations fops_htt_stats_type = {
3006 .read = ath12k_read_htt_stats_type,
3007 .write = ath12k_write_htt_stats_type,
3008 .open = simple_open,
3009 .owner = THIS_MODULE,
3010 .llseek = default_llseek,
3011};
3012
3013static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
3014{
3015 struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
3016 enum ath12k_dbg_htt_ext_stats_type type = stats_req->type;
3017 u64 cookie;
3018 int ret, pdev_id;
3019 struct htt_ext_stats_cfg_params cfg_params = { 0 };
3020
3021 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
3022
3023 init_completion(&stats_req->htt_stats_rcvd);
3024
3025 pdev_id = ath12k_mac_get_target_pdev_id(ar);
3026 stats_req->done = false;
3027 stats_req->pdev_id = pdev_id;
3028
3029 cookie = u64_encode_bits(ATH12K_HTT_STATS_MAGIC_VALUE,
3030 ATH12K_HTT_STATS_COOKIE_MSB);
3031 cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB);
3032
3033 if (stats_req->override_cfg_param) {
3034 cfg_params.cfg0 = stats_req->cfg_param[0];
3035 cfg_params.cfg1 = stats_req->cfg_param[1];
3036 cfg_params.cfg2 = stats_req->cfg_param[2];
3037 cfg_params.cfg3 = stats_req->cfg_param[3];
3038 }
3039
3040 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
3041 if (ret) {
3042 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
3043 return ret;
3044 }
3045 if (!wait_for_completion_timeout(&stats_req->htt_stats_rcvd, 3 * HZ)) {
3046 spin_lock_bh(&ar->data_lock);
3047 if (!stats_req->done) {
3048 stats_req->done = true;
3049 spin_unlock_bh(&ar->data_lock);
3050 ath12k_warn(ar->ab, "stats request timed out\n");
3051 return -ETIMEDOUT;
3052 }
3053 spin_unlock_bh(&ar->data_lock);
3054 }
3055
3056 return 0;
3057}
3058
3059static int ath12k_open_htt_stats(struct inode *inode,
3060 struct file *file)
3061{
3062 struct ath12k *ar = inode->i_private;
3063 struct debug_htt_stats_req *stats_req;
3064 enum ath12k_dbg_htt_ext_stats_type type = ar->debug.htt_stats.type;
3065 struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
3066 int ret;
3067
3068 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET)
3069 return -EPERM;
3070
3071 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3072
3073 if (ah->state != ATH12K_HW_STATE_ON) {
3074 ret = -ENETDOWN;
3075 goto err_unlock;
3076 }
3077
3078 if (ar->debug.htt_stats.stats_req) {
3079 ret = -EAGAIN;
3080 goto err_unlock;
3081 }
3082
3083 stats_req = kzalloc(sizeof(*stats_req) + ATH12K_HTT_STATS_BUF_SIZE, GFP_KERNEL);
3084 if (!stats_req) {
3085 ret = -ENOMEM;
3086 goto err_unlock;
3087 }
3088
3089 ar->debug.htt_stats.stats_req = stats_req;
3090 stats_req->type = type;
3091 stats_req->cfg_param[0] = ar->debug.htt_stats.cfg_param[0];
3092 stats_req->cfg_param[1] = ar->debug.htt_stats.cfg_param[1];
3093 stats_req->cfg_param[2] = ar->debug.htt_stats.cfg_param[2];
3094 stats_req->cfg_param[3] = ar->debug.htt_stats.cfg_param[3];
3095 stats_req->override_cfg_param = !!stats_req->cfg_param[0] ||
3096 !!stats_req->cfg_param[1] ||
3097 !!stats_req->cfg_param[2] ||
3098 !!stats_req->cfg_param[3];
3099
3100 ret = ath12k_debugfs_htt_stats_req(ar);
3101 if (ret < 0)
3102 goto out;
3103
3104 file->private_data = stats_req;
3105
3106 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3107
3108 return 0;
3109out:
3110 kfree(stats_req);
3111 ar->debug.htt_stats.stats_req = NULL;
3112err_unlock:
3113 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3114
3115 return ret;
3116}
3117
3118static int ath12k_release_htt_stats(struct inode *inode,
3119 struct file *file)
3120{
3121 struct ath12k *ar = inode->i_private;
3122
3123 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3124 kfree(file->private_data);
3125 ar->debug.htt_stats.stats_req = NULL;
3126 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3127
3128 return 0;
3129}
3130
3131static ssize_t ath12k_read_htt_stats(struct file *file,
3132 char __user *user_buf,
3133 size_t count, loff_t *ppos)
3134{
3135 struct debug_htt_stats_req *stats_req = file->private_data;
3136 char *buf;
3137 u32 length;
3138
3139 buf = stats_req->buf;
3140 length = min_t(u32, stats_req->buf_len, ATH12K_HTT_STATS_BUF_SIZE);
3141 return simple_read_from_buffer(user_buf, count, ppos, buf, length);
3142}
3143
3144static const struct file_operations fops_dump_htt_stats = {
3145 .open = ath12k_open_htt_stats,
3146 .release = ath12k_release_htt_stats,
3147 .read = ath12k_read_htt_stats,
3148 .owner = THIS_MODULE,
3149 .llseek = default_llseek,
3150};
3151
3152static ssize_t ath12k_write_htt_stats_reset(struct file *file,
3153 const char __user *user_buf,
3154 size_t count, loff_t *ppos)
3155{
3156 struct ath12k *ar = file->private_data;
3157 enum ath12k_dbg_htt_ext_stats_type type;
3158 struct htt_ext_stats_cfg_params cfg_params = { 0 };
3159 u8 param_pos;
3160 int ret;
3161
3162 ret = kstrtou32_from_user(user_buf, count, 0, &type);
3163 if (ret)
3164 return ret;
3165
3166 if (type >= ATH12K_DBG_HTT_NUM_EXT_STATS ||
3167 type == ATH12K_DBG_HTT_EXT_STATS_RESET)
3168 return -E2BIG;
3169
3170 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
3171 cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET;
3172 param_pos = (type >> 5) + 1;
3173
3174 switch (param_pos) {
3175 case ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES:
3176 cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type);
3177 break;
3178 case ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES:
3179 cfg_params.cfg2 = ATH12K_HTT_STATS_RESET_BITMAP32_BIT(cfg_params.cfg0 +
3180 type);
3181 break;
3182 case ATH12K_HTT_STATS_RESET_PARAM_CFG_128_BYTES:
3183 cfg_params.cfg3 = ATH12K_HTT_STATS_RESET_BITMAP64_BIT(cfg_params.cfg0 +
3184 type);
3185 break;
3186 default:
3187 break;
3188 }
3189
3190 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar,
3191 ATH12K_DBG_HTT_EXT_STATS_RESET,
3192 &cfg_params,
3193 0ULL);
3194 if (ret) {
3195 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
3196 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3197 return ret;
3198 }
3199
3200 ar->debug.htt_stats.reset = type;
3201 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
3202
3203 return count;
3204}
3205
3206static const struct file_operations fops_htt_stats_reset = {
3207 .write = ath12k_write_htt_stats_reset,
3208 .open = simple_open,
3209 .owner = THIS_MODULE,
3210 .llseek = default_llseek,
3211};
3212
3213void ath12k_debugfs_htt_stats_register(struct ath12k *ar)
3214{
3215 debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev,
3216 ar, &fops_htt_stats_type);
3217 debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev,
3218 ar, &fops_dump_htt_stats);
3219 debugfs_create_file("htt_stats_reset", 0200, ar->debug.debugfs_pdev,
3220 ar, &fops_htt_stats_reset);
3221}