1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5 */
6
7 #include <linux/vmalloc.h>
8 #include "core.h"
9 #include "debug.h"
10 #include "debugfs_htt_stats.h"
11 #include "dp_tx.h"
12 #include "dp_rx.h"
13
14 static u32
print_array_to_buf(u8 * buf,u32 offset,const char * header,const __le32 * array,u32 array_len,const char * footer)15 print_array_to_buf(u8 *buf, u32 offset, const char *header,
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,", i, le32_to_cpu(array[i]));
30 }
31 /* To overwrite the last trailing comma */
32 index--;
33 *(buf + offset + index) = '\0';
34
35 if (footer) {
36 index += scnprintf(buf + offset + index,
37 (ATH12K_HTT_STATS_BUF_SIZE - offset) - index,
38 "%s", footer);
39 }
40 return index;
41 }
42
43 static void
htt_print_tx_pdev_stats_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)44 htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
45 struct debug_htt_stats_req *stats_req)
46 {
47 const struct ath12k_htt_tx_pdev_stats_cmn_tlv *htt_stats_buf = tag_buf;
48 u8 *buf = stats_req->buf;
49 u32 len = stats_req->buf_len;
50 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
51 u32 mac_id_word;
52
53 if (tag_len < sizeof(*htt_stats_buf))
54 return;
55
56 mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word);
57
58 len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n");
59 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
60 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
61 len += scnprintf(buf + len, buf_len - len, "comp_delivered = %u\n",
62 le32_to_cpu(htt_stats_buf->comp_delivered));
63 len += scnprintf(buf + len, buf_len - len, "self_triggers = %u\n",
64 le32_to_cpu(htt_stats_buf->self_triggers));
65 len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
66 le32_to_cpu(htt_stats_buf->hw_queued));
67 len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
68 le32_to_cpu(htt_stats_buf->hw_reaped));
69 len += scnprintf(buf + len, buf_len - len, "underrun = %u\n",
70 le32_to_cpu(htt_stats_buf->underrun));
71 len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n",
72 le32_to_cpu(htt_stats_buf->hw_paused));
73 len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n",
74 le32_to_cpu(htt_stats_buf->hw_flush));
75 len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n",
76 le32_to_cpu(htt_stats_buf->hw_filt));
77 len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
78 le32_to_cpu(htt_stats_buf->tx_abort));
79 len += scnprintf(buf + len, buf_len - len, "ppdu_ok = %u\n",
80 le32_to_cpu(htt_stats_buf->ppdu_ok));
81 len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n",
82 le32_to_cpu(htt_stats_buf->mpdu_requed));
83 len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n",
84 le32_to_cpu(htt_stats_buf->tx_xretry));
85 len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n",
86 le32_to_cpu(htt_stats_buf->data_rc));
87 len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n",
88 le32_to_cpu(htt_stats_buf->mpdu_dropped_xretry));
89 len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n",
90 le32_to_cpu(htt_stats_buf->illgl_rate_phy_err));
91 len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n",
92 le32_to_cpu(htt_stats_buf->cont_xretry));
93 len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n",
94 le32_to_cpu(htt_stats_buf->tx_timeout));
95 len += scnprintf(buf + len, buf_len - len, "tx_time_dur_data = %u\n",
96 le32_to_cpu(htt_stats_buf->tx_time_dur_data));
97 len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n",
98 le32_to_cpu(htt_stats_buf->pdev_resets));
99 len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n",
100 le32_to_cpu(htt_stats_buf->phy_underrun));
101 len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n",
102 le32_to_cpu(htt_stats_buf->txop_ovf));
103 len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n",
104 le32_to_cpu(htt_stats_buf->seq_posted));
105 len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n",
106 le32_to_cpu(htt_stats_buf->seq_failed_queueing));
107 len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n",
108 le32_to_cpu(htt_stats_buf->seq_completed));
109 len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n",
110 le32_to_cpu(htt_stats_buf->seq_restarted));
111 len += scnprintf(buf + len, buf_len - len, "seq_txop_repost_stop = %u\n",
112 le32_to_cpu(htt_stats_buf->seq_txop_repost_stop));
113 len += scnprintf(buf + len, buf_len - len, "next_seq_cancel = %u\n",
114 le32_to_cpu(htt_stats_buf->next_seq_cancel));
115 len += scnprintf(buf + len, buf_len - len, "dl_mu_mimo_seq_posted = %u\n",
116 le32_to_cpu(htt_stats_buf->mu_seq_posted));
117 len += scnprintf(buf + len, buf_len - len, "dl_mu_ofdma_seq_posted = %u\n",
118 le32_to_cpu(htt_stats_buf->mu_ofdma_seq_posted));
119 len += scnprintf(buf + len, buf_len - len, "ul_mu_mimo_seq_posted = %u\n",
120 le32_to_cpu(htt_stats_buf->ul_mumimo_seq_posted));
121 len += scnprintf(buf + len, buf_len - len, "ul_mu_ofdma_seq_posted = %u\n",
122 le32_to_cpu(htt_stats_buf->ul_ofdma_seq_posted));
123 len += scnprintf(buf + len, buf_len - len, "mu_mimo_peer_blacklisted = %u\n",
124 le32_to_cpu(htt_stats_buf->num_mu_peer_blacklisted));
125 len += scnprintf(buf + len, buf_len - len, "seq_qdepth_repost_stop = %u\n",
126 le32_to_cpu(htt_stats_buf->seq_qdepth_repost_stop));
127 len += scnprintf(buf + len, buf_len - len, "seq_min_msdu_repost_stop = %u\n",
128 le32_to_cpu(htt_stats_buf->seq_min_msdu_repost_stop));
129 len += scnprintf(buf + len, buf_len - len, "mu_seq_min_msdu_repost_stop = %u\n",
130 le32_to_cpu(htt_stats_buf->mu_seq_min_msdu_repost_stop));
131 len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n",
132 le32_to_cpu(htt_stats_buf->seq_switch_hw_paused));
133 len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n",
134 le32_to_cpu(htt_stats_buf->next_seq_posted_dsr));
135 len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n",
136 le32_to_cpu(htt_stats_buf->seq_posted_isr));
137 len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n",
138 le32_to_cpu(htt_stats_buf->seq_ctrl_cached));
139 len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n",
140 le32_to_cpu(htt_stats_buf->mpdu_count_tqm));
141 len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n",
142 le32_to_cpu(htt_stats_buf->msdu_count_tqm));
143 len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n",
144 le32_to_cpu(htt_stats_buf->mpdu_removed_tqm));
145 len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n",
146 le32_to_cpu(htt_stats_buf->msdu_removed_tqm));
147 len += scnprintf(buf + len, buf_len - len, "remove_mpdus_max_retries = %u\n",
148 le32_to_cpu(htt_stats_buf->remove_mpdus_max_retries));
149 len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n",
150 le32_to_cpu(htt_stats_buf->mpdus_sw_flush));
151 len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
152 le32_to_cpu(htt_stats_buf->mpdus_hw_filter));
153 len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n",
154 le32_to_cpu(htt_stats_buf->mpdus_truncated));
155 len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n",
156 le32_to_cpu(htt_stats_buf->mpdus_ack_failed));
157 len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n",
158 le32_to_cpu(htt_stats_buf->mpdus_expired));
159 len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n",
160 le32_to_cpu(htt_stats_buf->mpdus_seq_hw_retry));
161 len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
162 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
163 len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n",
164 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt_valid));
165 len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n",
166 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt));
167 len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n",
168 le32_to_cpu(htt_stats_buf->num_total_ppdus_tried_ota));
169 len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n",
170 le32_to_cpu(htt_stats_buf->num_data_ppdus_tried_ota));
171 len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n",
172 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_enqued));
173 len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n",
174 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_freed));
175 len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n",
176 le32_to_cpu(htt_stats_buf->local_data_enqued));
177 len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n",
178 le32_to_cpu(htt_stats_buf->local_data_freed));
179 len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n",
180 le32_to_cpu(htt_stats_buf->mpdu_tried));
181 len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n",
182 le32_to_cpu(htt_stats_buf->isr_wait_seq_posted));
183 len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n",
184 le32_to_cpu(htt_stats_buf->tx_active_dur_us_low));
185 len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n",
186 le32_to_cpu(htt_stats_buf->tx_active_dur_us_high));
187 len += scnprintf(buf + len, buf_len - len, "fes_offsets_err_cnt = %u\n\n",
188 le32_to_cpu(htt_stats_buf->fes_offsets_err_cnt));
189
190 stats_req->buf_len = len;
191 }
192
193 static void
htt_print_tx_pdev_stats_urrn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)194 htt_print_tx_pdev_stats_urrn_tlv(const void *tag_buf,
195 u16 tag_len,
196 struct debug_htt_stats_req *stats_req)
197 {
198 const struct ath12k_htt_tx_pdev_stats_urrn_tlv *htt_stats_buf = tag_buf;
199 u8 *buf = stats_req->buf;
200 u32 len = stats_req->buf_len;
201 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
202 u16 num_elems = min_t(u16, (tag_len >> 2),
203 HTT_TX_PDEV_MAX_URRN_STATS);
204
205 len += scnprintf(buf + len, buf_len - len,
206 "HTT_TX_PDEV_STATS_URRN_TLV:\n");
207
208 len += print_array_to_buf(buf, len, "urrn_stats", htt_stats_buf->urrn_stats,
209 num_elems, "\n\n");
210
211 stats_req->buf_len = len;
212 }
213
214 static void
htt_print_tx_pdev_stats_flush_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)215 htt_print_tx_pdev_stats_flush_tlv(const void *tag_buf,
216 u16 tag_len,
217 struct debug_htt_stats_req *stats_req)
218 {
219 const struct ath12k_htt_tx_pdev_stats_flush_tlv *htt_stats_buf = tag_buf;
220 u8 *buf = stats_req->buf;
221 u32 len = stats_req->buf_len;
222 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
223 u16 num_elems = min_t(u16, (tag_len >> 2),
224 ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS);
225
226 len += scnprintf(buf + len, buf_len - len,
227 "HTT_TX_PDEV_STATS_FLUSH_TLV:\n");
228
229 len += print_array_to_buf(buf, len, "flush_errs", htt_stats_buf->flush_errs,
230 num_elems, "\n\n");
231
232 stats_req->buf_len = len;
233 }
234
235 static void
htt_print_tx_pdev_stats_sifs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)236 htt_print_tx_pdev_stats_sifs_tlv(const void *tag_buf,
237 u16 tag_len,
238 struct debug_htt_stats_req *stats_req)
239 {
240 const struct ath12k_htt_tx_pdev_stats_sifs_tlv *htt_stats_buf = tag_buf;
241 u8 *buf = stats_req->buf;
242 u32 len = stats_req->buf_len;
243 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
244 u16 num_elems = min_t(u16, (tag_len >> 2),
245 ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS);
246
247 len += scnprintf(buf + len, buf_len - len,
248 "HTT_TX_PDEV_STATS_SIFS_TLV:\n");
249
250 len += print_array_to_buf(buf, len, "sifs_status", htt_stats_buf->sifs_status,
251 num_elems, "\n\n");
252
253 stats_req->buf_len = len;
254 }
255
256 static void
htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)257 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void *tag_buf, u16 tag_len,
258 struct debug_htt_stats_req *stats_req)
259 {
260 const struct ath12k_htt_tx_pdev_mu_ppdu_dist_stats_tlv *htt_stats_buf = tag_buf;
261 char *mode;
262 u8 j, hw_mode, i, str_buf_len;
263 u8 *buf = stats_req->buf;
264 u32 len = stats_req->buf_len;
265 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
266 u32 stats_value;
267 u8 max_ppdu = ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST;
268 u8 max_sched = ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS;
269 char str_buf[ATH12K_HTT_MAX_STRING_LEN];
270
271 if (tag_len < sizeof(*htt_stats_buf))
272 return;
273
274 hw_mode = le32_to_cpu(htt_stats_buf->hw_mode);
275
276 switch (hw_mode) {
277 case ATH12K_HTT_STATS_HWMODE_AC:
278 len += scnprintf(buf + len, buf_len - len,
279 "HTT_TX_PDEV_AC_MU_PPDU_DISTRIBUTION_STATS:\n");
280 mode = "ac";
281 break;
282 case ATH12K_HTT_STATS_HWMODE_AX:
283 len += scnprintf(buf + len, buf_len - len,
284 "HTT_TX_PDEV_AX_MU_PPDU_DISTRIBUTION_STATS:\n");
285 mode = "ax";
286 break;
287 case ATH12K_HTT_STATS_HWMODE_BE:
288 len += scnprintf(buf + len, buf_len - len,
289 "HTT_TX_PDEV_BE_MU_PPDU_DISTRIBUTION_STATS:\n");
290 mode = "be";
291 break;
292 default:
293 return;
294 }
295
296 for (i = 0; i < ATH12K_HTT_STATS_NUM_NR_BINS ; i++) {
297 len += scnprintf(buf + len, buf_len - len,
298 "%s_mu_mimo_num_seq_posted_nr%u = %u\n", mode,
299 ((i + 1) * 4), htt_stats_buf->num_seq_posted[i]);
300 str_buf_len = 0;
301 memset(str_buf, 0x0, sizeof(str_buf));
302 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
303 stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_posted_per_burst
304 [i * max_ppdu + j]);
305 str_buf_len += scnprintf(&str_buf[str_buf_len],
306 ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
307 " %u:%u,", j, stats_value);
308 }
309 /* To overwrite the last trailing comma */
310 str_buf[str_buf_len - 1] = '\0';
311 len += scnprintf(buf + len, buf_len - len,
312 "%s_mu_mimo_num_ppdu_posted_per_burst_nr%u = %s\n",
313 mode, ((i + 1) * 4), str_buf);
314 str_buf_len = 0;
315 memset(str_buf, 0x0, sizeof(str_buf));
316 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) {
317 stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_cmpl_per_burst
318 [i * max_ppdu + j]);
319 str_buf_len += scnprintf(&str_buf[str_buf_len],
320 ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
321 " %u:%u,", j, stats_value);
322 }
323 /* To overwrite the last trailing comma */
324 str_buf[str_buf_len - 1] = '\0';
325 len += scnprintf(buf + len, buf_len - len,
326 "%s_mu_mimo_num_ppdu_completed_per_burst_nr%u = %s\n",
327 mode, ((i + 1) * 4), str_buf);
328 str_buf_len = 0;
329 memset(str_buf, 0x0, sizeof(str_buf));
330 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS ; j++) {
331 stats_value = le32_to_cpu(htt_stats_buf->num_seq_term_status
332 [i * max_sched + j]);
333 str_buf_len += scnprintf(&str_buf[str_buf_len],
334 ATH12K_HTT_MAX_STRING_LEN - str_buf_len,
335 " %u:%u,", j, stats_value);
336 }
337 /* To overwrite the last trailing comma */
338 str_buf[str_buf_len - 1] = '\0';
339 len += scnprintf(buf + len, buf_len - len,
340 "%s_mu_mimo_num_seq_term_status_nr%u = %s\n\n",
341 mode, ((i + 1) * 4), str_buf);
342 }
343
344 stats_req->buf_len = len;
345 }
346
347 static void
htt_print_tx_pdev_stats_sifs_hist_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)348 htt_print_tx_pdev_stats_sifs_hist_tlv(const void *tag_buf,
349 u16 tag_len,
350 struct debug_htt_stats_req *stats_req)
351 {
352 const struct ath12k_htt_tx_pdev_stats_sifs_hist_tlv *htt_stats_buf = tag_buf;
353 u8 *buf = stats_req->buf;
354 u32 len = stats_req->buf_len;
355 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
356 u16 num_elems = min_t(u16, (tag_len >> 2),
357 ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS);
358
359 len += scnprintf(buf + len, buf_len - len,
360 "HTT_TX_PDEV_STATS_SIFS_HIST_TLV:\n");
361
362 len += print_array_to_buf(buf, len, "sifs_hist_status",
363 htt_stats_buf->sifs_hist_status, num_elems, "\n\n");
364
365 stats_req->buf_len = len;
366 }
367
368 static void
htt_print_pdev_ctrl_path_tx_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)369 htt_print_pdev_ctrl_path_tx_stats_tlv(const void *tag_buf, u16 tag_len,
370 struct debug_htt_stats_req *stats_req)
371 {
372 const struct ath12k_htt_pdev_ctrl_path_tx_stats_tlv *htt_stats_buf = tag_buf;
373 u8 *buf = stats_req->buf;
374 u32 len = stats_req->buf_len;
375 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
376
377 if (len < sizeof(*htt_stats_buf))
378 return;
379
380 len += scnprintf(buf + len, buf_len - len,
381 "HTT_TX_PDEV_STATS_CTRL_PATH_TX_STATS:\n");
382 len += print_array_to_buf(buf, len, "fw_tx_mgmt_subtype",
383 htt_stats_buf->fw_tx_mgmt_subtype,
384 ATH12K_HTT_STATS_SUBTYPE_MAX, "\n\n");
385
386 stats_req->buf_len = len;
387 }
388
389 static void
ath12k_htt_print_stats_tx_sched_cmn_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)390 ath12k_htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf,
391 u16 tag_len,
392 struct debug_htt_stats_req *stats_req)
393 {
394 const struct ath12k_htt_stats_tx_sched_cmn_tlv *htt_stats_buf = tag_buf;
395 u8 *buf = stats_req->buf;
396 u32 len = stats_req->buf_len;
397 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
398 u32 mac_id_word;
399
400 if (tag_len < sizeof(*htt_stats_buf))
401 return;
402
403 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
404
405 len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n");
406 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
407 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
408 len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n",
409 le32_to_cpu(htt_stats_buf->current_timestamp));
410
411 stats_req->buf_len = len;
412 }
413
414 static void
ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)415 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf,
416 u16 tag_len,
417 struct debug_htt_stats_req *stats_req)
418 {
419 const struct ath12k_htt_tx_pdev_stats_sched_per_txq_tlv *htt_stats_buf = tag_buf;
420 u8 *buf = stats_req->buf;
421 u32 len = stats_req->buf_len;
422 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
423 u32 mac_id_word;
424
425 if (tag_len < sizeof(*htt_stats_buf))
426 return;
427
428 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
429
430 len += scnprintf(buf + len, buf_len - len,
431 "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n");
432 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
433 u32_get_bits(mac_id_word,
434 ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID));
435 len += scnprintf(buf + len, buf_len - len, "txq_id = %u\n",
436 u32_get_bits(mac_id_word,
437 ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID));
438 len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n",
439 le32_to_cpu(htt_stats_buf->sched_policy));
440 len += scnprintf(buf + len, buf_len - len,
441 "last_sched_cmd_posted_timestamp = %u\n",
442 le32_to_cpu(htt_stats_buf->last_sched_cmd_posted_timestamp));
443 len += scnprintf(buf + len, buf_len - len,
444 "last_sched_cmd_compl_timestamp = %u\n",
445 le32_to_cpu(htt_stats_buf->last_sched_cmd_compl_timestamp));
446 len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n",
447 le32_to_cpu(htt_stats_buf->sched_2_tac_lwm_count));
448 len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n",
449 le32_to_cpu(htt_stats_buf->sched_2_tac_ring_full));
450 len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n",
451 le32_to_cpu(htt_stats_buf->sched_cmd_post_failure));
452 len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n",
453 le32_to_cpu(htt_stats_buf->num_active_tids));
454 len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n",
455 le32_to_cpu(htt_stats_buf->num_ps_schedules));
456 len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n",
457 le32_to_cpu(htt_stats_buf->sched_cmds_pending));
458 len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n",
459 le32_to_cpu(htt_stats_buf->num_tid_register));
460 len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n",
461 le32_to_cpu(htt_stats_buf->num_tid_unregister));
462 len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n",
463 le32_to_cpu(htt_stats_buf->num_qstats_queried));
464 len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n",
465 le32_to_cpu(htt_stats_buf->qstats_update_pending));
466 len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n",
467 le32_to_cpu(htt_stats_buf->last_qstats_query_timestamp));
468 len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n",
469 le32_to_cpu(htt_stats_buf->num_tqm_cmdq_full));
470 len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n",
471 le32_to_cpu(htt_stats_buf->num_de_sched_algo_trigger));
472 len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n",
473 le32_to_cpu(htt_stats_buf->num_rt_sched_algo_trigger));
474 len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n",
475 le32_to_cpu(htt_stats_buf->num_tqm_sched_algo_trigger));
476 len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n",
477 le32_to_cpu(htt_stats_buf->notify_sched));
478 len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n",
479 le32_to_cpu(htt_stats_buf->dur_based_sendn_term));
480 len += scnprintf(buf + len, buf_len - len, "su_notify2_sched = %u\n",
481 le32_to_cpu(htt_stats_buf->su_notify2_sched));
482 len += scnprintf(buf + len, buf_len - len, "su_optimal_queued_msdus_sched = %u\n",
483 le32_to_cpu(htt_stats_buf->su_optimal_queued_msdus_sched));
484 len += scnprintf(buf + len, buf_len - len, "su_delay_timeout_sched = %u\n",
485 le32_to_cpu(htt_stats_buf->su_delay_timeout_sched));
486 len += scnprintf(buf + len, buf_len - len, "su_min_txtime_sched_delay = %u\n",
487 le32_to_cpu(htt_stats_buf->su_min_txtime_sched_delay));
488 len += scnprintf(buf + len, buf_len - len, "su_no_delay = %u\n",
489 le32_to_cpu(htt_stats_buf->su_no_delay));
490 len += scnprintf(buf + len, buf_len - len, "num_supercycles = %u\n",
491 le32_to_cpu(htt_stats_buf->num_supercycles));
492 len += scnprintf(buf + len, buf_len - len, "num_subcycles_with_sort = %u\n",
493 le32_to_cpu(htt_stats_buf->num_subcycles_with_sort));
494 len += scnprintf(buf + len, buf_len - len, "num_subcycles_no_sort = %u\n\n",
495 le32_to_cpu(htt_stats_buf->num_subcycles_no_sort));
496
497 stats_req->buf_len = len;
498 }
499
500 static void
ath12k_htt_print_sched_txq_cmd_posted_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)501 ath12k_htt_print_sched_txq_cmd_posted_tlv(const void *tag_buf,
502 u16 tag_len,
503 struct debug_htt_stats_req *stats_req)
504 {
505 const struct ath12k_htt_sched_txq_cmd_posted_tlv *htt_stats_buf = tag_buf;
506 u8 *buf = stats_req->buf;
507 u32 len = stats_req->buf_len;
508 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
509 u16 num_elements = tag_len >> 2;
510
511 len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV:\n");
512 len += print_array_to_buf(buf, len, "sched_cmd_posted",
513 htt_stats_buf->sched_cmd_posted, num_elements, "\n\n");
514
515 stats_req->buf_len = len;
516 }
517
518 static void
ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)519 ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void *tag_buf,
520 u16 tag_len,
521 struct debug_htt_stats_req *stats_req)
522 {
523 const struct ath12k_htt_sched_txq_cmd_reaped_tlv *htt_stats_buf = tag_buf;
524 u8 *buf = stats_req->buf;
525 u32 len = stats_req->buf_len;
526 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
527 u16 num_elements = tag_len >> 2;
528
529 len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV:\n");
530 len += print_array_to_buf(buf, len, "sched_cmd_reaped",
531 htt_stats_buf->sched_cmd_reaped, num_elements, "\n\n");
532
533 stats_req->buf_len = len;
534 }
535
536 static void
ath12k_htt_print_sched_txq_sched_order_su_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)537 ath12k_htt_print_sched_txq_sched_order_su_tlv(const void *tag_buf,
538 u16 tag_len,
539 struct debug_htt_stats_req *stats_req)
540 {
541 const struct ath12k_htt_sched_txq_sched_order_su_tlv *htt_stats_buf = tag_buf;
542 u8 *buf = stats_req->buf;
543 u32 len = stats_req->buf_len;
544 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
545 u32 sched_order_su_num_entries = min_t(u32, (tag_len >> 2),
546 ATH12K_HTT_TX_PDEV_NUM_SCHED_ORDER_LOG);
547
548 len += scnprintf(buf + len, buf_len - len,
549 "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV:\n");
550 len += print_array_to_buf(buf, len, "sched_order_su",
551 htt_stats_buf->sched_order_su,
552 sched_order_su_num_entries, "\n\n");
553
554 stats_req->buf_len = len;
555 }
556
557 static void
ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)558 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void *tag_buf,
559 u16 tag_len,
560 struct debug_htt_stats_req *stats_req)
561 {
562 const struct ath12k_htt_sched_txq_sched_ineligibility_tlv *htt_stats_buf =
563 tag_buf;
564 u8 *buf = stats_req->buf;
565 u32 len = stats_req->buf_len;
566 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
567 u32 sched_ineligibility_num_entries = tag_len >> 2;
568
569 len += scnprintf(buf + len, buf_len - len,
570 "HTT_SCHED_TXQ_SCHED_INELIGIBILITY:\n");
571 len += print_array_to_buf(buf, len, "sched_ineligibility",
572 htt_stats_buf->sched_ineligibility,
573 sched_ineligibility_num_entries, "\n\n");
574
575 stats_req->buf_len = len;
576 }
577
578 static void
ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)579 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void *tag_buf,
580 u16 tag_len,
581 struct debug_htt_stats_req *stats_req)
582 {
583 const struct ath12k_htt_sched_txq_supercycle_triggers_tlv *htt_stats_buf =
584 tag_buf;
585 u8 *buf = stats_req->buf;
586 u32 len = stats_req->buf_len;
587 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
588 u16 num_elems = min_t(u16, (tag_len >> 2),
589 ATH12K_HTT_SCHED_SUPERCYCLE_TRIGGER_MAX);
590
591 len += scnprintf(buf + len, buf_len - len,
592 "HTT_SCHED_TXQ_SUPERCYCLE_TRIGGER:\n");
593 len += print_array_to_buf(buf, len, "supercycle_triggers",
594 htt_stats_buf->supercycle_triggers, num_elems, "\n\n");
595
596 stats_req->buf_len = len;
597 }
598
599 static void
ath12k_htt_print_hw_stats_pdev_errs_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)600 ath12k_htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf, u16 tag_len,
601 struct debug_htt_stats_req *stats_req)
602 {
603 const struct ath12k_htt_hw_stats_pdev_errs_tlv *htt_buf = tag_buf;
604 u8 *buf = stats_req->buf;
605 u32 len = stats_req->buf_len;
606 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
607 u32 mac_id_word;
608
609 if (tag_len < sizeof(*htt_buf))
610 return;
611
612 mac_id_word = le32_to_cpu(htt_buf->mac_id__word);
613
614 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n");
615 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
616 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
617 len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
618 le32_to_cpu(htt_buf->tx_abort));
619 len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n",
620 le32_to_cpu(htt_buf->tx_abort_fail_count));
621 len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n",
622 le32_to_cpu(htt_buf->rx_abort));
623 len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n",
624 le32_to_cpu(htt_buf->rx_abort_fail_count));
625 len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n",
626 le32_to_cpu(htt_buf->rx_flush_cnt));
627 len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n",
628 le32_to_cpu(htt_buf->warm_reset));
629 len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n",
630 le32_to_cpu(htt_buf->cold_reset));
631 len += scnprintf(buf + len, buf_len - len, "mac_cold_reset_restore_cal = %u\n",
632 le32_to_cpu(htt_buf->mac_cold_reset_restore_cal));
633 len += scnprintf(buf + len, buf_len - len, "mac_cold_reset = %u\n",
634 le32_to_cpu(htt_buf->mac_cold_reset));
635 len += scnprintf(buf + len, buf_len - len, "mac_warm_reset = %u\n",
636 le32_to_cpu(htt_buf->mac_warm_reset));
637 len += scnprintf(buf + len, buf_len - len, "mac_only_reset = %u\n",
638 le32_to_cpu(htt_buf->mac_only_reset));
639 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset = %u\n",
640 le32_to_cpu(htt_buf->phy_warm_reset));
641 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_ucode_trig = %u\n",
642 le32_to_cpu(htt_buf->phy_warm_reset_ucode_trig));
643 len += scnprintf(buf + len, buf_len - len, "mac_warm_reset_restore_cal = %u\n",
644 le32_to_cpu(htt_buf->mac_warm_reset_restore_cal));
645 len += scnprintf(buf + len, buf_len - len, "mac_sfm_reset = %u\n",
646 le32_to_cpu(htt_buf->mac_sfm_reset));
647 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_m3_ssr = %u\n",
648 le32_to_cpu(htt_buf->phy_warm_reset_m3_ssr));
649 len += scnprintf(buf + len, buf_len - len, "fw_rx_rings_reset = %u\n",
650 le32_to_cpu(htt_buf->fw_rx_rings_reset));
651 len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n",
652 le32_to_cpu(htt_buf->tx_flush));
653 len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n",
654 le32_to_cpu(htt_buf->tx_glb_reset));
655 len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n",
656 le32_to_cpu(htt_buf->tx_txq_reset));
657 len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n",
658 le32_to_cpu(htt_buf->rx_timeout_reset));
659
660 len += scnprintf(buf + len, buf_len - len, "PDEV_PHY_WARM_RESET_REASONS:\n");
661 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_reason_phy_m3 = %u\n",
662 le32_to_cpu(htt_buf->phy_warm_reset_reason_phy_m3));
663 len += scnprintf(buf + len, buf_len - len,
664 "phy_warm_reset_reason_tx_hw_stuck = %u\n",
665 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hw_stuck));
666 len += scnprintf(buf + len, buf_len - len,
667 "phy_warm_reset_reason_num_cca_rx_frame_stuck = %u\n",
668 le32_to_cpu(htt_buf->phy_warm_reset_reason_num_rx_frame_stuck));
669 len += scnprintf(buf + len, buf_len - len,
670 "phy_warm_reset_reason_wal_rx_recovery_rst_rx_busy = %u\n",
671 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_rx_busy));
672 len += scnprintf(buf + len, buf_len - len,
673 "phy_warm_reset_reason_wal_rx_recovery_rst_mac_hang = %u\n",
674 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_mac_hng));
675 len += scnprintf(buf + len, buf_len - len,
676 "phy_warm_reset_reason_mac_reset_converted_phy_reset = %u\n",
677 le32_to_cpu(htt_buf->phy_warm_reset_reason_mac_conv_phy_reset));
678 len += scnprintf(buf + len, buf_len - len,
679 "phy_warm_reset_reason_tx_lifetime_expiry_cca_stuck = %u\n",
680 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_exp_cca_stuck));
681 len += scnprintf(buf + len, buf_len - len,
682 "phy_warm_reset_reason_tx_consecutive_flush9_war = %u\n",
683 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_consec_flsh_war));
684 len += scnprintf(buf + len, buf_len - len,
685 "phy_warm_reset_reason_tx_hwsch_reset_war = %u\n",
686 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hwsch_reset_war));
687 len += scnprintf(buf + len, buf_len - len,
688 "phy_warm_reset_reason_hwsch_wdog_or_cca_wdog_war = %u\n\n",
689 le32_to_cpu(htt_buf->phy_warm_reset_reason_hwsch_cca_wdog_war));
690
691 len += scnprintf(buf + len, buf_len - len, "WAL_RX_RECOVERY_STATS:\n");
692 len += scnprintf(buf + len, buf_len - len,
693 "wal_rx_recovery_rst_mac_hang_count = %u\n",
694 le32_to_cpu(htt_buf->wal_rx_recovery_rst_mac_hang_cnt));
695 len += scnprintf(buf + len, buf_len - len,
696 "wal_rx_recovery_rst_known_sig_count = %u\n",
697 le32_to_cpu(htt_buf->wal_rx_recovery_rst_known_sig_cnt));
698 len += scnprintf(buf + len, buf_len - len,
699 "wal_rx_recovery_rst_no_rx_count = %u\n",
700 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_cnt));
701 len += scnprintf(buf + len, buf_len - len,
702 "wal_rx_recovery_rst_no_rx_consecutive_count = %u\n",
703 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_consec_cnt));
704 len += scnprintf(buf + len, buf_len - len,
705 "wal_rx_recovery_rst_rx_busy_count = %u\n",
706 le32_to_cpu(htt_buf->wal_rx_recovery_rst_rx_busy_cnt));
707 len += scnprintf(buf + len, buf_len - len,
708 "wal_rx_recovery_rst_phy_mac_hang_count = %u\n\n",
709 le32_to_cpu(htt_buf->wal_rx_recovery_rst_phy_mac_hang_cnt));
710
711 len += scnprintf(buf + len, buf_len - len, "HTT_RX_DEST_DRAIN_STATS:\n");
712 len += scnprintf(buf + len, buf_len - len,
713 "rx_dest_drain_rx_descs_leak_prevention_done = %u\n",
714 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_leak_prevented));
715 len += scnprintf(buf + len, buf_len - len,
716 "rx_dest_drain_rx_descs_saved_cnt = %u\n",
717 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_saved_cnt));
718 len += scnprintf(buf + len, buf_len - len,
719 "rx_dest_drain_rxdma2reo_leak_detected = %u\n",
720 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2reo_leak_detected));
721 len += scnprintf(buf + len, buf_len - len,
722 "rx_dest_drain_rxdma2fw_leak_detected = %u\n",
723 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2fw_leak_detected));
724 len += scnprintf(buf + len, buf_len - len,
725 "rx_dest_drain_rxdma2wbm_leak_detected = %u\n",
726 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2wbm_leak_detected));
727 len += scnprintf(buf + len, buf_len - len,
728 "rx_dest_drain_rxdma1_2sw_leak_detected = %u\n",
729 le32_to_cpu(htt_buf->rx_dest_drain_rxdma1_2sw_leak_detected));
730 len += scnprintf(buf + len, buf_len - len,
731 "rx_dest_drain_rx_drain_ok_mac_idle = %u\n",
732 le32_to_cpu(htt_buf->rx_dest_drain_rx_drain_ok_mac_idle));
733 len += scnprintf(buf + len, buf_len - len,
734 "rx_dest_drain_ok_mac_not_idle = %u\n",
735 le32_to_cpu(htt_buf->rx_dest_drain_ok_mac_not_idle));
736 len += scnprintf(buf + len, buf_len - len,
737 "rx_dest_drain_prerequisite_invld = %u\n",
738 le32_to_cpu(htt_buf->rx_dest_drain_prerequisite_invld));
739 len += scnprintf(buf + len, buf_len - len,
740 "rx_dest_drain_skip_for_non_lmac_reset = %u\n",
741 le32_to_cpu(htt_buf->rx_dest_drain_skip_non_lmac_reset));
742 len += scnprintf(buf + len, buf_len - len,
743 "rx_dest_drain_hw_fifo_not_empty_post_drain_wait = %u\n\n",
744 le32_to_cpu(htt_buf->rx_dest_drain_hw_fifo_notempty_post_wait));
745
746 stats_req->buf_len = len;
747 }
748
749 static void
ath12k_htt_print_hw_stats_intr_misc_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)750 ath12k_htt_print_hw_stats_intr_misc_tlv(const void *tag_buf, u16 tag_len,
751 struct debug_htt_stats_req *stats_req)
752 {
753 const struct ath12k_htt_hw_stats_intr_misc_tlv *htt_stats_buf = tag_buf;
754 u8 *buf = stats_req->buf;
755 u32 len = stats_req->buf_len;
756 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
757
758 if (tag_len < sizeof(*htt_stats_buf))
759 return;
760
761 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n");
762 len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n",
763 htt_stats_buf->hw_intr_name);
764 len += scnprintf(buf + len, buf_len - len, "mask = %u\n",
765 le32_to_cpu(htt_stats_buf->mask));
766 len += scnprintf(buf + len, buf_len - len, "count = %u\n\n",
767 le32_to_cpu(htt_stats_buf->count));
768
769 stats_req->buf_len = len;
770 }
771
772 static void
ath12k_htt_print_hw_stats_whal_tx_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)773 ath12k_htt_print_hw_stats_whal_tx_tlv(const void *tag_buf, u16 tag_len,
774 struct debug_htt_stats_req *stats_req)
775 {
776 const struct ath12k_htt_hw_stats_whal_tx_tlv *htt_stats_buf = tag_buf;
777 u8 *buf = stats_req->buf;
778 u32 len = stats_req->buf_len;
779 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
780 u32 mac_id_word;
781
782 if (tag_len < sizeof(*htt_stats_buf))
783 return;
784
785 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
786
787 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n");
788 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
789 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
790 len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n",
791 le32_to_cpu(htt_stats_buf->last_unpause_ppdu_id));
792 len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n",
793 le32_to_cpu(htt_stats_buf->hwsch_unpause_wait_tqm_write));
794 len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n",
795 le32_to_cpu(htt_stats_buf->hwsch_dummy_tlv_skipped));
796 len += scnprintf(buf + len, buf_len - len,
797 "hwsch_misaligned_offset_received = %u\n",
798 le32_to_cpu(htt_stats_buf->hwsch_misaligned_offset_received));
799 len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n",
800 le32_to_cpu(htt_stats_buf->hwsch_reset_count));
801 len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n",
802 le32_to_cpu(htt_stats_buf->hwsch_dev_reset_war));
803 len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n",
804 le32_to_cpu(htt_stats_buf->hwsch_delayed_pause));
805 len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n",
806 le32_to_cpu(htt_stats_buf->hwsch_long_delayed_pause));
807 len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n",
808 le32_to_cpu(htt_stats_buf->sch_rx_ppdu_no_response));
809 len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n",
810 le32_to_cpu(htt_stats_buf->sch_selfgen_response));
811 len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n",
812 le32_to_cpu(htt_stats_buf->sch_rx_sifs_resp_trigger));
813
814 stats_req->buf_len = len;
815 }
816
817 static void
ath12k_htt_print_hw_war_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)818 ath12k_htt_print_hw_war_tlv(const void *tag_buf, u16 tag_len,
819 struct debug_htt_stats_req *stats_req)
820 {
821 const struct ath12k_htt_hw_war_stats_tlv *htt_stats_buf = tag_buf;
822 u8 *buf = stats_req->buf;
823 u32 len = stats_req->buf_len;
824 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
825 u16 fixed_len, array_len;
826 u8 i, array_words;
827 u32 mac_id;
828
829 if (tag_len < sizeof(*htt_stats_buf))
830 return;
831
832 mac_id = __le32_to_cpu(htt_stats_buf->mac_id__word);
833 fixed_len = sizeof(*htt_stats_buf);
834 array_len = tag_len - fixed_len;
835 array_words = array_len >> 2;
836
837 len += scnprintf(buf + len, buf_len - len, "HTT_HW_WAR_STATS_TLV:\n");
838 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
839 u32_get_bits(mac_id, ATH12K_HTT_STATS_MAC_ID));
840
841 for (i = 0; i < array_words; i++) {
842 len += scnprintf(buf + len, buf_len - len, "hw_war %u = %u\n\n",
843 i, le32_to_cpu(htt_stats_buf->hw_wars[i]));
844 }
845
846 stats_req->buf_len = len;
847 }
848
849 static void
ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)850 ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
851 struct debug_htt_stats_req *stats_req)
852 {
853 const struct ath12k_htt_tx_tqm_cmn_stats_tlv *htt_stats_buf = tag_buf;
854 u8 *buf = stats_req->buf;
855 u32 len = stats_req->buf_len;
856 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
857 u32 mac_id_word;
858
859 if (tag_len < sizeof(*htt_stats_buf))
860 return;
861
862 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
863
864 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n");
865 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
866 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
867 len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n",
868 le32_to_cpu(htt_stats_buf->max_cmdq_id));
869 len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n",
870 le32_to_cpu(htt_stats_buf->list_mpdu_cnt_hist_intvl));
871 len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n",
872 le32_to_cpu(htt_stats_buf->add_msdu));
873 len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n",
874 le32_to_cpu(htt_stats_buf->q_empty));
875 len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n",
876 le32_to_cpu(htt_stats_buf->q_not_empty));
877 len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n",
878 le32_to_cpu(htt_stats_buf->drop_notification));
879 len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n",
880 le32_to_cpu(htt_stats_buf->desc_threshold));
881 len += scnprintf(buf + len, buf_len - len, "hwsch_tqm_invalid_status = %u\n",
882 le32_to_cpu(htt_stats_buf->hwsch_tqm_invalid_status));
883 len += scnprintf(buf + len, buf_len - len, "missed_tqm_gen_mpdus = %u\n",
884 le32_to_cpu(htt_stats_buf->missed_tqm_gen_mpdus));
885 len += scnprintf(buf + len, buf_len - len,
886 "total_msduq_timestamp_updates = %u\n",
887 le32_to_cpu(htt_stats_buf->msduq_timestamp_updates));
888 len += scnprintf(buf + len, buf_len - len,
889 "total_msduq_timestamp_updates_by_get_mpdu_head_info_cmd = %u\n",
890 le32_to_cpu(htt_stats_buf->msduq_updates_mpdu_head_info_cmd));
891 len += scnprintf(buf + len, buf_len - len,
892 "total_msduq_timestamp_updates_by_emp_to_nonemp_status = %u\n",
893 le32_to_cpu(htt_stats_buf->msduq_updates_emp_to_nonemp_status));
894 len += scnprintf(buf + len, buf_len - len,
895 "total_get_mpdu_head_info_cmds_by_sched_algo_la_query = %u\n",
896 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_query));
897 len += scnprintf(buf + len, buf_len - len,
898 "total_get_mpdu_head_info_cmds_by_tac = %u\n",
899 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_tac));
900 len += scnprintf(buf + len, buf_len - len,
901 "total_gen_mpdu_cmds_by_sched_algo_la_query = %u\n",
902 le32_to_cpu(htt_stats_buf->gen_mpdu_cmds_by_query));
903 len += scnprintf(buf + len, buf_len - len, "active_tqm_tids = %u\n",
904 le32_to_cpu(htt_stats_buf->tqm_active_tids));
905 len += scnprintf(buf + len, buf_len - len, "inactive_tqm_tids = %u\n",
906 le32_to_cpu(htt_stats_buf->tqm_inactive_tids));
907 len += scnprintf(buf + len, buf_len - len, "tqm_active_msduq_flows = %u\n",
908 le32_to_cpu(htt_stats_buf->tqm_active_msduq_flows));
909 len += scnprintf(buf + len, buf_len - len, "hi_prio_q_not_empty = %u\n\n",
910 le32_to_cpu(htt_stats_buf->high_prio_q_not_empty));
911
912 stats_req->buf_len = len;
913 }
914
915 static void
ath12k_htt_print_tx_tqm_error_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)916 ath12k_htt_print_tx_tqm_error_stats_tlv(const void *tag_buf, u16 tag_len,
917 struct debug_htt_stats_req *stats_req)
918 {
919 const struct ath12k_htt_tx_tqm_error_stats_tlv *htt_stats_buf = tag_buf;
920 u8 *buf = stats_req->buf;
921 u32 len = stats_req->buf_len;
922 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
923
924 if (tag_len < sizeof(*htt_stats_buf))
925 return;
926
927 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n");
928 len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n",
929 le32_to_cpu(htt_stats_buf->q_empty_failure));
930 len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n",
931 le32_to_cpu(htt_stats_buf->q_not_empty_failure));
932 len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n",
933 le32_to_cpu(htt_stats_buf->add_msdu_failure));
934
935 len += scnprintf(buf + len, buf_len - len, "TQM_ERROR_RESET_STATS:\n");
936 len += scnprintf(buf + len, buf_len - len, "tqm_cache_ctl_err = %u\n",
937 le32_to_cpu(htt_stats_buf->tqm_cache_ctl_err));
938 len += scnprintf(buf + len, buf_len - len, "tqm_soft_reset = %u\n",
939 le32_to_cpu(htt_stats_buf->tqm_soft_reset));
940 len += scnprintf(buf + len, buf_len - len,
941 "tqm_reset_total_num_in_use_link_descs = %u\n",
942 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_link_descs));
943 len += scnprintf(buf + len, buf_len - len,
944 "tqm_reset_worst_case_num_lost_link_descs = %u\n",
945 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_link_descs));
946 len += scnprintf(buf + len, buf_len - len,
947 "tqm_reset_worst_case_num_lost_host_tx_bufs_count = %u\n",
948 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_host_tx_buf_cnt));
949 len += scnprintf(buf + len, buf_len - len,
950 "tqm_reset_num_in_use_link_descs_internal_tqm = %u\n",
951 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_internal_tqm));
952 len += scnprintf(buf + len, buf_len - len,
953 "tqm_reset_num_in_use_link_descs_wbm_idle_link_ring = %u\n",
954 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_idle_link_rng));
955 len += scnprintf(buf + len, buf_len - len,
956 "tqm_reset_time_to_tqm_hang_delta_ms = %u\n",
957 le32_to_cpu(htt_stats_buf->tqm_reset_time_to_tqm_hang_delta_ms));
958 len += scnprintf(buf + len, buf_len - len, "tqm_reset_recovery_time_ms = %u\n",
959 le32_to_cpu(htt_stats_buf->tqm_reset_recovery_time_ms));
960 len += scnprintf(buf + len, buf_len - len, "tqm_reset_num_peers_hdl = %u\n",
961 le32_to_cpu(htt_stats_buf->tqm_reset_num_peers_hdl));
962 len += scnprintf(buf + len, buf_len - len,
963 "tqm_reset_cumm_dirty_hw_mpduq_proc_cnt = %u\n",
964 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_mpduq_cnt));
965 len += scnprintf(buf + len, buf_len - len,
966 "tqm_reset_cumm_dirty_hw_msduq_proc = %u\n",
967 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_msduq_proc));
968 len += scnprintf(buf + len, buf_len - len,
969 "tqm_reset_flush_cache_cmd_su_cnt = %u\n",
970 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_su_cnt));
971 len += scnprintf(buf + len, buf_len - len,
972 "tqm_reset_flush_cache_cmd_other_cnt = %u\n",
973 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_other_cnt));
974 len += scnprintf(buf + len, buf_len - len,
975 "tqm_reset_flush_cache_cmd_trig_type = %u\n",
976 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_type));
977 len += scnprintf(buf + len, buf_len - len,
978 "tqm_reset_flush_cache_cmd_trig_cfg = %u\n",
979 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_cfg));
980 len += scnprintf(buf + len, buf_len - len,
981 "tqm_reset_flush_cache_cmd_skip_cmd_status_null = %u\n\n",
982 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cmd_skp_status_null));
983
984 stats_req->buf_len = len;
985 }
986
987 static void
ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)988 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
989 struct debug_htt_stats_req *stats_req)
990 {
991 const struct ath12k_htt_tx_tqm_gen_mpdu_stats_tlv *htt_stats_buf = tag_buf;
992 u8 *buf = stats_req->buf;
993 u32 len = stats_req->buf_len;
994 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
995 u16 num_elements = tag_len >> 2;
996
997 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV:\n");
998 len += print_array_to_buf(buf, len, "gen_mpdu_end_reason",
999 htt_stats_buf->gen_mpdu_end_reason, num_elements,
1000 "\n\n");
1001
1002 stats_req->buf_len = len;
1003 }
1004
1005 static void
ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1006 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void *tag_buf, u16 tag_len,
1007 struct debug_htt_stats_req *stats_req)
1008 {
1009 const struct ath12k_htt_tx_tqm_list_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1010 u8 *buf = stats_req->buf;
1011 u32 len = stats_req->buf_len;
1012 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1013 u16 num_elems = min_t(u16, (tag_len >> 2),
1014 ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_END_REASON);
1015
1016 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_STATS_TLV:\n");
1017 len += print_array_to_buf(buf, len, "list_mpdu_end_reason",
1018 htt_stats_buf->list_mpdu_end_reason, num_elems, "\n\n");
1019
1020 stats_req->buf_len = len;
1021 }
1022
1023 static void
ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1024 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void *tag_buf, u16 tag_len,
1025 struct debug_htt_stats_req *stats_req)
1026 {
1027 const struct ath12k_htt_tx_tqm_list_mpdu_cnt_tlv *htt_stats_buf = tag_buf;
1028 u8 *buf = stats_req->buf;
1029 u32 len = stats_req->buf_len;
1030 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1031 u16 num_elems = min_t(u16, (tag_len >> 2),
1032 ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS);
1033
1034 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n");
1035 len += print_array_to_buf(buf, len, "list_mpdu_cnt_hist",
1036 htt_stats_buf->list_mpdu_cnt_hist, num_elems, "\n\n");
1037
1038 stats_req->buf_len = len;
1039 }
1040
1041 static void
ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1042 ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void *tag_buf, u16 tag_len,
1043 struct debug_htt_stats_req *stats_req)
1044 {
1045 const struct ath12k_htt_tx_tqm_pdev_stats_tlv *htt_stats_buf = tag_buf;
1046 u8 *buf = stats_req->buf;
1047 u32 len = stats_req->buf_len;
1048 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1049
1050 if (tag_len < sizeof(*htt_stats_buf))
1051 return;
1052
1053 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n");
1054 len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n",
1055 le32_to_cpu(htt_stats_buf->msdu_count));
1056 len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n",
1057 le32_to_cpu(htt_stats_buf->mpdu_count));
1058 len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n",
1059 le32_to_cpu(htt_stats_buf->remove_msdu));
1060 len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n",
1061 le32_to_cpu(htt_stats_buf->remove_mpdu));
1062 len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n",
1063 le32_to_cpu(htt_stats_buf->remove_msdu_ttl));
1064 len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n",
1065 le32_to_cpu(htt_stats_buf->send_bar));
1066 len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n",
1067 le32_to_cpu(htt_stats_buf->bar_sync));
1068 len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n",
1069 le32_to_cpu(htt_stats_buf->notify_mpdu));
1070 len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
1071 le32_to_cpu(htt_stats_buf->sync_cmd));
1072 len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
1073 le32_to_cpu(htt_stats_buf->write_cmd));
1074 len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n",
1075 le32_to_cpu(htt_stats_buf->hwsch_trigger));
1076 len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
1077 le32_to_cpu(htt_stats_buf->ack_tlv_proc));
1078 len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n",
1079 le32_to_cpu(htt_stats_buf->gen_mpdu_cmd));
1080 len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n",
1081 le32_to_cpu(htt_stats_buf->gen_list_cmd));
1082 len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n",
1083 le32_to_cpu(htt_stats_buf->remove_mpdu_cmd));
1084 len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n",
1085 le32_to_cpu(htt_stats_buf->remove_mpdu_tried_cmd));
1086 len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n",
1087 le32_to_cpu(htt_stats_buf->mpdu_queue_stats_cmd));
1088 len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n",
1089 le32_to_cpu(htt_stats_buf->mpdu_head_info_cmd));
1090 len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n",
1091 le32_to_cpu(htt_stats_buf->msdu_flow_stats_cmd));
1092 len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n",
1093 le32_to_cpu(htt_stats_buf->remove_msdu_cmd));
1094 len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n",
1095 le32_to_cpu(htt_stats_buf->remove_msdu_ttl_cmd));
1096 len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n",
1097 le32_to_cpu(htt_stats_buf->flush_cache_cmd));
1098 len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n",
1099 le32_to_cpu(htt_stats_buf->update_mpduq_cmd));
1100 len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n",
1101 le32_to_cpu(htt_stats_buf->enqueue));
1102 len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n",
1103 le32_to_cpu(htt_stats_buf->enqueue_notify));
1104 len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n",
1105 le32_to_cpu(htt_stats_buf->notify_mpdu_at_head));
1106 len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n",
1107 le32_to_cpu(htt_stats_buf->notify_mpdu_state_valid));
1108 len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n",
1109 le32_to_cpu(htt_stats_buf->sched_udp_notify1));
1110 len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n",
1111 le32_to_cpu(htt_stats_buf->sched_udp_notify2));
1112 len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n",
1113 le32_to_cpu(htt_stats_buf->sched_nonudp_notify1));
1114 len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n",
1115 le32_to_cpu(htt_stats_buf->sched_nonudp_notify2));
1116
1117 stats_req->buf_len = len;
1118 }
1119
1120 static void
ath12k_htt_print_tx_de_cmn_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1121 ath12k_htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, u16 tag_len,
1122 struct debug_htt_stats_req *stats_req)
1123 {
1124 const struct ath12k_htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf;
1125 u8 *buf = stats_req->buf;
1126 u32 len = stats_req->buf_len;
1127 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1128 u32 mac_id_word;
1129
1130 if (tag_len < sizeof(*htt_stats_buf))
1131 return;
1132
1133 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word);
1134
1135 len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
1136 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
1137 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
1138 len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
1139 le32_to_cpu(htt_stats_buf->tcl2fw_entry_count));
1140 len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
1141 le32_to_cpu(htt_stats_buf->not_to_fw));
1142 len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n",
1143 le32_to_cpu(htt_stats_buf->invalid_pdev_vdev_peer));
1144 len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n",
1145 le32_to_cpu(htt_stats_buf->tcl_res_invalid_addrx));
1146 len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n",
1147 le32_to_cpu(htt_stats_buf->wbm2fw_entry_count));
1148 len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n",
1149 le32_to_cpu(htt_stats_buf->invalid_pdev));
1150 len += scnprintf(buf + len, buf_len - len, "tcl_res_addrx_timeout = %u\n",
1151 le32_to_cpu(htt_stats_buf->tcl_res_addrx_timeout));
1152 len += scnprintf(buf + len, buf_len - len, "invalid_vdev = %u\n",
1153 le32_to_cpu(htt_stats_buf->invalid_vdev));
1154 len += scnprintf(buf + len, buf_len - len, "invalid_tcl_exp_frame_desc = %u\n",
1155 le32_to_cpu(htt_stats_buf->invalid_tcl_exp_frame_desc));
1156 len += scnprintf(buf + len, buf_len - len, "vdev_id_mismatch_count = %u\n\n",
1157 le32_to_cpu(htt_stats_buf->vdev_id_mismatch_cnt));
1158
1159 stats_req->buf_len = len;
1160 }
1161
1162 static void
ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1163 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1164 struct debug_htt_stats_req *stats_req)
1165 {
1166 const struct ath12k_htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf;
1167 u8 *buf = stats_req->buf;
1168 u32 len = stats_req->buf_len;
1169 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1170
1171 if (tag_len < sizeof(*htt_stats_buf))
1172 return;
1173
1174 len += scnprintf(buf + len, buf_len - len,
1175 "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n");
1176 len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n",
1177 le32_to_cpu(htt_stats_buf->m1_packets));
1178 len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n",
1179 le32_to_cpu(htt_stats_buf->m2_packets));
1180 len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n",
1181 le32_to_cpu(htt_stats_buf->m3_packets));
1182 len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n",
1183 le32_to_cpu(htt_stats_buf->m4_packets));
1184 len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n",
1185 le32_to_cpu(htt_stats_buf->g1_packets));
1186 len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n",
1187 le32_to_cpu(htt_stats_buf->g2_packets));
1188 len += scnprintf(buf + len, buf_len - len, "rc4_packets = %u\n",
1189 le32_to_cpu(htt_stats_buf->rc4_packets));
1190 len += scnprintf(buf + len, buf_len - len, "eap_packets = %u\n",
1191 le32_to_cpu(htt_stats_buf->eap_packets));
1192 len += scnprintf(buf + len, buf_len - len, "eapol_start_packets = %u\n",
1193 le32_to_cpu(htt_stats_buf->eapol_start_packets));
1194 len += scnprintf(buf + len, buf_len - len, "eapol_logoff_packets = %u\n",
1195 le32_to_cpu(htt_stats_buf->eapol_logoff_packets));
1196 len += scnprintf(buf + len, buf_len - len, "eapol_encap_asf_packets = %u\n\n",
1197 le32_to_cpu(htt_stats_buf->eapol_encap_asf_packets));
1198
1199 stats_req->buf_len = len;
1200 }
1201
1202 static void
ath12k_htt_print_tx_de_classify_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1203 ath12k_htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u16 tag_len,
1204 struct debug_htt_stats_req *stats_req)
1205 {
1206 const struct ath12k_htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf;
1207 u8 *buf = stats_req->buf;
1208 u32 len = stats_req->buf_len;
1209 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1210
1211 if (tag_len < sizeof(*htt_stats_buf))
1212 return;
1213
1214 len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n");
1215 len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n",
1216 le32_to_cpu(htt_stats_buf->arp_packets));
1217 len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n",
1218 le32_to_cpu(htt_stats_buf->igmp_packets));
1219 len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n",
1220 le32_to_cpu(htt_stats_buf->dhcp_packets));
1221 len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n",
1222 le32_to_cpu(htt_stats_buf->host_inspected));
1223 len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n",
1224 le32_to_cpu(htt_stats_buf->htt_included));
1225 len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n",
1226 le32_to_cpu(htt_stats_buf->htt_valid_mcs));
1227 len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n",
1228 le32_to_cpu(htt_stats_buf->htt_valid_nss));
1229 len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n",
1230 le32_to_cpu(htt_stats_buf->htt_valid_preamble_type));
1231 len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n",
1232 le32_to_cpu(htt_stats_buf->htt_valid_chainmask));
1233 len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n",
1234 le32_to_cpu(htt_stats_buf->htt_valid_guard_interval));
1235 len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n",
1236 le32_to_cpu(htt_stats_buf->htt_valid_retries));
1237 len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n",
1238 le32_to_cpu(htt_stats_buf->htt_valid_bw_info));
1239 len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n",
1240 le32_to_cpu(htt_stats_buf->htt_valid_power));
1241 len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n",
1242 le32_to_cpu(htt_stats_buf->htt_valid_key_flags));
1243 len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n",
1244 le32_to_cpu(htt_stats_buf->htt_valid_no_encryption));
1245 len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n",
1246 le32_to_cpu(htt_stats_buf->fse_entry_count));
1247 len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n",
1248 le32_to_cpu(htt_stats_buf->fse_priority_be));
1249 len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n",
1250 le32_to_cpu(htt_stats_buf->fse_priority_high));
1251 len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n",
1252 le32_to_cpu(htt_stats_buf->fse_priority_low));
1253 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n",
1254 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_be));
1255 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n",
1256 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_over_sub));
1257 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n",
1258 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_bursty));
1259 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n",
1260 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_interactive));
1261 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n",
1262 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_periodic));
1263 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n",
1264 le32_to_cpu(htt_stats_buf->fse_hwqueue_alloc));
1265 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n",
1266 le32_to_cpu(htt_stats_buf->fse_hwqueue_created));
1267 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n",
1268 le32_to_cpu(htt_stats_buf->fse_hwqueue_send_to_host));
1269 len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n",
1270 le32_to_cpu(htt_stats_buf->mcast_entry));
1271 len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n",
1272 le32_to_cpu(htt_stats_buf->bcast_entry));
1273 len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n",
1274 le32_to_cpu(htt_stats_buf->htt_update_peer_cache));
1275 len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n",
1276 le32_to_cpu(htt_stats_buf->htt_learning_frame));
1277 len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n",
1278 le32_to_cpu(htt_stats_buf->fse_invalid_peer));
1279 len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n",
1280 le32_to_cpu(htt_stats_buf->mec_notify));
1281
1282 stats_req->buf_len = len;
1283 }
1284
1285 static void
ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1286 ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u16 tag_len,
1287 struct debug_htt_stats_req *stats_req)
1288 {
1289 const struct ath12k_htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf;
1290 u8 *buf = stats_req->buf;
1291 u32 len = stats_req->buf_len;
1292 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1293
1294 if (tag_len < sizeof(*htt_stats_buf))
1295 return;
1296
1297 len += scnprintf(buf + len, buf_len - len,
1298 "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n");
1299 len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n",
1300 le32_to_cpu(htt_stats_buf->ap_bss_peer_not_found));
1301 len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n",
1302 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_no_peer));
1303 len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n",
1304 le32_to_cpu(htt_stats_buf->sta_delete_in_progress));
1305 len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n",
1306 le32_to_cpu(htt_stats_buf->ibss_no_bss_peer));
1307 len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n",
1308 le32_to_cpu(htt_stats_buf->invalid_vdev_type));
1309 len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n",
1310 le32_to_cpu(htt_stats_buf->invalid_ast_peer_entry));
1311 len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n",
1312 le32_to_cpu(htt_stats_buf->peer_entry_invalid));
1313 len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n",
1314 le32_to_cpu(htt_stats_buf->ethertype_not_ip));
1315 len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n",
1316 le32_to_cpu(htt_stats_buf->eapol_lookup_failed));
1317 len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n",
1318 le32_to_cpu(htt_stats_buf->qpeer_not_allow_data));
1319 len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n",
1320 le32_to_cpu(htt_stats_buf->fse_tid_override));
1321 len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n",
1322 le32_to_cpu(htt_stats_buf->ipv6_jumbogram_zero_length));
1323 len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n",
1324 le32_to_cpu(htt_stats_buf->qos_to_non_qos_in_prog));
1325 len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_eapol = %u\n",
1326 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_eapol));
1327 len += scnprintf(buf + len, buf_len - len, "unicast_on_ap_bss_peer = %u\n",
1328 le32_to_cpu(htt_stats_buf->unicast_on_ap_bss_peer));
1329 len += scnprintf(buf + len, buf_len - len, "ap_vdev_invalid = %u\n",
1330 le32_to_cpu(htt_stats_buf->ap_vdev_invalid));
1331 len += scnprintf(buf + len, buf_len - len, "incomplete_llc = %u\n",
1332 le32_to_cpu(htt_stats_buf->incomplete_llc));
1333 len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m3 = %u\n",
1334 le32_to_cpu(htt_stats_buf->eapol_duplicate_m3));
1335 len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m4 = %u\n\n",
1336 le32_to_cpu(htt_stats_buf->eapol_duplicate_m4));
1337
1338 stats_req->buf_len = len;
1339 }
1340
1341 static void
ath12k_htt_print_tx_de_classify_status_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1342 ath12k_htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u16 tag_len,
1343 struct debug_htt_stats_req *stats_req)
1344 {
1345 const struct ath12k_htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf;
1346 u8 *buf = stats_req->buf;
1347 u32 len = stats_req->buf_len;
1348 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1349
1350 if (tag_len < sizeof(*htt_stats_buf))
1351 return;
1352
1353 len += scnprintf(buf + len, buf_len - len,
1354 "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n");
1355 len += scnprintf(buf + len, buf_len - len, "eok = %u\n",
1356 le32_to_cpu(htt_stats_buf->eok));
1357 len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n",
1358 le32_to_cpu(htt_stats_buf->classify_done));
1359 len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n",
1360 le32_to_cpu(htt_stats_buf->lookup_failed));
1361 len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n",
1362 le32_to_cpu(htt_stats_buf->send_host_dhcp));
1363 len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n",
1364 le32_to_cpu(htt_stats_buf->send_host_mcast));
1365 len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n",
1366 le32_to_cpu(htt_stats_buf->send_host_unknown_dest));
1367 len += scnprintf(buf + len, buf_len - len, "send_host = %u\n",
1368 le32_to_cpu(htt_stats_buf->send_host));
1369 len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n",
1370 le32_to_cpu(htt_stats_buf->status_invalid));
1371
1372 stats_req->buf_len = len;
1373 }
1374
1375 static void
ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1376 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u16 tag_len,
1377 struct debug_htt_stats_req *stats_req)
1378 {
1379 const struct ath12k_htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf;
1380 u8 *buf = stats_req->buf;
1381 u32 len = stats_req->buf_len;
1382 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1383
1384 if (tag_len < sizeof(*htt_stats_buf))
1385 return;
1386
1387 len += scnprintf(buf + len, buf_len - len,
1388 "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n");
1389 len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n",
1390 le32_to_cpu(htt_stats_buf->enqueued_pkts));
1391 len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n",
1392 le32_to_cpu(htt_stats_buf->to_tqm));
1393 len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n",
1394 le32_to_cpu(htt_stats_buf->to_tqm_bypass));
1395
1396 stats_req->buf_len = len;
1397 }
1398
1399 static void
ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1400 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u16 tag_len,
1401 struct debug_htt_stats_req *stats_req)
1402 {
1403 const struct ath12k_htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf;
1404 u8 *buf = stats_req->buf;
1405 u32 len = stats_req->buf_len;
1406 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
1407
1408 if (tag_len < sizeof(*htt_stats_buf))
1409 return;
1410
1411 len += scnprintf(buf + len, buf_len - len,
1412 "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n");
1413 len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n",
1414 le32_to_cpu(htt_stats_buf->discarded_pkts));
1415 len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n",
1416 le32_to_cpu(htt_stats_buf->local_frames));
1417 len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n",
1418 le32_to_cpu(htt_stats_buf->is_ext_msdu));
1419
1420 stats_req->buf_len = len;
1421 }
1422
1423 static void
ath12k_htt_print_tx_de_compl_stats_tlv(const void * tag_buf,u16 tag_len,struct debug_htt_stats_req * stats_req)1424 ath12k_htt_print_tx_de_compl_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_compl_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, "HTT_TX_DE_COMPL_STATS_TLV:\n");
1436 len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n",
1437 le32_to_cpu(htt_stats_buf->tcl_dummy_frame));
1438 len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n",
1439 le32_to_cpu(htt_stats_buf->tqm_dummy_frame));
1440 len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n",
1441 le32_to_cpu(htt_stats_buf->tqm_notify_frame));
1442 len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n",
1443 le32_to_cpu(htt_stats_buf->fw2wbm_enq));
1444 len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n",
1445 le32_to_cpu(htt_stats_buf->tqm_bypass_frame));
1446
1447 stats_req->buf_len = len;
1448 }
1449
ath12k_dbg_htt_ext_stats_parse(struct ath12k_base * ab,u16 tag,u16 len,const void * tag_buf,void * user_data)1450 static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
1451 u16 tag, u16 len, const void *tag_buf,
1452 void *user_data)
1453 {
1454 struct debug_htt_stats_req *stats_req = user_data;
1455
1456 switch (tag) {
1457 case HTT_STATS_TX_PDEV_CMN_TAG:
1458 htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req);
1459 break;
1460 case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
1461 htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req);
1462 break;
1463 case HTT_STATS_TX_PDEV_SIFS_TAG:
1464 htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req);
1465 break;
1466 case HTT_STATS_TX_PDEV_FLUSH_TAG:
1467 htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req);
1468 break;
1469 case HTT_STATS_TX_PDEV_SIFS_HIST_TAG:
1470 htt_print_tx_pdev_stats_sifs_hist_tlv(tag_buf, len, stats_req);
1471 break;
1472 case HTT_STATS_PDEV_CTRL_PATH_TX_STATS_TAG:
1473 htt_print_pdev_ctrl_path_tx_stats_tlv(tag_buf, len, stats_req);
1474 break;
1475 case HTT_STATS_MU_PPDU_DIST_TAG:
1476 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(tag_buf, len, stats_req);
1477 break;
1478 case HTT_STATS_TX_SCHED_CMN_TAG:
1479 ath12k_htt_print_stats_tx_sched_cmn_tlv(tag_buf, len, stats_req);
1480 break;
1481 case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG:
1482 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, len, stats_req);
1483 break;
1484 case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG:
1485 ath12k_htt_print_sched_txq_cmd_posted_tlv(tag_buf, len, stats_req);
1486 break;
1487 case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG:
1488 ath12k_htt_print_sched_txq_cmd_reaped_tlv(tag_buf, len, stats_req);
1489 break;
1490 case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG:
1491 ath12k_htt_print_sched_txq_sched_order_su_tlv(tag_buf, len, stats_req);
1492 break;
1493 case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG:
1494 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(tag_buf, len,
1495 stats_req);
1496 break;
1497 case HTT_STATS_SCHED_TXQ_SUPERCYCLE_TRIGGER_TAG:
1498 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(tag_buf, len,
1499 stats_req);
1500 break;
1501 case HTT_STATS_HW_PDEV_ERRS_TAG:
1502 ath12k_htt_print_hw_stats_pdev_errs_tlv(tag_buf, len, stats_req);
1503 break;
1504 case HTT_STATS_HW_INTR_MISC_TAG:
1505 ath12k_htt_print_hw_stats_intr_misc_tlv(tag_buf, len, stats_req);
1506 break;
1507 case HTT_STATS_WHAL_TX_TAG:
1508 ath12k_htt_print_hw_stats_whal_tx_tlv(tag_buf, len, stats_req);
1509 break;
1510 case HTT_STATS_HW_WAR_TAG:
1511 ath12k_htt_print_hw_war_tlv(tag_buf, len, stats_req);
1512 break;
1513 case HTT_STATS_TX_TQM_CMN_TAG:
1514 ath12k_htt_print_tx_tqm_cmn_stats_tlv(tag_buf, len, stats_req);
1515 break;
1516 case HTT_STATS_TX_TQM_ERROR_STATS_TAG:
1517 ath12k_htt_print_tx_tqm_error_stats_tlv(tag_buf, len, stats_req);
1518 break;
1519 case HTT_STATS_TX_TQM_GEN_MPDU_TAG:
1520 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(tag_buf, len, stats_req);
1521 break;
1522 case HTT_STATS_TX_TQM_LIST_MPDU_TAG:
1523 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(tag_buf, len, stats_req);
1524 break;
1525 case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG:
1526 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(tag_buf, len, stats_req);
1527 break;
1528 case HTT_STATS_TX_TQM_PDEV_TAG:
1529 ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req);
1530 break;
1531 case HTT_STATS_TX_DE_CMN_TAG:
1532 ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req);
1533 break;
1534 case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
1535 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req);
1536 break;
1537 case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
1538 ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req);
1539 break;
1540 case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
1541 ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req);
1542 break;
1543 case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
1544 ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req);
1545 break;
1546 case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
1547 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req);
1548 break;
1549 case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
1550 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req);
1551 break;
1552 case HTT_STATS_TX_DE_COMPL_STATS_TAG:
1553 ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
1554 break;
1555 default:
1556 break;
1557 }
1558
1559 return 0;
1560 }
1561
ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base * ab,struct sk_buff * skb)1562 void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
1563 struct sk_buff *skb)
1564 {
1565 struct ath12k_htt_extd_stats_msg *msg;
1566 struct debug_htt_stats_req *stats_req;
1567 struct ath12k *ar;
1568 u32 len, pdev_id, stats_info;
1569 u64 cookie;
1570 int ret;
1571 bool send_completion = false;
1572
1573 msg = (struct ath12k_htt_extd_stats_msg *)skb->data;
1574 cookie = le64_to_cpu(msg->cookie);
1575
1576 if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) !=
1577 ATH12K_HTT_STATS_MAGIC_VALUE) {
1578 ath12k_warn(ab, "received invalid htt ext stats event\n");
1579 return;
1580 }
1581
1582 pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB);
1583 rcu_read_lock();
1584 ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
1585 if (!ar) {
1586 ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
1587 goto exit;
1588 }
1589
1590 stats_req = ar->debug.htt_stats.stats_req;
1591 if (!stats_req)
1592 goto exit;
1593
1594 spin_lock_bh(&ar->data_lock);
1595
1596 stats_info = le32_to_cpu(msg->info1);
1597 stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE);
1598 if (stats_req->done)
1599 send_completion = true;
1600
1601 spin_unlock_bh(&ar->data_lock);
1602
1603 len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH);
1604 if (len > skb->len) {
1605 ath12k_warn(ab, "invalid length %d for HTT stats", len);
1606 goto exit;
1607 }
1608
1609 ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
1610 ath12k_dbg_htt_ext_stats_parse,
1611 stats_req);
1612 if (ret)
1613 ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
1614
1615 if (send_completion)
1616 complete(&stats_req->htt_stats_rcvd);
1617 exit:
1618 rcu_read_unlock();
1619 }
1620
ath12k_read_htt_stats_type(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1621 static ssize_t ath12k_read_htt_stats_type(struct file *file,
1622 char __user *user_buf,
1623 size_t count, loff_t *ppos)
1624 {
1625 struct ath12k *ar = file->private_data;
1626 enum ath12k_dbg_htt_ext_stats_type type;
1627 char buf[32];
1628 size_t len;
1629
1630 mutex_lock(&ar->conf_mutex);
1631 type = ar->debug.htt_stats.type;
1632 mutex_unlock(&ar->conf_mutex);
1633
1634 len = scnprintf(buf, sizeof(buf), "%u\n", type);
1635
1636 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1637 }
1638
ath12k_write_htt_stats_type(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1639 static ssize_t ath12k_write_htt_stats_type(struct file *file,
1640 const char __user *user_buf,
1641 size_t count, loff_t *ppos)
1642 {
1643 struct ath12k *ar = file->private_data;
1644 enum ath12k_dbg_htt_ext_stats_type type;
1645 unsigned int cfg_param[4] = {0};
1646 const int size = 32;
1647 int num_args;
1648
1649 char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
1650 if (!buf)
1651 return -ENOMEM;
1652
1653 if (copy_from_user(buf, user_buf, count))
1654 return -EFAULT;
1655
1656 num_args = sscanf(buf, "%u %u %u %u %u\n", &type, &cfg_param[0],
1657 &cfg_param[1], &cfg_param[2], &cfg_param[3]);
1658 if (!num_args || num_args > 5)
1659 return -EINVAL;
1660
1661 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET ||
1662 type >= ATH12K_DBG_HTT_NUM_EXT_STATS)
1663 return -EINVAL;
1664
1665 mutex_lock(&ar->conf_mutex);
1666
1667 ar->debug.htt_stats.type = type;
1668 ar->debug.htt_stats.cfg_param[0] = cfg_param[0];
1669 ar->debug.htt_stats.cfg_param[1] = cfg_param[1];
1670 ar->debug.htt_stats.cfg_param[2] = cfg_param[2];
1671 ar->debug.htt_stats.cfg_param[3] = cfg_param[3];
1672
1673 mutex_unlock(&ar->conf_mutex);
1674
1675 return count;
1676 }
1677
1678 static const struct file_operations fops_htt_stats_type = {
1679 .read = ath12k_read_htt_stats_type,
1680 .write = ath12k_write_htt_stats_type,
1681 .open = simple_open,
1682 .owner = THIS_MODULE,
1683 .llseek = default_llseek,
1684 };
1685
ath12k_debugfs_htt_stats_req(struct ath12k * ar)1686 static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
1687 {
1688 struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
1689 enum ath12k_dbg_htt_ext_stats_type type = stats_req->type;
1690 u64 cookie;
1691 int ret, pdev_id;
1692 struct htt_ext_stats_cfg_params cfg_params = { 0 };
1693
1694 lockdep_assert_held(&ar->conf_mutex);
1695
1696 init_completion(&stats_req->htt_stats_rcvd);
1697
1698 pdev_id = ath12k_mac_get_target_pdev_id(ar);
1699 stats_req->done = false;
1700 stats_req->pdev_id = pdev_id;
1701
1702 cookie = u64_encode_bits(ATH12K_HTT_STATS_MAGIC_VALUE,
1703 ATH12K_HTT_STATS_COOKIE_MSB);
1704 cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB);
1705
1706 if (stats_req->override_cfg_param) {
1707 cfg_params.cfg0 = stats_req->cfg_param[0];
1708 cfg_params.cfg1 = stats_req->cfg_param[1];
1709 cfg_params.cfg2 = stats_req->cfg_param[2];
1710 cfg_params.cfg3 = stats_req->cfg_param[3];
1711 }
1712
1713 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
1714 if (ret) {
1715 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
1716 return ret;
1717 }
1718 if (!wait_for_completion_timeout(&stats_req->htt_stats_rcvd, 3 * HZ)) {
1719 spin_lock_bh(&ar->data_lock);
1720 if (!stats_req->done) {
1721 stats_req->done = true;
1722 spin_unlock_bh(&ar->data_lock);
1723 ath12k_warn(ar->ab, "stats request timed out\n");
1724 return -ETIMEDOUT;
1725 }
1726 spin_unlock_bh(&ar->data_lock);
1727 }
1728
1729 return 0;
1730 }
1731
ath12k_open_htt_stats(struct inode * inode,struct file * file)1732 static int ath12k_open_htt_stats(struct inode *inode,
1733 struct file *file)
1734 {
1735 struct ath12k *ar = inode->i_private;
1736 struct debug_htt_stats_req *stats_req;
1737 enum ath12k_dbg_htt_ext_stats_type type = ar->debug.htt_stats.type;
1738 struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1739 int ret;
1740
1741 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET)
1742 return -EPERM;
1743
1744 mutex_lock(&ar->conf_mutex);
1745
1746 if (ah->state != ATH12K_HW_STATE_ON) {
1747 ret = -ENETDOWN;
1748 goto err_unlock;
1749 }
1750
1751 if (ar->debug.htt_stats.stats_req) {
1752 ret = -EAGAIN;
1753 goto err_unlock;
1754 }
1755
1756 stats_req = kzalloc(sizeof(*stats_req) + ATH12K_HTT_STATS_BUF_SIZE, GFP_KERNEL);
1757 if (!stats_req) {
1758 ret = -ENOMEM;
1759 goto err_unlock;
1760 }
1761
1762 ar->debug.htt_stats.stats_req = stats_req;
1763 stats_req->type = type;
1764 stats_req->cfg_param[0] = ar->debug.htt_stats.cfg_param[0];
1765 stats_req->cfg_param[1] = ar->debug.htt_stats.cfg_param[1];
1766 stats_req->cfg_param[2] = ar->debug.htt_stats.cfg_param[2];
1767 stats_req->cfg_param[3] = ar->debug.htt_stats.cfg_param[3];
1768 stats_req->override_cfg_param = !!stats_req->cfg_param[0] ||
1769 !!stats_req->cfg_param[1] ||
1770 !!stats_req->cfg_param[2] ||
1771 !!stats_req->cfg_param[3];
1772
1773 ret = ath12k_debugfs_htt_stats_req(ar);
1774 if (ret < 0)
1775 goto out;
1776
1777 file->private_data = stats_req;
1778
1779 mutex_unlock(&ar->conf_mutex);
1780
1781 return 0;
1782 out:
1783 kfree(stats_req);
1784 ar->debug.htt_stats.stats_req = NULL;
1785 err_unlock:
1786 mutex_unlock(&ar->conf_mutex);
1787
1788 return ret;
1789 }
1790
ath12k_release_htt_stats(struct inode * inode,struct file * file)1791 static int ath12k_release_htt_stats(struct inode *inode,
1792 struct file *file)
1793 {
1794 struct ath12k *ar = inode->i_private;
1795
1796 mutex_lock(&ar->conf_mutex);
1797 kfree(file->private_data);
1798 ar->debug.htt_stats.stats_req = NULL;
1799 mutex_unlock(&ar->conf_mutex);
1800
1801 return 0;
1802 }
1803
ath12k_read_htt_stats(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)1804 static ssize_t ath12k_read_htt_stats(struct file *file,
1805 char __user *user_buf,
1806 size_t count, loff_t *ppos)
1807 {
1808 struct debug_htt_stats_req *stats_req = file->private_data;
1809 char *buf;
1810 u32 length;
1811
1812 buf = stats_req->buf;
1813 length = min_t(u32, stats_req->buf_len, ATH12K_HTT_STATS_BUF_SIZE);
1814 return simple_read_from_buffer(user_buf, count, ppos, buf, length);
1815 }
1816
1817 static const struct file_operations fops_dump_htt_stats = {
1818 .open = ath12k_open_htt_stats,
1819 .release = ath12k_release_htt_stats,
1820 .read = ath12k_read_htt_stats,
1821 .owner = THIS_MODULE,
1822 .llseek = default_llseek,
1823 };
1824
ath12k_write_htt_stats_reset(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)1825 static ssize_t ath12k_write_htt_stats_reset(struct file *file,
1826 const char __user *user_buf,
1827 size_t count, loff_t *ppos)
1828 {
1829 struct ath12k *ar = file->private_data;
1830 enum ath12k_dbg_htt_ext_stats_type type;
1831 struct htt_ext_stats_cfg_params cfg_params = { 0 };
1832 u8 param_pos;
1833 int ret;
1834
1835 ret = kstrtou32_from_user(user_buf, count, 0, &type);
1836 if (ret)
1837 return ret;
1838
1839 if (type >= ATH12K_DBG_HTT_NUM_EXT_STATS ||
1840 type == ATH12K_DBG_HTT_EXT_STATS_RESET)
1841 return -E2BIG;
1842
1843 mutex_lock(&ar->conf_mutex);
1844 cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET;
1845 param_pos = (type >> 5) + 1;
1846
1847 switch (param_pos) {
1848 case ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES:
1849 cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type);
1850 break;
1851 case ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES:
1852 cfg_params.cfg2 = ATH12K_HTT_STATS_RESET_BITMAP32_BIT(cfg_params.cfg0 +
1853 type);
1854 break;
1855 case ATH12K_HTT_STATS_RESET_PARAM_CFG_128_BYTES:
1856 cfg_params.cfg3 = ATH12K_HTT_STATS_RESET_BITMAP64_BIT(cfg_params.cfg0 +
1857 type);
1858 break;
1859 default:
1860 break;
1861 }
1862
1863 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar,
1864 ATH12K_DBG_HTT_EXT_STATS_RESET,
1865 &cfg_params,
1866 0ULL);
1867 if (ret) {
1868 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
1869 mutex_unlock(&ar->conf_mutex);
1870 return ret;
1871 }
1872
1873 ar->debug.htt_stats.reset = type;
1874 mutex_unlock(&ar->conf_mutex);
1875
1876 return count;
1877 }
1878
1879 static const struct file_operations fops_htt_stats_reset = {
1880 .write = ath12k_write_htt_stats_reset,
1881 .open = simple_open,
1882 .owner = THIS_MODULE,
1883 .llseek = default_llseek,
1884 };
1885
ath12k_debugfs_htt_stats_register(struct ath12k * ar)1886 void ath12k_debugfs_htt_stats_register(struct ath12k *ar)
1887 {
1888 debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev,
1889 ar, &fops_htt_stats_type);
1890 debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev,
1891 ar, &fops_dump_htt_stats);
1892 debugfs_create_file("htt_stats_reset", 0200, ar->debug.debugfs_pdev,
1893 ar, &fops_htt_stats_reset);
1894 }
1895