GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / net / wireless / ath / ath11k / debugfs_htt_stats.c
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6
7 #include <linux/vmalloc.h>
8 #include "core.h"
9 #include "dp_tx.h"
10 #include "dp_rx.h"
11 #include "debug.h"
12 #include "debugfs_htt_stats.h"
13
14 #define HTT_MAX_PRINT_CHAR_PER_ELEM 15
15
16 #define HTT_TLV_HDR_LEN 4
17
18 #define PRINT_ARRAY_TO_BUF(out, buflen, arr, str, len, newline)                         \
19         do {                                                                            \
20                 int index = 0; u8 i; const char *str_val = str;                         \
21                 const char *new_line = newline;                                         \
22                 if (str_val) {                                                          \
23                         index += scnprintf((out + buflen),                              \
24                                  (ATH11K_HTT_STATS_BUF_SIZE - buflen),                  \
25                                  "%s = ", str_val);                                     \
26                 }                                                                       \
27                 for (i = 0; i < len; i++) {                                             \
28                         index += scnprintf((out + buflen) + index,                      \
29                                  (ATH11K_HTT_STATS_BUF_SIZE - buflen) - index,          \
30                                  " %u:%u,", i, arr[i]);                                 \
31                 }                                                                       \
32                 index += scnprintf((out + buflen) + index,                              \
33                          (ATH11K_HTT_STATS_BUF_SIZE - buflen) - index,                  \
34                           "%s", new_line);                                              \
35                 buflen += index;                                                        \
36         } while (0)
37
38 static inline void htt_print_stats_string_tlv(const void *tag_buf,
39                                               u16 tag_len,
40                                               struct debug_htt_stats_req *stats_req)
41 {
42         const struct htt_stats_string_tlv *htt_stats_buf = tag_buf;
43         u8 *buf = stats_req->buf;
44         u32 len = stats_req->buf_len;
45         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
46         u8  i;
47
48         tag_len = tag_len >> 2;
49
50         len += scnprintf(buf + len, buf_len - len, "HTT_STATS_STRING_TLV:\n");
51
52         len += scnprintf(buf + len, buf_len - len,
53                          "data = ");
54         for (i = 0; i < tag_len; i++) {
55                 len += scnprintf(buf + len,
56                                  buf_len - len,
57                                  "%.*s", 4, (char *)&(htt_stats_buf->data[i]));
58         }
59         /* New lines are added for better display */
60         len += scnprintf(buf + len, buf_len - len, "\n\n");
61
62         if (len >= buf_len)
63                 buf[buf_len - 1] = 0;
64         else
65                 buf[len] = 0;
66
67         stats_req->buf_len = len;
68 }
69
70 static inline void htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf,
71                                                    struct debug_htt_stats_req *stats_req)
72 {
73         const struct htt_tx_pdev_stats_cmn_tlv *htt_stats_buf = tag_buf;
74         u8 *buf = stats_req->buf;
75         u32 len = stats_req->buf_len;
76         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
77
78         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n");
79         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
80                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
81         len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
82                          htt_stats_buf->hw_queued);
83         len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
84                          htt_stats_buf->hw_reaped);
85         len += scnprintf(buf + len, buf_len - len, "underrun = %u\n",
86                          htt_stats_buf->underrun);
87         len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n",
88                          htt_stats_buf->hw_paused);
89         len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n",
90                          htt_stats_buf->hw_flush);
91         len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n",
92                          htt_stats_buf->hw_filt);
93         len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
94                          htt_stats_buf->tx_abort);
95         len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n",
96                          htt_stats_buf->mpdu_requeued);
97         len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n",
98                          htt_stats_buf->tx_xretry);
99         len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n",
100                          htt_stats_buf->data_rc);
101         len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n",
102                          htt_stats_buf->mpdu_dropped_xretry);
103         len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n",
104                          htt_stats_buf->illgl_rate_phy_err);
105         len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n",
106                          htt_stats_buf->cont_xretry);
107         len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n",
108                          htt_stats_buf->tx_timeout);
109         len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n",
110                          htt_stats_buf->pdev_resets);
111         len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n",
112                          htt_stats_buf->phy_underrun);
113         len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n",
114                          htt_stats_buf->txop_ovf);
115         len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n",
116                          htt_stats_buf->seq_posted);
117         len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n",
118                          htt_stats_buf->seq_failed_queueing);
119         len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n",
120                          htt_stats_buf->seq_completed);
121         len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n",
122                          htt_stats_buf->seq_restarted);
123         len += scnprintf(buf + len, buf_len - len, "mu_seq_posted = %u\n",
124                          htt_stats_buf->mu_seq_posted);
125         len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n",
126                          htt_stats_buf->seq_switch_hw_paused);
127         len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n",
128                          htt_stats_buf->next_seq_posted_dsr);
129         len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n",
130                          htt_stats_buf->seq_posted_isr);
131         len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n",
132                          htt_stats_buf->seq_ctrl_cached);
133         len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n",
134                          htt_stats_buf->mpdu_count_tqm);
135         len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n",
136                          htt_stats_buf->msdu_count_tqm);
137         len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n",
138                          htt_stats_buf->mpdu_removed_tqm);
139         len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n",
140                          htt_stats_buf->msdu_removed_tqm);
141         len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n",
142                          htt_stats_buf->mpdus_sw_flush);
143         len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
144                          htt_stats_buf->mpdus_hw_filter);
145         len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n",
146                          htt_stats_buf->mpdus_truncated);
147         len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n",
148                          htt_stats_buf->mpdus_ack_failed);
149         len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n",
150                          htt_stats_buf->mpdus_expired);
151         len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n",
152                          htt_stats_buf->mpdus_seq_hw_retry);
153         len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
154                          htt_stats_buf->ack_tlv_proc);
155         len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n",
156                          htt_stats_buf->coex_abort_mpdu_cnt_valid);
157         len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n",
158                          htt_stats_buf->coex_abort_mpdu_cnt);
159         len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n",
160                          htt_stats_buf->num_total_ppdus_tried_ota);
161         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n",
162                          htt_stats_buf->num_data_ppdus_tried_ota);
163         len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n",
164                          htt_stats_buf->local_ctrl_mgmt_enqued);
165         len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n",
166                          htt_stats_buf->local_ctrl_mgmt_freed);
167         len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n",
168                          htt_stats_buf->local_data_enqued);
169         len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n",
170                          htt_stats_buf->local_data_freed);
171         len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n",
172                          htt_stats_buf->mpdu_tried);
173         len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n",
174                          htt_stats_buf->isr_wait_seq_posted);
175         len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n",
176                          htt_stats_buf->tx_active_dur_us_low);
177         len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n\n",
178                          htt_stats_buf->tx_active_dur_us_high);
179
180         if (len >= buf_len)
181                 buf[buf_len - 1] = 0;
182         else
183                 buf[len] = 0;
184
185         stats_req->buf_len = len;
186 }
187
188 static inline void
189 htt_print_tx_pdev_stats_urrn_tlv_v(const void *tag_buf,
190                                    u16 tag_len,
191                                    struct debug_htt_stats_req *stats_req)
192 {
193         const struct htt_tx_pdev_stats_urrn_tlv_v *htt_stats_buf = tag_buf;
194         u8 *buf = stats_req->buf;
195         u32 len = stats_req->buf_len;
196         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
197         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_URRN_STATS);
198
199         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_URRN_TLV_V:\n");
200
201         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->urrn_stats, "urrn_stats",
202                            num_elems, "\n\n");
203
204         if (len >= buf_len)
205                 buf[buf_len - 1] = 0;
206         else
207                 buf[len] = 0;
208
209         stats_req->buf_len = len;
210 }
211
212 static inline void
213 htt_print_tx_pdev_stats_flush_tlv_v(const void *tag_buf,
214                                     u16 tag_len,
215                                     struct debug_htt_stats_req *stats_req)
216 {
217         const struct htt_tx_pdev_stats_flush_tlv_v *htt_stats_buf = tag_buf;
218         u8 *buf = stats_req->buf;
219         u32 len = stats_req->buf_len;
220         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
221         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_FLUSH_REASON_STATS);
222
223         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_FLUSH_TLV_V:\n");
224
225         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->flush_errs, "flush_errs",
226                            num_elems, "\n\n");
227
228         if (len >= buf_len)
229                 buf[buf_len - 1] = 0;
230         else
231                 buf[len] = 0;
232
233         stats_req->buf_len = len;
234 }
235
236 static inline void
237 htt_print_tx_pdev_stats_sifs_tlv_v(const void *tag_buf,
238                                    u16 tag_len,
239                                    struct debug_htt_stats_req *stats_req)
240 {
241         const struct htt_tx_pdev_stats_sifs_tlv_v *htt_stats_buf = tag_buf;
242         u8 *buf = stats_req->buf;
243         u32 len = stats_req->buf_len;
244         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
245         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_SIFS_BURST_STATS);
246
247         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_SIFS_TLV_V:\n");
248
249         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sifs_status, "sifs_status",
250                            num_elems, "\n\n");
251
252         if (len >= buf_len)
253                 buf[buf_len - 1] = 0;
254         else
255                 buf[len] = 0;
256
257         stats_req->buf_len = len;
258 }
259
260 static inline void
261 htt_print_tx_pdev_stats_phy_err_tlv_v(const void *tag_buf,
262                                       u16 tag_len,
263                                       struct debug_htt_stats_req *stats_req)
264 {
265         const struct htt_tx_pdev_stats_phy_err_tlv_v *htt_stats_buf = tag_buf;
266         u8 *buf = stats_req->buf;
267         u32 len = stats_req->buf_len;
268         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
269         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_PHY_ERR_STATS);
270
271         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_PHY_ERR_TLV_V:\n");
272
273         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->phy_errs, "phy_errs",
274                            num_elems, "\n\n");
275
276         if (len >= buf_len)
277                 buf[buf_len - 1] = 0;
278         else
279                 buf[len] = 0;
280
281         stats_req->buf_len = len;
282 }
283
284 static inline void
285 htt_print_tx_pdev_stats_sifs_hist_tlv_v(const void *tag_buf,
286                                         u16 tag_len,
287                                         struct debug_htt_stats_req *stats_req)
288 {
289         const struct htt_tx_pdev_stats_sifs_hist_tlv_v *htt_stats_buf = tag_buf;
290         u8 *buf = stats_req->buf;
291         u32 len = stats_req->buf_len;
292         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
293         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS);
294
295         len += scnprintf(buf + len, buf_len - len,
296                          "HTT_TX_PDEV_STATS_SIFS_HIST_TLV_V:\n");
297
298         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sifs_hist_status,
299                            "sifs_hist_status", num_elems, "\n\n");
300
301         if (len >= buf_len)
302                 buf[buf_len - 1] = 0;
303         else
304                 buf[len] = 0;
305
306         stats_req->buf_len = len;
307 }
308
309 static inline void
310 htt_print_tx_pdev_stats_tx_ppdu_stats_tlv_v(const void *tag_buf,
311                                             struct debug_htt_stats_req *stats_req)
312 {
313         const struct htt_tx_pdev_stats_tx_ppdu_stats_tlv_v *htt_stats_buf = tag_buf;
314         u8 *buf = stats_req->buf;
315         u32 len = stats_req->buf_len;
316         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
317
318         len += scnprintf(buf + len, buf_len - len,
319                          "HTT_TX_PDEV_STATS_TX_PPDU_STATS_TLV_V:\n");
320
321         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_legacy_su = %u\n",
322                          htt_stats_buf->num_data_ppdus_legacy_su);
323
324         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ac_su = %u\n",
325                          htt_stats_buf->num_data_ppdus_ac_su);
326
327         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ax_su = %u\n",
328                          htt_stats_buf->num_data_ppdus_ax_su);
329
330         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ac_su_txbf = %u\n",
331                          htt_stats_buf->num_data_ppdus_ac_su_txbf);
332
333         len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_ax_su_txbf = %u\n\n",
334                          htt_stats_buf->num_data_ppdus_ax_su_txbf);
335
336         if (len >= buf_len)
337                 buf[buf_len - 1] = 0;
338         else
339                 buf[len] = 0;
340
341         stats_req->buf_len = len;
342 }
343
344 static inline void
345 htt_print_tx_pdev_stats_tried_mpdu_cnt_hist_tlv_v(const void *tag_buf,
346                                                   u16 tag_len,
347                                                   struct debug_htt_stats_req *stats_req)
348 {
349         const struct htt_tx_pdev_stats_tried_mpdu_cnt_hist_tlv_v *htt_stats_buf = tag_buf;
350         u8 *buf = stats_req->buf;
351         u32 len = stats_req->buf_len;
352         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
353         u32  num_elements = ((tag_len - sizeof(htt_stats_buf->hist_bin_size)) >> 2);
354
355         len += scnprintf(buf + len, buf_len - len,
356                          "HTT_TX_PDEV_STATS_TRIED_MPDU_CNT_HIST_TLV_V:\n");
357         len += scnprintf(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u\n",
358                          htt_stats_buf->hist_bin_size);
359
360         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tried_mpdu_cnt_hist,
361                            "tried_mpdu_cnt_hist", num_elements, "\n\n");
362
363         if (len >= buf_len)
364                 buf[buf_len - 1] = 0;
365         else
366                 buf[len] = 0;
367
368         stats_req->buf_len = len;
369 }
370
371 static inline void htt_print_hw_stats_intr_misc_tlv(const void *tag_buf,
372                                                     struct debug_htt_stats_req *stats_req)
373 {
374         const struct htt_hw_stats_intr_misc_tlv *htt_stats_buf = tag_buf;
375         u8 *buf = stats_req->buf;
376         u32 len = stats_req->buf_len;
377         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
378         char hw_intr_name[HTT_STATS_MAX_HW_INTR_NAME_LEN + 1] = {0};
379
380         len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n");
381         memcpy(hw_intr_name, &(htt_stats_buf->hw_intr_name[0]),
382                HTT_STATS_MAX_HW_INTR_NAME_LEN);
383         len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n", hw_intr_name);
384         len += scnprintf(buf + len, buf_len - len, "mask = %u\n",
385                          htt_stats_buf->mask);
386         len += scnprintf(buf + len, buf_len - len, "count = %u\n\n",
387                          htt_stats_buf->count);
388
389         if (len >= buf_len)
390                 buf[buf_len - 1] = 0;
391         else
392                 buf[len] = 0;
393
394         stats_req->buf_len = len;
395 }
396
397 static inline void
398 htt_print_hw_stats_wd_timeout_tlv(const void *tag_buf,
399                                   struct debug_htt_stats_req *stats_req)
400 {
401         const struct htt_hw_stats_wd_timeout_tlv *htt_stats_buf = tag_buf;
402         u8 *buf = stats_req->buf;
403         u32 len = stats_req->buf_len;
404         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
405         char hw_module_name[HTT_STATS_MAX_HW_MODULE_NAME_LEN + 1] = {0};
406
407         len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WD_TIMEOUT_TLV:\n");
408         memcpy(hw_module_name, &(htt_stats_buf->hw_module_name[0]),
409                HTT_STATS_MAX_HW_MODULE_NAME_LEN);
410         len += scnprintf(buf + len, buf_len - len, "hw_module_name = %s\n",
411                          hw_module_name);
412         len += scnprintf(buf + len, buf_len - len, "count = %u\n",
413                          htt_stats_buf->count);
414
415         if (len >= buf_len)
416                 buf[buf_len - 1] = 0;
417         else
418                 buf[len] = 0;
419
420         stats_req->buf_len = len;
421 }
422
423 static inline void htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf,
424                                                     struct debug_htt_stats_req *stats_req)
425 {
426         const struct htt_hw_stats_pdev_errs_tlv *htt_stats_buf = tag_buf;
427         u8 *buf = stats_req->buf;
428         u32 len = stats_req->buf_len;
429         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
430
431         len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n");
432         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
433                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
434         len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
435                          htt_stats_buf->tx_abort);
436         len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n",
437                          htt_stats_buf->tx_abort_fail_count);
438         len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n",
439                          htt_stats_buf->rx_abort);
440         len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n",
441                          htt_stats_buf->rx_abort_fail_count);
442         len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n",
443                          htt_stats_buf->warm_reset);
444         len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n",
445                          htt_stats_buf->cold_reset);
446         len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n",
447                          htt_stats_buf->tx_flush);
448         len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n",
449                          htt_stats_buf->tx_glb_reset);
450         len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n",
451                          htt_stats_buf->tx_txq_reset);
452         len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n",
453                          htt_stats_buf->rx_timeout_reset);
454
455         if (len >= buf_len)
456                 buf[buf_len - 1] = 0;
457         else
458                 buf[len] = 0;
459
460         stats_req->buf_len = len;
461 }
462
463 static inline void htt_print_msdu_flow_stats_tlv(const void *tag_buf,
464                                                  struct debug_htt_stats_req *stats_req)
465 {
466         const struct htt_msdu_flow_stats_tlv *htt_stats_buf = tag_buf;
467         u8 *buf = stats_req->buf;
468         u32 len = stats_req->buf_len;
469         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
470
471         len += scnprintf(buf + len, buf_len - len, "HTT_MSDU_FLOW_STATS_TLV:\n");
472         len += scnprintf(buf + len, buf_len - len, "last_update_timestamp = %u\n",
473                          htt_stats_buf->last_update_timestamp);
474         len += scnprintf(buf + len, buf_len - len, "last_add_timestamp = %u\n",
475                          htt_stats_buf->last_add_timestamp);
476         len += scnprintf(buf + len, buf_len - len, "last_remove_timestamp = %u\n",
477                          htt_stats_buf->last_remove_timestamp);
478         len += scnprintf(buf + len, buf_len - len, "total_processed_msdu_count = %u\n",
479                          htt_stats_buf->total_processed_msdu_count);
480         len += scnprintf(buf + len, buf_len - len, "cur_msdu_count_in_flowq = %u\n",
481                          htt_stats_buf->cur_msdu_count_in_flowq);
482         len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
483                          htt_stats_buf->sw_peer_id);
484         len += scnprintf(buf + len, buf_len - len, "tx_flow_no = %lu\n",
485                          FIELD_GET(HTT_MSDU_FLOW_STATS_TX_FLOW_NO,
486                                    htt_stats_buf->tx_flow_no__tid_num__drop_rule));
487         len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
488                          FIELD_GET(HTT_MSDU_FLOW_STATS_TID_NUM,
489                                    htt_stats_buf->tx_flow_no__tid_num__drop_rule));
490         len += scnprintf(buf + len, buf_len - len, "drop_rule = %lu\n",
491                          FIELD_GET(HTT_MSDU_FLOW_STATS_DROP_RULE,
492                                    htt_stats_buf->tx_flow_no__tid_num__drop_rule));
493         len += scnprintf(buf + len, buf_len - len, "last_cycle_enqueue_count = %u\n",
494                          htt_stats_buf->last_cycle_enqueue_count);
495         len += scnprintf(buf + len, buf_len - len, "last_cycle_dequeue_count = %u\n",
496                          htt_stats_buf->last_cycle_dequeue_count);
497         len += scnprintf(buf + len, buf_len - len, "last_cycle_drop_count = %u\n",
498                          htt_stats_buf->last_cycle_drop_count);
499         len += scnprintf(buf + len, buf_len - len, "current_drop_th = %u\n\n",
500                          htt_stats_buf->current_drop_th);
501
502         if (len >= buf_len)
503                 buf[buf_len - 1] = 0;
504         else
505                 buf[len] = 0;
506
507         stats_req->buf_len = len;
508 }
509
510 static inline void htt_print_tx_tid_stats_tlv(const void *tag_buf,
511                                               struct debug_htt_stats_req *stats_req)
512 {
513         const struct htt_tx_tid_stats_tlv *htt_stats_buf = tag_buf;
514         u8 *buf = stats_req->buf;
515         u32 len = stats_req->buf_len;
516         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
517         char tid_name[MAX_HTT_TID_NAME + 1] = {0};
518
519         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_TLV:\n");
520         memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
521         len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
522         len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
523                          FIELD_GET(HTT_TX_TID_STATS_SW_PEER_ID,
524                                    htt_stats_buf->sw_peer_id__tid_num));
525         len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
526                          FIELD_GET(HTT_TX_TID_STATS_TID_NUM,
527                                    htt_stats_buf->sw_peer_id__tid_num));
528         len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n",
529                          FIELD_GET(HTT_TX_TID_STATS_NUM_SCHED_PENDING,
530                                    htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
531         len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n",
532                          FIELD_GET(HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ,
533                                    htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
534         len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n",
535                          htt_stats_buf->tid_flags);
536         len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
537                          htt_stats_buf->hw_queued);
538         len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
539                          htt_stats_buf->hw_reaped);
540         len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
541                          htt_stats_buf->mpdus_hw_filter);
542         len += scnprintf(buf + len, buf_len - len, "qdepth_bytes = %u\n",
543                          htt_stats_buf->qdepth_bytes);
544         len += scnprintf(buf + len, buf_len - len, "qdepth_num_msdu = %u\n",
545                          htt_stats_buf->qdepth_num_msdu);
546         len += scnprintf(buf + len, buf_len - len, "qdepth_num_mpdu = %u\n",
547                          htt_stats_buf->qdepth_num_mpdu);
548         len += scnprintf(buf + len, buf_len - len, "last_scheduled_tsmp = %u\n",
549                          htt_stats_buf->last_scheduled_tsmp);
550         len += scnprintf(buf + len, buf_len - len, "pause_module_id = %u\n",
551                          htt_stats_buf->pause_module_id);
552         len += scnprintf(buf + len, buf_len - len, "block_module_id = %u\n\n",
553                          htt_stats_buf->block_module_id);
554
555         if (len >= buf_len)
556                 buf[buf_len - 1] = 0;
557         else
558                 buf[len] = 0;
559
560         stats_req->buf_len = len;
561 }
562
563 static inline void htt_print_tx_tid_stats_v1_tlv(const void *tag_buf,
564                                                  struct debug_htt_stats_req *stats_req)
565 {
566         const struct htt_tx_tid_stats_v1_tlv *htt_stats_buf = tag_buf;
567         u8 *buf = stats_req->buf;
568         u32 len = stats_req->buf_len;
569         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
570         char tid_name[MAX_HTT_TID_NAME + 1] = {0};
571
572         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_V1_TLV:\n");
573         memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
574         len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
575         len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
576                          FIELD_GET(HTT_TX_TID_STATS_V1_SW_PEER_ID,
577                                    htt_stats_buf->sw_peer_id__tid_num));
578         len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
579                          FIELD_GET(HTT_TX_TID_STATS_V1_TID_NUM,
580                                    htt_stats_buf->sw_peer_id__tid_num));
581         len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n",
582                          FIELD_GET(HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING,
583                                    htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
584         len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n",
585                          FIELD_GET(HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ,
586                                    htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
587         len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n",
588                          htt_stats_buf->tid_flags);
589         len += scnprintf(buf + len, buf_len - len, "max_qdepth_bytes = %u\n",
590                          htt_stats_buf->max_qdepth_bytes);
591         len += scnprintf(buf + len, buf_len - len, "max_qdepth_n_msdus = %u\n",
592                          htt_stats_buf->max_qdepth_n_msdus);
593         len += scnprintf(buf + len, buf_len - len, "rsvd = %u\n",
594                          htt_stats_buf->rsvd);
595         len += scnprintf(buf + len, buf_len - len, "qdepth_bytes = %u\n",
596                          htt_stats_buf->qdepth_bytes);
597         len += scnprintf(buf + len, buf_len - len, "qdepth_num_msdu = %u\n",
598                          htt_stats_buf->qdepth_num_msdu);
599         len += scnprintf(buf + len, buf_len - len, "qdepth_num_mpdu = %u\n",
600                          htt_stats_buf->qdepth_num_mpdu);
601         len += scnprintf(buf + len, buf_len - len, "last_scheduled_tsmp = %u\n",
602                          htt_stats_buf->last_scheduled_tsmp);
603         len += scnprintf(buf + len, buf_len - len, "pause_module_id = %u\n",
604                          htt_stats_buf->pause_module_id);
605         len += scnprintf(buf + len, buf_len - len, "block_module_id = %u\n",
606                          htt_stats_buf->block_module_id);
607         len += scnprintf(buf + len, buf_len - len, "allow_n_flags = 0x%x\n",
608                          htt_stats_buf->allow_n_flags);
609         len += scnprintf(buf + len, buf_len - len, "sendn_frms_allowed = %u\n\n",
610                          htt_stats_buf->sendn_frms_allowed);
611
612         if (len >= buf_len)
613                 buf[buf_len - 1] = 0;
614         else
615                 buf[len] = 0;
616
617         stats_req->buf_len = len;
618 }
619
620 static inline void htt_print_rx_tid_stats_tlv(const void *tag_buf,
621                                               struct debug_htt_stats_req *stats_req)
622 {
623         const struct htt_rx_tid_stats_tlv *htt_stats_buf = tag_buf;
624         u8 *buf = stats_req->buf;
625         u32 len = stats_req->buf_len;
626         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
627         char tid_name[MAX_HTT_TID_NAME + 1] = {0};
628
629         len += scnprintf(buf + len, buf_len - len, "HTT_RX_TID_STATS_TLV:\n");
630         len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
631                          FIELD_GET(HTT_RX_TID_STATS_SW_PEER_ID,
632                                    htt_stats_buf->sw_peer_id__tid_num));
633         len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
634                          FIELD_GET(HTT_RX_TID_STATS_TID_NUM,
635                                    htt_stats_buf->sw_peer_id__tid_num));
636         memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
637         len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
638         len += scnprintf(buf + len, buf_len - len, "dup_in_reorder = %u\n",
639                          htt_stats_buf->dup_in_reorder);
640         len += scnprintf(buf + len, buf_len - len, "dup_past_outside_window = %u\n",
641                          htt_stats_buf->dup_past_outside_window);
642         len += scnprintf(buf + len, buf_len - len, "dup_past_within_window = %u\n",
643                          htt_stats_buf->dup_past_within_window);
644         len += scnprintf(buf + len, buf_len - len, "rxdesc_err_decrypt = %u\n\n",
645                          htt_stats_buf->rxdesc_err_decrypt);
646
647         if (len >= buf_len)
648                 buf[buf_len - 1] = 0;
649         else
650                 buf[len] = 0;
651
652         stats_req->buf_len = len;
653 }
654
655 static inline void htt_print_counter_tlv(const void *tag_buf,
656                                          struct debug_htt_stats_req *stats_req)
657 {
658         const struct htt_counter_tlv *htt_stats_buf = tag_buf;
659         u8 *buf = stats_req->buf;
660         u32 len = stats_req->buf_len;
661         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
662
663         len += scnprintf(buf + len, buf_len - len, "HTT_COUNTER_TLV:\n");
664
665         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->counter_name,
666                            "counter_name",
667                            HTT_MAX_COUNTER_NAME, "\n");
668         len += scnprintf(buf + len, buf_len - len, "count = %u\n\n",
669                          htt_stats_buf->count);
670
671         if (len >= buf_len)
672                 buf[buf_len - 1] = 0;
673         else
674                 buf[len] = 0;
675
676         stats_req->buf_len = len;
677 }
678
679 static inline void htt_print_peer_stats_cmn_tlv(const void *tag_buf,
680                                                 struct debug_htt_stats_req *stats_req)
681 {
682         const struct htt_peer_stats_cmn_tlv *htt_stats_buf = tag_buf;
683         u8 *buf = stats_req->buf;
684         u32 len = stats_req->buf_len;
685         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
686
687         len += scnprintf(buf + len, buf_len - len, "HTT_PEER_STATS_CMN_TLV:\n");
688         len += scnprintf(buf + len, buf_len - len, "ppdu_cnt = %u\n",
689                          htt_stats_buf->ppdu_cnt);
690         len += scnprintf(buf + len, buf_len - len, "mpdu_cnt = %u\n",
691                          htt_stats_buf->mpdu_cnt);
692         len += scnprintf(buf + len, buf_len - len, "msdu_cnt = %u\n",
693                          htt_stats_buf->msdu_cnt);
694         len += scnprintf(buf + len, buf_len - len, "pause_bitmap = %u\n",
695                          htt_stats_buf->pause_bitmap);
696         len += scnprintf(buf + len, buf_len - len, "block_bitmap = %u\n",
697                          htt_stats_buf->block_bitmap);
698         len += scnprintf(buf + len, buf_len - len, "last_rssi = %d\n",
699                          htt_stats_buf->rssi);
700         len += scnprintf(buf + len, buf_len - len, "enqueued_count = %llu\n",
701                          htt_stats_buf->peer_enqueued_count_low |
702                          ((u64)htt_stats_buf->peer_enqueued_count_high << 32));
703         len += scnprintf(buf + len, buf_len - len, "dequeued_count = %llu\n",
704                          htt_stats_buf->peer_dequeued_count_low |
705                          ((u64)htt_stats_buf->peer_dequeued_count_high << 32));
706         len += scnprintf(buf + len, buf_len - len, "dropped_count = %llu\n",
707                          htt_stats_buf->peer_dropped_count_low |
708                          ((u64)htt_stats_buf->peer_dropped_count_high << 32));
709         len += scnprintf(buf + len, buf_len - len, "transmitted_ppdu_bytes = %llu\n",
710                          htt_stats_buf->ppdu_transmitted_bytes_low |
711                          ((u64)htt_stats_buf->ppdu_transmitted_bytes_high << 32));
712         len += scnprintf(buf + len, buf_len - len, "ttl_removed_count = %u\n",
713                          htt_stats_buf->peer_ttl_removed_count);
714         len += scnprintf(buf + len, buf_len - len, "inactive_time = %u\n\n",
715                          htt_stats_buf->inactive_time);
716
717         if (len >= buf_len)
718                 buf[buf_len - 1] = 0;
719         else
720                 buf[len] = 0;
721
722         stats_req->buf_len = len;
723 }
724
725 static inline void htt_print_peer_details_tlv(const void *tag_buf,
726                                               struct debug_htt_stats_req *stats_req)
727 {
728         const struct htt_peer_details_tlv *htt_stats_buf = tag_buf;
729         u8 *buf = stats_req->buf;
730         u32 len = stats_req->buf_len;
731         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
732
733         len += scnprintf(buf + len, buf_len - len, "HTT_PEER_DETAILS_TLV:\n");
734         len += scnprintf(buf + len, buf_len - len, "peer_type = %u\n",
735                          htt_stats_buf->peer_type);
736         len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
737                          htt_stats_buf->sw_peer_id);
738         len += scnprintf(buf + len, buf_len - len, "vdev_id = %lu\n",
739                          FIELD_GET(HTT_PEER_DETAILS_VDEV_ID,
740                                    htt_stats_buf->vdev_pdev_ast_idx));
741         len += scnprintf(buf + len, buf_len - len, "pdev_id = %lu\n",
742                          FIELD_GET(HTT_PEER_DETAILS_PDEV_ID,
743                                    htt_stats_buf->vdev_pdev_ast_idx));
744         len += scnprintf(buf + len, buf_len - len, "ast_idx = %lu\n",
745                          FIELD_GET(HTT_PEER_DETAILS_AST_IDX,
746                                    htt_stats_buf->vdev_pdev_ast_idx));
747         len += scnprintf(buf + len, buf_len - len,
748                          "mac_addr = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
749                          FIELD_GET(HTT_MAC_ADDR_L32_0,
750                                    htt_stats_buf->mac_addr.mac_addr_l32),
751                          FIELD_GET(HTT_MAC_ADDR_L32_1,
752                                    htt_stats_buf->mac_addr.mac_addr_l32),
753                          FIELD_GET(HTT_MAC_ADDR_L32_2,
754                                    htt_stats_buf->mac_addr.mac_addr_l32),
755                          FIELD_GET(HTT_MAC_ADDR_L32_3,
756                                    htt_stats_buf->mac_addr.mac_addr_l32),
757                          FIELD_GET(HTT_MAC_ADDR_H16_0,
758                                    htt_stats_buf->mac_addr.mac_addr_h16),
759                          FIELD_GET(HTT_MAC_ADDR_H16_1,
760                                    htt_stats_buf->mac_addr.mac_addr_h16));
761         len += scnprintf(buf + len, buf_len - len, "peer_flags = 0x%x\n",
762                          htt_stats_buf->peer_flags);
763         len += scnprintf(buf + len, buf_len - len, "qpeer_flags = 0x%x\n\n",
764                          htt_stats_buf->qpeer_flags);
765
766         if (len >= buf_len)
767                 buf[buf_len - 1] = 0;
768         else
769                 buf[len] = 0;
770
771         stats_req->buf_len = len;
772 }
773
774 static inline void htt_print_tx_peer_rate_stats_tlv(const void *tag_buf,
775                                                     struct debug_htt_stats_req *stats_req)
776 {
777         const struct htt_tx_peer_rate_stats_tlv *htt_stats_buf = tag_buf;
778         u8 *buf = stats_req->buf;
779         u32 len = stats_req->buf_len;
780         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
781         u8 j;
782
783         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PEER_RATE_STATS_TLV:\n");
784         len += scnprintf(buf + len, buf_len - len, "tx_ldpc = %u\n",
785                          htt_stats_buf->tx_ldpc);
786         len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n",
787                          htt_stats_buf->rts_cnt);
788         len += scnprintf(buf + len, buf_len - len, "ack_rssi = %u\n",
789                          htt_stats_buf->ack_rssi);
790
791         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mcs, "tx_mcs",
792                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
793         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_su_mcs, "tx_su_mcs",
794                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
795         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mu_mcs, "tx_mu_mcs",
796                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
797         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_nss, "tx_nss",
798                            HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
799         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_bw, "tx_bw",
800                            HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
801         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_stbc, "tx_stbc",
802                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
803         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_pream, "tx_pream",
804                            HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n");
805
806         for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) {
807                 len += scnprintf(buf + len, buf_len - len,
808                                  "tx_gi[%u] = ", j);
809                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_gi[j], NULL,
810                                    HTT_TX_PEER_STATS_NUM_MCS_COUNTERS, "\n");
811         }
812
813         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_dcm, "tx_dcm",
814                            HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS, "\n\n");
815
816         if (len >= buf_len)
817                 buf[buf_len - 1] = 0;
818         else
819                 buf[len] = 0;
820
821         stats_req->buf_len = len;
822 }
823
824 static inline void htt_print_rx_peer_rate_stats_tlv(const void *tag_buf,
825                                                     struct debug_htt_stats_req *stats_req)
826 {
827         const struct htt_rx_peer_rate_stats_tlv *htt_stats_buf = tag_buf;
828         u8 *buf = stats_req->buf;
829         u32 len = stats_req->buf_len;
830         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
831         u8 j;
832
833         len += scnprintf(buf + len, buf_len - len, "HTT_RX_PEER_RATE_STATS_TLV:\n");
834         len += scnprintf(buf + len, buf_len - len, "nsts = %u\n",
835                          htt_stats_buf->nsts);
836         len += scnprintf(buf + len, buf_len - len, "rx_ldpc = %u\n",
837                          htt_stats_buf->rx_ldpc);
838         len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n",
839                          htt_stats_buf->rts_cnt);
840         len += scnprintf(buf + len, buf_len - len, "rssi_mgmt = %u\n",
841                          htt_stats_buf->rssi_mgmt);
842         len += scnprintf(buf + len, buf_len - len, "rssi_data = %u\n",
843                          htt_stats_buf->rssi_data);
844         len += scnprintf(buf + len, buf_len - len, "rssi_comb = %u\n",
845                          htt_stats_buf->rssi_comb);
846
847         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_mcs, "rx_mcs",
848                            HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
849         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_nss, "rx_nss",
850                            HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
851         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_dcm, "rx_dcm",
852                            HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS, "\n");
853         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_stbc, "rx_stbc",
854                            HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
855         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_bw, "rx_bw",
856                            HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
857
858         for (j = 0; j < HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS; j++) {
859                 len += scnprintf(buf + len, (buf_len - len),
860                                  "rssi_chain[%u] = ", j);
861                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rssi_chain[j], NULL,
862                                    HTT_RX_PEER_STATS_NUM_BW_COUNTERS, "\n");
863         }
864
865         for (j = 0; j < HTT_RX_PEER_STATS_NUM_GI_COUNTERS; j++) {
866                 len += scnprintf(buf + len, (buf_len - len),
867                                  "rx_gi[%u] = ", j);
868                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_gi[j], NULL,
869                                    HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
870         }
871
872         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_pream, "rx_pream",
873                            HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n");
874
875         if (len >= buf_len)
876                 buf[buf_len - 1] = 0;
877         else
878                 buf[len] = 0;
879
880         stats_req->buf_len = len;
881 }
882
883 static inline void
884 htt_print_tx_hwq_mu_mimo_sch_stats_tlv(const void *tag_buf,
885                                        struct debug_htt_stats_req *stats_req)
886 {
887         const struct htt_tx_hwq_mu_mimo_sch_stats_tlv *htt_stats_buf = tag_buf;
888         u8 *buf = stats_req->buf;
889         u32 len = stats_req->buf_len;
890         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
891
892         len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_SCH_STATS_TLV:\n");
893         len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n",
894                          htt_stats_buf->mu_mimo_sch_posted);
895         len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n",
896                          htt_stats_buf->mu_mimo_sch_failed);
897         len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n\n",
898                          htt_stats_buf->mu_mimo_ppdu_posted);
899
900         if (len >= buf_len)
901                 buf[buf_len - 1] = 0;
902         else
903                 buf[len] = 0;
904
905         stats_req->buf_len = len;
906 }
907
908 static inline void
909 htt_print_tx_hwq_mu_mimo_mpdu_stats_tlv(const void *tag_buf,
910                                         struct debug_htt_stats_req *stats_req)
911 {
912         const struct htt_tx_hwq_mu_mimo_mpdu_stats_tlv *htt_stats_buf = tag_buf;
913         u8 *buf = stats_req->buf;
914         u32 len = stats_req->buf_len;
915         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
916
917         len += scnprintf(buf + len, buf_len - len,
918                          "HTT_TX_HWQ_MU_MIMO_MPDU_STATS_TLV:\n");
919         len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_queued_usr = %u\n",
920                          htt_stats_buf->mu_mimo_mpdus_queued_usr);
921         len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_tried_usr = %u\n",
922                          htt_stats_buf->mu_mimo_mpdus_tried_usr);
923         len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_failed_usr = %u\n",
924                          htt_stats_buf->mu_mimo_mpdus_failed_usr);
925         len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdus_requeued_usr = %u\n",
926                          htt_stats_buf->mu_mimo_mpdus_requeued_usr);
927         len += scnprintf(buf + len, buf_len - len, "mu_mimo_err_no_ba_usr = %u\n",
928                          htt_stats_buf->mu_mimo_err_no_ba_usr);
929         len += scnprintf(buf + len, buf_len - len, "mu_mimo_mpdu_underrun_usr = %u\n",
930                          htt_stats_buf->mu_mimo_mpdu_underrun_usr);
931         len += scnprintf(buf + len, buf_len - len, "mu_mimo_ampdu_underrun_usr = %u\n\n",
932                          htt_stats_buf->mu_mimo_ampdu_underrun_usr);
933
934         if (len >= buf_len)
935                 buf[buf_len - 1] = 0;
936         else
937                 buf[len] = 0;
938
939         stats_req->buf_len = len;
940 }
941
942 static inline void
943 htt_print_tx_hwq_mu_mimo_cmn_stats_tlv(const void *tag_buf,
944                                        struct debug_htt_stats_req *stats_req)
945 {
946         const struct htt_tx_hwq_mu_mimo_cmn_stats_tlv *htt_stats_buf = tag_buf;
947         u8 *buf = stats_req->buf;
948         u32 len = stats_req->buf_len;
949         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
950
951         len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_CMN_STATS_TLV:\n");
952         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
953                          FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID,
954                                    htt_stats_buf->mac_id__hwq_id__word));
955         len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n\n",
956                          FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID,
957                                    htt_stats_buf->mac_id__hwq_id__word));
958
959         if (len >= buf_len)
960                 buf[buf_len - 1] = 0;
961         else
962                 buf[len] = 0;
963
964         stats_req->buf_len = len;
965 }
966
967 static inline void
968 htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, struct debug_htt_stats_req *stats_req)
969 {
970         const struct htt_tx_hwq_stats_cmn_tlv *htt_stats_buf = tag_buf;
971         u8 *buf = stats_req->buf;
972         u32 len = stats_req->buf_len;
973         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
974
975         /* TODO: HKDBG */
976         len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n");
977         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
978                          FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID,
979                                    htt_stats_buf->mac_id__hwq_id__word));
980         len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n",
981                          FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID,
982                                    htt_stats_buf->mac_id__hwq_id__word));
983         len += scnprintf(buf + len, buf_len - len, "xretry = %u\n",
984                          htt_stats_buf->xretry);
985         len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n",
986                          htt_stats_buf->underrun_cnt);
987         len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n",
988                          htt_stats_buf->flush_cnt);
989         len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n",
990                          htt_stats_buf->filt_cnt);
991         len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n",
992                          htt_stats_buf->null_mpdu_bmap);
993         len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n",
994                          htt_stats_buf->user_ack_failure);
995         len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
996                          htt_stats_buf->ack_tlv_proc);
997         len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n",
998                          htt_stats_buf->sched_id_proc);
999         len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n",
1000                          htt_stats_buf->null_mpdu_tx_count);
1001         len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n",
1002                          htt_stats_buf->mpdu_bmap_not_recvd);
1003         len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n",
1004                          htt_stats_buf->num_bar);
1005         len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
1006                          htt_stats_buf->rts);
1007         len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
1008                          htt_stats_buf->cts2self);
1009         len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
1010                          htt_stats_buf->qos_null);
1011         len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n",
1012                          htt_stats_buf->mpdu_tried_cnt);
1013         len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n",
1014                          htt_stats_buf->mpdu_queued_cnt);
1015         len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n",
1016                          htt_stats_buf->mpdu_ack_fail_cnt);
1017         len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n",
1018                          htt_stats_buf->mpdu_filt_cnt);
1019         len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n",
1020                          htt_stats_buf->false_mpdu_ack_count);
1021         len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n\n",
1022                          htt_stats_buf->txq_timeout);
1023
1024         if (len >= buf_len)
1025                 buf[buf_len - 1] = 0;
1026         else
1027                 buf[len] = 0;
1028
1029         stats_req->buf_len = len;
1030 }
1031
1032 static inline void
1033 htt_print_tx_hwq_difs_latency_stats_tlv_v(const void *tag_buf,
1034                                           u16 tag_len,
1035                                           struct debug_htt_stats_req *stats_req)
1036 {
1037         const struct htt_tx_hwq_difs_latency_stats_tlv_v *htt_stats_buf = tag_buf;
1038         u8 *buf = stats_req->buf;
1039         u32 len = stats_req->buf_len;
1040         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1041         u16 data_len = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_DIFS_LATENCY_BINS);
1042
1043         len += scnprintf(buf + len, buf_len - len,
1044                          "HTT_TX_HWQ_DIFS_LATENCY_STATS_TLV_V:\n");
1045         len += scnprintf(buf + len, buf_len - len, "hist_intvl = %u\n",
1046                          htt_stats_buf->hist_intvl);
1047
1048         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->difs_latency_hist,
1049                            "difs_latency_hist", data_len, "\n\n");
1050
1051         if (len >= buf_len)
1052                 buf[buf_len - 1] = 0;
1053         else
1054                 buf[len] = 0;
1055
1056         stats_req->buf_len = len;
1057 }
1058
1059 static inline void
1060 htt_print_tx_hwq_cmd_result_stats_tlv_v(const void *tag_buf,
1061                                         u16 tag_len,
1062                                         struct debug_htt_stats_req *stats_req)
1063 {
1064         const struct htt_tx_hwq_cmd_result_stats_tlv_v *htt_stats_buf = tag_buf;
1065         u8 *buf = stats_req->buf;
1066         u32 len = stats_req->buf_len;
1067         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1068         u16 data_len;
1069
1070         data_len = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_CMD_RESULT_STATS);
1071
1072         len += scnprintf(buf + len, buf_len - len,
1073                          "HTT_TX_HWQ_CMD_RESULT_STATS_TLV_V:\n");
1074
1075         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->cmd_result, "cmd_result",
1076                            data_len, "\n\n");
1077
1078         if (len >= buf_len)
1079                 buf[buf_len - 1] = 0;
1080         else
1081                 buf[len] = 0;
1082
1083         stats_req->buf_len = len;
1084 }
1085
1086 static inline void
1087 htt_print_tx_hwq_cmd_stall_stats_tlv_v(const void *tag_buf,
1088                                        u16 tag_len,
1089                                        struct debug_htt_stats_req *stats_req)
1090 {
1091         const struct htt_tx_hwq_cmd_stall_stats_tlv_v *htt_stats_buf = tag_buf;
1092         u8 *buf = stats_req->buf;
1093         u32 len = stats_req->buf_len;
1094         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1095         u16 num_elems;
1096
1097         num_elems = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_CMD_STALL_STATS);
1098
1099         len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_CMD_STALL_STATS_TLV_V:\n");
1100
1101         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->cmd_stall_status,
1102                            "cmd_stall_status", num_elems, "\n\n");
1103
1104         if (len >= buf_len)
1105                 buf[buf_len - 1] = 0;
1106         else
1107                 buf[len] = 0;
1108
1109         stats_req->buf_len = len;
1110 }
1111
1112 static inline void
1113 htt_print_tx_hwq_fes_result_stats_tlv_v(const void *tag_buf,
1114                                         u16 tag_len,
1115                                         struct debug_htt_stats_req *stats_req)
1116 {
1117         const struct htt_tx_hwq_fes_result_stats_tlv_v *htt_stats_buf = tag_buf;
1118         u8 *buf = stats_req->buf;
1119         u32 len = stats_req->buf_len;
1120         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1121         u16 num_elems;
1122
1123         num_elems = min_t(u16, (tag_len >> 2), HTT_TX_HWQ_MAX_FES_RESULT_STATS);
1124
1125         len += scnprintf(buf + len, buf_len - len,
1126                          "HTT_TX_HWQ_FES_RESULT_STATS_TLV_V:\n");
1127
1128         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fes_result, "fes_result",
1129                            num_elems, "\n\n");
1130
1131         if (len >= buf_len)
1132                 buf[buf_len - 1] = 0;
1133         else
1134                 buf[len] = 0;
1135
1136         stats_req->buf_len = len;
1137 }
1138
1139 static inline void
1140 htt_print_tx_hwq_tried_mpdu_cnt_hist_tlv_v(const void *tag_buf,
1141                                            u16 tag_len,
1142                                            struct debug_htt_stats_req *stats_req)
1143 {
1144         const struct htt_tx_hwq_tried_mpdu_cnt_hist_tlv_v *htt_stats_buf = tag_buf;
1145         u8 *buf = stats_req->buf;
1146         u32 len = stats_req->buf_len;
1147         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1148         u32  num_elements = ((tag_len -
1149                             sizeof(htt_stats_buf->hist_bin_size)) >> 2);
1150
1151         len += scnprintf(buf + len, buf_len - len,
1152                          "HTT_TX_HWQ_TRIED_MPDU_CNT_HIST_TLV_V:\n");
1153         len += scnprintf(buf + len, buf_len - len, "TRIED_MPDU_CNT_HIST_BIN_SIZE : %u\n",
1154                          htt_stats_buf->hist_bin_size);
1155
1156         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tried_mpdu_cnt_hist,
1157                            "tried_mpdu_cnt_hist", num_elements, "\n\n");
1158
1159         if (len >= buf_len)
1160                 buf[buf_len - 1] = 0;
1161         else
1162                 buf[len] = 0;
1163
1164         stats_req->buf_len = len;
1165 }
1166
1167 static inline void
1168 htt_print_tx_hwq_txop_used_cnt_hist_tlv_v(const void *tag_buf,
1169                                           u16 tag_len,
1170                                           struct debug_htt_stats_req *stats_req)
1171 {
1172         const struct htt_tx_hwq_txop_used_cnt_hist_tlv_v *htt_stats_buf = tag_buf;
1173         u8 *buf = stats_req->buf;
1174         u32 len = stats_req->buf_len;
1175         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1176         u32 num_elements = tag_len >> 2;
1177
1178         len += scnprintf(buf + len, buf_len - len,
1179                          "HTT_TX_HWQ_TXOP_USED_CNT_HIST_TLV_V:\n");
1180
1181         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->txop_used_cnt_hist,
1182                            "txop_used_cnt_hist", num_elements, "\n\n");
1183
1184         if (len >= buf_len)
1185                 buf[buf_len - 1] = 0;
1186         else
1187                 buf[len] = 0;
1188
1189         stats_req->buf_len = len;
1190 }
1191
1192 static inline void htt_print_tx_sounding_stats_tlv(const void *tag_buf,
1193                                                    struct debug_htt_stats_req *stats_req)
1194 {
1195         s32 i;
1196         const struct htt_tx_sounding_stats_tlv *htt_stats_buf = tag_buf;
1197         u8 *buf = stats_req->buf;
1198         u32 len = stats_req->buf_len;
1199         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1200         const u32 *cbf_20 = htt_stats_buf->cbf_20;
1201         const u32 *cbf_40 = htt_stats_buf->cbf_40;
1202         const u32 *cbf_80 = htt_stats_buf->cbf_80;
1203         const u32 *cbf_160 = htt_stats_buf->cbf_160;
1204
1205         if (htt_stats_buf->tx_sounding_mode == HTT_TX_AC_SOUNDING_MODE) {
1206                 len += scnprintf(buf + len, buf_len - len,
1207                                  "\nHTT_TX_AC_SOUNDING_STATS_TLV:\n\n");
1208                 len += scnprintf(buf + len, buf_len - len,
1209                                  "ac_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1210                                  cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS],
1211                                  cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1212                                  cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1213                                  cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1214                                  cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1215                 len += scnprintf(buf + len, buf_len - len,
1216                                  "ac_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1217                                  cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS],
1218                                  cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1219                                  cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1220                                  cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1221                                  cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1222                 len += scnprintf(buf + len, buf_len - len,
1223                                  "ac_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1224                                  cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS],
1225                                  cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1226                                  cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1227                                  cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1228                                  cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1229                 len += scnprintf(buf + len, buf_len - len,
1230                                  "ac_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1231                                  cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS],
1232                                  cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1233                                  cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1234                                  cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1235                                  cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1236
1237                 for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++) {
1238                         len += scnprintf(buf + len, buf_len - len,
1239                                          "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u\n",
1240                                          i,
1241                                          htt_stats_buf->sounding[0],
1242                                          htt_stats_buf->sounding[1],
1243                                          htt_stats_buf->sounding[2],
1244                                          htt_stats_buf->sounding[3]);
1245                 }
1246         } else if (htt_stats_buf->tx_sounding_mode == HTT_TX_AX_SOUNDING_MODE) {
1247                 len += scnprintf(buf + len, buf_len - len,
1248                                  "\nHTT_TX_AX_SOUNDING_STATS_TLV:\n");
1249                 len += scnprintf(buf + len, buf_len - len,
1250                                  "ax_cbf_20 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1251                                  cbf_20[HTT_IMPLICIT_TXBF_STEER_STATS],
1252                                  cbf_20[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1253                                  cbf_20[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1254                                  cbf_20[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1255                                  cbf_20[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1256                 len += scnprintf(buf + len, buf_len - len,
1257                                  "ax_cbf_40 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1258                                  cbf_40[HTT_IMPLICIT_TXBF_STEER_STATS],
1259                                  cbf_40[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1260                                  cbf_40[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1261                                  cbf_40[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1262                                  cbf_40[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1263                 len += scnprintf(buf + len, buf_len - len,
1264                                  "ax_cbf_80 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1265                                  cbf_80[HTT_IMPLICIT_TXBF_STEER_STATS],
1266                                  cbf_80[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1267                                  cbf_80[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1268                                  cbf_80[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1269                                  cbf_80[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1270                 len += scnprintf(buf + len, buf_len - len,
1271                                  "ax_cbf_160 = IBF : %u, SU_SIFS : %u, SU_RBO : %u, MU_SIFS : %u, MU_RBO : %u\n",
1272                                  cbf_160[HTT_IMPLICIT_TXBF_STEER_STATS],
1273                                  cbf_160[HTT_EXPLICIT_TXBF_SU_SIFS_STEER_STATS],
1274                                  cbf_160[HTT_EXPLICIT_TXBF_SU_RBO_STEER_STATS],
1275                                  cbf_160[HTT_EXPLICIT_TXBF_MU_SIFS_STEER_STATS],
1276                                  cbf_160[HTT_EXPLICIT_TXBF_MU_RBO_STEER_STATS]);
1277
1278                 for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++) {
1279                         len += scnprintf(buf + len, buf_len - len,
1280                                          "Sounding User %u = 20MHz: %u, 40MHz : %u, 80MHz: %u, 160MHz: %u\n",
1281                                          i,
1282                                          htt_stats_buf->sounding[0],
1283                                          htt_stats_buf->sounding[1],
1284                                          htt_stats_buf->sounding[2],
1285                                          htt_stats_buf->sounding[3]);
1286                 }
1287         }
1288
1289         if (len >= buf_len)
1290                 buf[buf_len - 1] = 0;
1291         else
1292                 buf[len] = 0;
1293
1294         stats_req->buf_len = len;
1295 }
1296
1297 static inline void
1298 htt_print_tx_selfgen_cmn_stats_tlv(const void *tag_buf,
1299                                    struct debug_htt_stats_req *stats_req)
1300 {
1301         const struct htt_tx_selfgen_cmn_stats_tlv *htt_stats_buf = tag_buf;
1302         u8 *buf = stats_req->buf;
1303         u32 len = stats_req->buf_len;
1304         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1305
1306         len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:\n");
1307         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
1308                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
1309         len += scnprintf(buf + len, buf_len - len, "su_bar = %u\n",
1310                          htt_stats_buf->su_bar);
1311         len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
1312                          htt_stats_buf->rts);
1313         len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
1314                          htt_stats_buf->cts2self);
1315         len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
1316                          htt_stats_buf->qos_null);
1317         len += scnprintf(buf + len, buf_len - len, "delayed_bar_1 = %u\n",
1318                          htt_stats_buf->delayed_bar_1);
1319         len += scnprintf(buf + len, buf_len - len, "delayed_bar_2 = %u\n",
1320                          htt_stats_buf->delayed_bar_2);
1321         len += scnprintf(buf + len, buf_len - len, "delayed_bar_3 = %u\n",
1322                          htt_stats_buf->delayed_bar_3);
1323         len += scnprintf(buf + len, buf_len - len, "delayed_bar_4 = %u\n",
1324                          htt_stats_buf->delayed_bar_4);
1325         len += scnprintf(buf + len, buf_len - len, "delayed_bar_5 = %u\n",
1326                          htt_stats_buf->delayed_bar_5);
1327         len += scnprintf(buf + len, buf_len - len, "delayed_bar_6 = %u\n",
1328                          htt_stats_buf->delayed_bar_6);
1329         len += scnprintf(buf + len, buf_len - len, "delayed_bar_7 = %u\n\n",
1330                          htt_stats_buf->delayed_bar_7);
1331
1332         if (len >= buf_len)
1333                 buf[buf_len - 1] = 0;
1334         else
1335                 buf[len] = 0;
1336
1337         stats_req->buf_len = len;
1338 }
1339
1340 static inline void
1341 htt_print_tx_selfgen_ac_stats_tlv(const void *tag_buf,
1342                                   struct debug_htt_stats_req *stats_req)
1343 {
1344         const struct htt_tx_selfgen_ac_stats_tlv *htt_stats_buf = tag_buf;
1345         u8 *buf = stats_req->buf;
1346         u32 len = stats_req->buf_len;
1347         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1348
1349         len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_STATS_TLV:\n");
1350         len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa = %u\n",
1351                          htt_stats_buf->ac_su_ndpa);
1352         len += scnprintf(buf + len, buf_len - len, "ac_su_ndp = %u\n",
1353                          htt_stats_buf->ac_su_ndp);
1354         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa = %u\n",
1355                          htt_stats_buf->ac_mu_mimo_ndpa);
1356         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp = %u\n",
1357                          htt_stats_buf->ac_mu_mimo_ndp);
1358         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_1 = %u\n",
1359                          htt_stats_buf->ac_mu_mimo_brpoll_1);
1360         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_2 = %u\n",
1361                          htt_stats_buf->ac_mu_mimo_brpoll_2);
1362         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brpoll_3 = %u\n\n",
1363                          htt_stats_buf->ac_mu_mimo_brpoll_3);
1364
1365         if (len >= buf_len)
1366                 buf[buf_len - 1] = 0;
1367         else
1368                 buf[len] = 0;
1369
1370         stats_req->buf_len = len;
1371 }
1372
1373 static inline void
1374 htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf,
1375                                   struct debug_htt_stats_req *stats_req)
1376 {
1377         const struct htt_tx_selfgen_ax_stats_tlv *htt_stats_buf = tag_buf;
1378         u8 *buf = stats_req->buf;
1379         u32 len = stats_req->buf_len;
1380         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1381
1382         len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_STATS_TLV:\n");
1383         len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa = %u\n",
1384                          htt_stats_buf->ax_su_ndpa);
1385         len += scnprintf(buf + len, buf_len - len, "ax_su_ndp = %u\n",
1386                          htt_stats_buf->ax_su_ndp);
1387         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa = %u\n",
1388                          htt_stats_buf->ax_mu_mimo_ndpa);
1389         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp = %u\n",
1390                          htt_stats_buf->ax_mu_mimo_ndp);
1391         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_1 = %u\n",
1392                          htt_stats_buf->ax_mu_mimo_brpoll_1);
1393         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_2 = %u\n",
1394                          htt_stats_buf->ax_mu_mimo_brpoll_2);
1395         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_3 = %u\n",
1396                          htt_stats_buf->ax_mu_mimo_brpoll_3);
1397         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_4 = %u\n",
1398                          htt_stats_buf->ax_mu_mimo_brpoll_4);
1399         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_5 = %u\n",
1400                          htt_stats_buf->ax_mu_mimo_brpoll_5);
1401         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_6 = %u\n",
1402                          htt_stats_buf->ax_mu_mimo_brpoll_6);
1403         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brpoll_7 = %u\n",
1404                          htt_stats_buf->ax_mu_mimo_brpoll_7);
1405         len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n",
1406                          htt_stats_buf->ax_basic_trigger);
1407         len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_trigger = %u\n",
1408                          htt_stats_buf->ax_ulmumimo_trigger);
1409         len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n",
1410                          htt_stats_buf->ax_bsr_trigger);
1411         len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n",
1412                          htt_stats_buf->ax_mu_bar_trigger);
1413         len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger = %u\n\n",
1414                          htt_stats_buf->ax_mu_rts_trigger);
1415
1416         if (len >= buf_len)
1417                 buf[buf_len - 1] = 0;
1418         else
1419                 buf[len] = 0;
1420
1421         stats_req->buf_len = len;
1422 }
1423
1424 static inline void
1425 htt_print_tx_selfgen_ac_err_stats_tlv(const void *tag_buf,
1426                                       struct debug_htt_stats_req *stats_req)
1427 {
1428         const struct htt_tx_selfgen_ac_err_stats_tlv *htt_stats_buf = tag_buf;
1429         u8 *buf = stats_req->buf;
1430         u32 len = stats_req->buf_len;
1431         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1432
1433         len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AC_ERR_STATS_TLV:\n");
1434         len += scnprintf(buf + len, buf_len - len, "ac_su_ndp_err = %u\n",
1435                          htt_stats_buf->ac_su_ndp_err);
1436         len += scnprintf(buf + len, buf_len - len, "ac_su_ndpa_err = %u\n",
1437                          htt_stats_buf->ac_su_ndpa_err);
1438         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndpa_err = %u\n",
1439                          htt_stats_buf->ac_mu_mimo_ndpa_err);
1440         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_ndp_err = %u\n",
1441                          htt_stats_buf->ac_mu_mimo_ndp_err);
1442         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp1_err = %u\n",
1443                          htt_stats_buf->ac_mu_mimo_brp1_err);
1444         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp2_err = %u\n",
1445                          htt_stats_buf->ac_mu_mimo_brp2_err);
1446         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_brp3_err = %u\n\n",
1447                          htt_stats_buf->ac_mu_mimo_brp3_err);
1448
1449         if (len >= buf_len)
1450                 buf[buf_len - 1] = 0;
1451         else
1452                 buf[len] = 0;
1453
1454         stats_req->buf_len = len;
1455 }
1456
1457 static inline void
1458 htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf,
1459                                       struct debug_htt_stats_req *stats_req)
1460 {
1461         const struct htt_tx_selfgen_ax_err_stats_tlv *htt_stats_buf = tag_buf;
1462         u8 *buf = stats_req->buf;
1463         u32 len = stats_req->buf_len;
1464         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1465
1466         len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_AX_ERR_STATS_TLV:\n");
1467         len += scnprintf(buf + len, buf_len - len, "ax_su_ndp_err = %u\n",
1468                          htt_stats_buf->ax_su_ndp_err);
1469         len += scnprintf(buf + len, buf_len - len, "ax_su_ndpa_err = %u\n",
1470                          htt_stats_buf->ax_su_ndpa_err);
1471         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndpa_err = %u\n",
1472                          htt_stats_buf->ax_mu_mimo_ndpa_err);
1473         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_ndp_err = %u\n",
1474                          htt_stats_buf->ax_mu_mimo_ndp_err);
1475         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp1_err = %u\n",
1476                          htt_stats_buf->ax_mu_mimo_brp1_err);
1477         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp2_err = %u\n",
1478                          htt_stats_buf->ax_mu_mimo_brp2_err);
1479         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp3_err = %u\n",
1480                          htt_stats_buf->ax_mu_mimo_brp3_err);
1481         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp4_err = %u\n",
1482                          htt_stats_buf->ax_mu_mimo_brp4_err);
1483         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp5_err = %u\n",
1484                          htt_stats_buf->ax_mu_mimo_brp5_err);
1485         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp6_err = %u\n",
1486                          htt_stats_buf->ax_mu_mimo_brp6_err);
1487         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_brp7_err = %u\n",
1488                          htt_stats_buf->ax_mu_mimo_brp7_err);
1489         len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n",
1490                          htt_stats_buf->ax_basic_trigger_err);
1491         len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_trigger_err = %u\n",
1492                          htt_stats_buf->ax_ulmumimo_trigger_err);
1493         len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n",
1494                          htt_stats_buf->ax_bsr_trigger_err);
1495         len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n",
1496                          htt_stats_buf->ax_mu_bar_trigger_err);
1497         len += scnprintf(buf + len, buf_len - len, "ax_mu_rts_trigger_err = %u\n\n",
1498                          htt_stats_buf->ax_mu_rts_trigger_err);
1499
1500         if (len >= buf_len)
1501                 buf[buf_len - 1] = 0;
1502         else
1503                 buf[len] = 0;
1504
1505         stats_req->buf_len = len;
1506 }
1507
1508 static inline void
1509 htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf,
1510                                         struct debug_htt_stats_req *stats_req)
1511 {
1512         const struct htt_tx_pdev_mu_mimo_sch_stats_tlv *htt_stats_buf = tag_buf;
1513         u8 *buf = stats_req->buf;
1514         u32 len = stats_req->buf_len;
1515         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1516         u8 i;
1517
1518         len += scnprintf(buf + len, buf_len - len,
1519                          "HTT_TX_PDEV_MU_MIMO_SCH_STATS_TLV:\n");
1520         len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_posted = %u\n",
1521                          htt_stats_buf->mu_mimo_sch_posted);
1522         len += scnprintf(buf + len, buf_len - len, "mu_mimo_sch_failed = %u\n",
1523                          htt_stats_buf->mu_mimo_sch_failed);
1524         len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n\n",
1525                          htt_stats_buf->mu_mimo_ppdu_posted);
1526
1527         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++)
1528                 len += scnprintf(buf + len, buf_len - len,
1529                                  "ac_mu_mimo_sch_posted_per_group_index %u = %u\n",
1530                                  i, htt_stats_buf->ac_mu_mimo_sch_posted_per_grp_sz[i]);
1531
1532         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++)
1533                 len += scnprintf(buf + len, buf_len - len,
1534                                  "ax_mu_mimo_sch_posted_per_group_index %u = %u\n",
1535                                  i, htt_stats_buf->ax_mu_mimo_sch_posted_per_grp_sz[i]);
1536
1537         len += scnprintf(buf + len, buf_len - len, "11ac MU_MIMO SCH STATS:\n");
1538
1539         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++)
1540                 len += scnprintf(buf + len, buf_len - len,
1541                                  "ac_mu_mimo_sch_nusers_%u = %u\n",
1542                                  i, htt_stats_buf->ac_mu_mimo_sch_nusers[i]);
1543
1544         len += scnprintf(buf + len, buf_len - len, "\n11ax MU_MIMO SCH STATS:\n");
1545
1546         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++)
1547                 len += scnprintf(buf + len, buf_len - len,
1548                                  "ax_mu_mimo_sch_nusers_%u = %u\n",
1549                                  i, htt_stats_buf->ax_mu_mimo_sch_nusers[i]);
1550
1551         len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n");
1552
1553         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
1554                 len += scnprintf(buf + len, buf_len - len,
1555                                  "ax_ofdma_sch_nusers_%u = %u\n",
1556                                  i, htt_stats_buf->ax_ofdma_sch_nusers[i]);
1557                 len += scnprintf(buf + len, buf_len - len,
1558                                  "ax_ul_ofdma_basic_sch_nusers_%u = %u\n",
1559                                  i, htt_stats_buf->ax_ul_ofdma_basic_sch_nusers[i]);
1560                 len += scnprintf(buf + len, buf_len - len,
1561                                  "ax_ul_ofdma_bsr_sch_nusers_%u = %u\n",
1562                                  i, htt_stats_buf->ax_ul_ofdma_bsr_sch_nusers[i]);
1563                 len += scnprintf(buf + len, buf_len - len,
1564                                  "ax_ul_ofdma_sch_bar_nusers_%u = %u\n",
1565                                  i, htt_stats_buf->ax_ul_ofdma_bar_sch_nusers[i]);
1566                 len += scnprintf(buf + len, buf_len - len,
1567                                  "ax_ul_ofdma_brp_sch_nusers_%u = %u\n",
1568                                  i, htt_stats_buf->ax_ul_ofdma_brp_sch_nusers[i]);
1569         }
1570
1571         len += scnprintf(buf + len, buf_len - len, "\n11ax UL MUMIO SCH STATS:\n");
1572
1573         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS; i++) {
1574                 len += scnprintf(buf + len, buf_len - len,
1575                                  "ax_ul_mumimo_basic_sch_nusers_%u = %u\n",
1576                                  i, htt_stats_buf->ax_ul_mumimo_basic_sch_nusers[i]);
1577                 len += scnprintf(buf + len, buf_len - len,
1578                                  "ax_ul_mumimo_brp_sch_nusers_%u = %u\n",
1579                                  i, htt_stats_buf->ax_ul_mumimo_brp_sch_nusers[i]);
1580         }
1581
1582         if (len >= buf_len)
1583                 buf[buf_len - 1] = 0;
1584         else
1585                 buf[len] = 0;
1586
1587         stats_req->buf_len = len;
1588 }
1589
1590 static inline void
1591 htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(const void *tag_buf,
1592                                          struct debug_htt_stats_req *stats_req)
1593 {
1594         const struct htt_tx_pdev_mpdu_stats_tlv *htt_stats_buf = tag_buf;
1595         u8 *buf = stats_req->buf;
1596         u32 len = stats_req->buf_len;
1597         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1598
1599         if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_MIMO_AC) {
1600                 if (!htt_stats_buf->user_index)
1601                         len += scnprintf(buf + len, buf_len - len,
1602                                          "HTT_TX_PDEV_MU_MIMO_AC_MPDU_STATS:\n");
1603
1604                 if (htt_stats_buf->user_index <
1605                     HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS) {
1606                         len += scnprintf(buf + len, buf_len - len,
1607                                          "ac_mu_mimo_mpdus_queued_usr_%u = %u\n",
1608                                          htt_stats_buf->user_index,
1609                                          htt_stats_buf->mpdus_queued_usr);
1610                         len += scnprintf(buf + len, buf_len - len,
1611                                          "ac_mu_mimo_mpdus_tried_usr_%u = %u\n",
1612                                          htt_stats_buf->user_index,
1613                                          htt_stats_buf->mpdus_tried_usr);
1614                         len += scnprintf(buf + len, buf_len - len,
1615                                          "ac_mu_mimo_mpdus_failed_usr_%u = %u\n",
1616                                          htt_stats_buf->user_index,
1617                                          htt_stats_buf->mpdus_failed_usr);
1618                         len += scnprintf(buf + len, buf_len - len,
1619                                          "ac_mu_mimo_mpdus_requeued_usr_%u = %u\n",
1620                                          htt_stats_buf->user_index,
1621                                          htt_stats_buf->mpdus_requeued_usr);
1622                         len += scnprintf(buf + len, buf_len - len,
1623                                          "ac_mu_mimo_err_no_ba_usr_%u = %u\n",
1624                                          htt_stats_buf->user_index,
1625                                          htt_stats_buf->err_no_ba_usr);
1626                         len += scnprintf(buf + len, buf_len - len,
1627                                          "ac_mu_mimo_mpdu_underrun_usr_%u = %u\n",
1628                                          htt_stats_buf->user_index,
1629                                          htt_stats_buf->mpdu_underrun_usr);
1630                         len += scnprintf(buf + len, buf_len - len,
1631                                          "ac_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
1632                                          htt_stats_buf->user_index,
1633                                          htt_stats_buf->ampdu_underrun_usr);
1634                 }
1635         }
1636
1637         if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_MIMO_AX) {
1638                 if (!htt_stats_buf->user_index)
1639                         len += scnprintf(buf + len, buf_len - len,
1640                                          "HTT_TX_PDEV_MU_MIMO_AX_MPDU_STATS:\n");
1641
1642                 if (htt_stats_buf->user_index <
1643                     HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS) {
1644                         len += scnprintf(buf + len, buf_len - len,
1645                                          "ax_mu_mimo_mpdus_queued_usr_%u = %u\n",
1646                                          htt_stats_buf->user_index,
1647                                          htt_stats_buf->mpdus_queued_usr);
1648                         len += scnprintf(buf + len, buf_len - len,
1649                                          "ax_mu_mimo_mpdus_tried_usr_%u = %u\n",
1650                                          htt_stats_buf->user_index,
1651                                          htt_stats_buf->mpdus_tried_usr);
1652                         len += scnprintf(buf + len, buf_len - len,
1653                                          "ax_mu_mimo_mpdus_failed_usr_%u = %u\n",
1654                                          htt_stats_buf->user_index,
1655                                          htt_stats_buf->mpdus_failed_usr);
1656                         len += scnprintf(buf + len, buf_len - len,
1657                                          "ax_mu_mimo_mpdus_requeued_usr_%u = %u\n",
1658                                          htt_stats_buf->user_index,
1659                                          htt_stats_buf->mpdus_requeued_usr);
1660                         len += scnprintf(buf + len, buf_len - len,
1661                                          "ax_mu_mimo_err_no_ba_usr_%u = %u\n",
1662                                          htt_stats_buf->user_index,
1663                                          htt_stats_buf->err_no_ba_usr);
1664                         len += scnprintf(buf + len, buf_len - len,
1665                                          "ax_mu_mimo_mpdu_underrun_usr_%u = %u\n",
1666                                          htt_stats_buf->user_index,
1667                                          htt_stats_buf->mpdu_underrun_usr);
1668                         len += scnprintf(buf + len, buf_len - len,
1669                                          "ax_mu_mimo_ampdu_underrun_usr_%u = %u\n\n",
1670                                          htt_stats_buf->user_index,
1671                                          htt_stats_buf->ampdu_underrun_usr);
1672                 }
1673         }
1674
1675         if (htt_stats_buf->tx_sched_mode == HTT_STATS_TX_SCHED_MODE_MU_OFDMA_AX) {
1676                 if (!htt_stats_buf->user_index)
1677                         len += scnprintf(buf + len, buf_len - len,
1678                                          "HTT_TX_PDEV_AX_MU_OFDMA_MPDU_STATS:\n");
1679
1680                 if (htt_stats_buf->user_index < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS) {
1681                         len += scnprintf(buf + len, buf_len - len,
1682                                          "ax_mu_ofdma_mpdus_queued_usr_%u = %u\n",
1683                                          htt_stats_buf->user_index,
1684                                          htt_stats_buf->mpdus_queued_usr);
1685                         len += scnprintf(buf + len, buf_len - len,
1686                                          "ax_mu_ofdma_mpdus_tried_usr_%u = %u\n",
1687                                          htt_stats_buf->user_index,
1688                                          htt_stats_buf->mpdus_tried_usr);
1689                         len += scnprintf(buf + len, buf_len - len,
1690                                          "ax_mu_ofdma_mpdus_failed_usr_%u = %u\n",
1691                                          htt_stats_buf->user_index,
1692                                          htt_stats_buf->mpdus_failed_usr);
1693                         len += scnprintf(buf + len, buf_len - len,
1694                                          "ax_mu_ofdma_mpdus_requeued_usr_%u = %u\n",
1695                                          htt_stats_buf->user_index,
1696                                          htt_stats_buf->mpdus_requeued_usr);
1697                         len += scnprintf(buf + len, buf_len - len,
1698                                          "ax_mu_ofdma_err_no_ba_usr_%u = %u\n",
1699                                          htt_stats_buf->user_index,
1700                                          htt_stats_buf->err_no_ba_usr);
1701                         len += scnprintf(buf + len, buf_len - len,
1702                                          "ax_mu_ofdma_mpdu_underrun_usr_%u = %u\n",
1703                                          htt_stats_buf->user_index,
1704                                          htt_stats_buf->mpdu_underrun_usr);
1705                         len += scnprintf(buf + len, buf_len - len,
1706                                          "ax_mu_ofdma_ampdu_underrun_usr_%u = %u\n\n",
1707                                          htt_stats_buf->user_index,
1708                                          htt_stats_buf->ampdu_underrun_usr);
1709                 }
1710         }
1711
1712         if (len >= buf_len)
1713                 buf[buf_len - 1] = 0;
1714         else
1715                 buf[len] = 0;
1716
1717         stats_req->buf_len = len;
1718 }
1719
1720 static inline void
1721 htt_print_sched_txq_cmd_posted_tlv_v(const void *tag_buf,
1722                                      u16 tag_len,
1723                                      struct debug_htt_stats_req *stats_req)
1724 {
1725         const struct htt_sched_txq_cmd_posted_tlv_v *htt_stats_buf = tag_buf;
1726         u8 *buf = stats_req->buf;
1727         u32 len = stats_req->buf_len;
1728         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1729         u16 num_elements = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_SCHED_TX_MODE_MAX);
1730
1731         len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV_V:\n");
1732
1733         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_cmd_posted,
1734                            "sched_cmd_posted", num_elements, "\n\n");
1735
1736         if (len >= buf_len)
1737                 buf[buf_len - 1] = 0;
1738         else
1739                 buf[len] = 0;
1740
1741         stats_req->buf_len = len;
1742 }
1743
1744 static inline void
1745 htt_print_sched_txq_cmd_reaped_tlv_v(const void *tag_buf,
1746                                      u16 tag_len,
1747                                      struct debug_htt_stats_req *stats_req)
1748 {
1749         const struct htt_sched_txq_cmd_reaped_tlv_v *htt_stats_buf = tag_buf;
1750         u8 *buf = stats_req->buf;
1751         u32 len = stats_req->buf_len;
1752         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1753         u16 num_elements = min_t(u16, (tag_len >> 2), HTT_TX_PDEV_SCHED_TX_MODE_MAX);
1754
1755         len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV_V:\n");
1756
1757         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_cmd_reaped,
1758                            "sched_cmd_reaped", num_elements, "\n\n");
1759
1760         if (len >= buf_len)
1761                 buf[buf_len - 1] = 0;
1762         else
1763                 buf[len] = 0;
1764
1765         stats_req->buf_len = len;
1766 }
1767
1768 static inline void
1769 htt_print_sched_txq_sched_order_su_tlv_v(const void *tag_buf,
1770                                          u16 tag_len,
1771                                          struct debug_htt_stats_req *stats_req)
1772 {
1773         const struct htt_sched_txq_sched_order_su_tlv_v *htt_stats_buf = tag_buf;
1774         u8 *buf = stats_req->buf;
1775         u32 len = stats_req->buf_len;
1776         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1777         /* each entry is u32, i.e. 4 bytes */
1778         u32 sched_order_su_num_entries =
1779                 min_t(u32, (tag_len >> 2), HTT_TX_PDEV_NUM_SCHED_ORDER_LOG);
1780
1781         len += scnprintf(buf + len, buf_len - len,
1782                          "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV_V:\n");
1783
1784         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_order_su, "sched_order_su",
1785                            sched_order_su_num_entries, "\n\n");
1786
1787         if (len >= buf_len)
1788                 buf[buf_len - 1] = 0;
1789         else
1790                 buf[len] = 0;
1791
1792         stats_req->buf_len = len;
1793 }
1794
1795 static inline void
1796 htt_print_sched_txq_sched_ineligibility_tlv_v(const void *tag_buf,
1797                                               u16 tag_len,
1798                                               struct debug_htt_stats_req *stats_req)
1799 {
1800         const struct htt_sched_txq_sched_ineligibility_tlv_v *htt_stats_buf = tag_buf;
1801         u8 *buf = stats_req->buf;
1802         u32 len = stats_req->buf_len;
1803         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1804         /* each entry is u32, i.e. 4 bytes */
1805         u32 sched_ineligibility_num_entries = tag_len >> 2;
1806
1807         len += scnprintf(buf + len, buf_len - len,
1808                          "HTT_SCHED_TXQ_SCHED_INELIGIBILITY_V:\n");
1809
1810         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->sched_ineligibility,
1811                            "sched_ineligibility", sched_ineligibility_num_entries,
1812                            "\n\n");
1813
1814         if (len >= buf_len)
1815                 buf[buf_len - 1] = 0;
1816         else
1817                 buf[len] = 0;
1818
1819         stats_req->buf_len = len;
1820 }
1821
1822 static inline void
1823 htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf,
1824                                           struct debug_htt_stats_req *stats_req)
1825 {
1826         const struct htt_tx_pdev_stats_sched_per_txq_tlv *htt_stats_buf = tag_buf;
1827         u8 *buf = stats_req->buf;
1828         u32 len = stats_req->buf_len;
1829         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1830
1831         len += scnprintf(buf + len, buf_len - len,
1832                          "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n");
1833         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
1834                          FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID,
1835                                    htt_stats_buf->mac_id__txq_id__word));
1836         len += scnprintf(buf + len, buf_len - len, "txq_id = %lu\n",
1837                          FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID,
1838                                    htt_stats_buf->mac_id__txq_id__word));
1839         len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n",
1840                          htt_stats_buf->sched_policy);
1841         len += scnprintf(buf + len, buf_len - len,
1842                          "last_sched_cmd_posted_timestamp = %u\n",
1843                          htt_stats_buf->last_sched_cmd_posted_timestamp);
1844         len += scnprintf(buf + len, buf_len - len,
1845                          "last_sched_cmd_compl_timestamp = %u\n",
1846                          htt_stats_buf->last_sched_cmd_compl_timestamp);
1847         len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n",
1848                          htt_stats_buf->sched_2_tac_lwm_count);
1849         len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n",
1850                          htt_stats_buf->sched_2_tac_ring_full);
1851         len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n",
1852                          htt_stats_buf->sched_cmd_post_failure);
1853         len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n",
1854                          htt_stats_buf->num_active_tids);
1855         len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n",
1856                          htt_stats_buf->num_ps_schedules);
1857         len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n",
1858                          htt_stats_buf->sched_cmds_pending);
1859         len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n",
1860                          htt_stats_buf->num_tid_register);
1861         len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n",
1862                          htt_stats_buf->num_tid_unregister);
1863         len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n",
1864                          htt_stats_buf->num_qstats_queried);
1865         len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n",
1866                          htt_stats_buf->qstats_update_pending);
1867         len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n",
1868                          htt_stats_buf->last_qstats_query_timestamp);
1869         len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n",
1870                          htt_stats_buf->num_tqm_cmdq_full);
1871         len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n",
1872                          htt_stats_buf->num_de_sched_algo_trigger);
1873         len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n",
1874                          htt_stats_buf->num_rt_sched_algo_trigger);
1875         len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n",
1876                          htt_stats_buf->num_tqm_sched_algo_trigger);
1877         len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n\n",
1878                          htt_stats_buf->notify_sched);
1879         len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n\n",
1880                          htt_stats_buf->dur_based_sendn_term);
1881
1882         if (len >= buf_len)
1883                 buf[buf_len - 1] = 0;
1884         else
1885                 buf[len] = 0;
1886
1887         stats_req->buf_len = len;
1888 }
1889
1890 static inline void htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf,
1891                                                     struct debug_htt_stats_req *stats_req)
1892 {
1893         const struct htt_stats_tx_sched_cmn_tlv *htt_stats_buf = tag_buf;
1894         u8 *buf = stats_req->buf;
1895         u32 len = stats_req->buf_len;
1896         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1897
1898         len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n");
1899         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
1900                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
1901         len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n",
1902                          htt_stats_buf->current_timestamp);
1903
1904         if (len >= buf_len)
1905                 buf[buf_len - 1] = 0;
1906         else
1907                 buf[len] = 0;
1908
1909         stats_req->buf_len = len;
1910 }
1911
1912 static inline void
1913 htt_print_tx_tqm_gen_mpdu_stats_tlv_v(const void *tag_buf,
1914                                       u16 tag_len,
1915                                       struct debug_htt_stats_req *stats_req)
1916 {
1917         const struct htt_tx_tqm_gen_mpdu_stats_tlv_v *htt_stats_buf = tag_buf;
1918         u8 *buf = stats_req->buf;
1919         u32 len = stats_req->buf_len;
1920         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1921         u16 num_elements = min_t(u16, (tag_len >> 2),
1922                                  HTT_TX_TQM_MAX_LIST_MPDU_END_REASON);
1923
1924         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV_V:\n");
1925
1926         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->gen_mpdu_end_reason,
1927                            "gen_mpdu_end_reason", num_elements, "\n\n");
1928
1929         if (len >= buf_len)
1930                 buf[buf_len - 1] = 0;
1931         else
1932                 buf[len] = 0;
1933
1934         stats_req->buf_len = len;
1935 }
1936
1937 static inline void
1938 htt_print_tx_tqm_list_mpdu_stats_tlv_v(const void *tag_buf,
1939                                        u16 tag_len,
1940                                        struct debug_htt_stats_req *stats_req)
1941 {
1942         const struct htt_tx_tqm_list_mpdu_stats_tlv_v *htt_stats_buf = tag_buf;
1943         u8 *buf = stats_req->buf;
1944         u32 len = stats_req->buf_len;
1945         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1946         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_TX_TQM_MAX_LIST_MPDU_END_REASON);
1947
1948         len += scnprintf(buf + len, buf_len - len,
1949                          "HTT_TX_TQM_LIST_MPDU_STATS_TLV_V:\n");
1950
1951         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->list_mpdu_end_reason,
1952                            "list_mpdu_end_reason", num_elems, "\n\n");
1953
1954         if (len >= buf_len)
1955                 buf[buf_len - 1] = 0;
1956         else
1957                 buf[len] = 0;
1958
1959         stats_req->buf_len = len;
1960 }
1961
1962 static inline void
1963 htt_print_tx_tqm_list_mpdu_cnt_tlv_v(const void *tag_buf,
1964                                      u16 tag_len,
1965                                      struct debug_htt_stats_req *stats_req)
1966 {
1967         const struct htt_tx_tqm_list_mpdu_cnt_tlv_v *htt_stats_buf = tag_buf;
1968         u8 *buf = stats_req->buf;
1969         u32 len = stats_req->buf_len;
1970         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1971         u16 num_elems = min_t(u16, (tag_len >> 2),
1972                               HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS);
1973
1974         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n");
1975
1976         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->list_mpdu_cnt_hist,
1977                            "list_mpdu_cnt_hist", num_elems, "\n\n");
1978
1979         if (len >= buf_len)
1980                 buf[buf_len - 1] = 0;
1981         else
1982                 buf[len] = 0;
1983
1984         stats_req->buf_len = len;
1985 }
1986
1987 static inline void
1988 htt_print_tx_tqm_pdev_stats_tlv_v(const void *tag_buf,
1989                                   struct debug_htt_stats_req *stats_req)
1990 {
1991         const struct htt_tx_tqm_pdev_stats_tlv_v *htt_stats_buf = tag_buf;
1992         u8 *buf = stats_req->buf;
1993         u32 len = stats_req->buf_len;
1994         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
1995
1996         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n");
1997         len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n",
1998                          htt_stats_buf->msdu_count);
1999         len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n",
2000                          htt_stats_buf->mpdu_count);
2001         len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n",
2002                          htt_stats_buf->remove_msdu);
2003         len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n",
2004                          htt_stats_buf->remove_mpdu);
2005         len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n",
2006                          htt_stats_buf->remove_msdu_ttl);
2007         len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n",
2008                          htt_stats_buf->send_bar);
2009         len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n",
2010                          htt_stats_buf->bar_sync);
2011         len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n",
2012                          htt_stats_buf->notify_mpdu);
2013         len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
2014                          htt_stats_buf->sync_cmd);
2015         len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
2016                          htt_stats_buf->write_cmd);
2017         len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n",
2018                          htt_stats_buf->hwsch_trigger);
2019         len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
2020                          htt_stats_buf->ack_tlv_proc);
2021         len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n",
2022                          htt_stats_buf->gen_mpdu_cmd);
2023         len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n",
2024                          htt_stats_buf->gen_list_cmd);
2025         len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n",
2026                          htt_stats_buf->remove_mpdu_cmd);
2027         len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n",
2028                          htt_stats_buf->remove_mpdu_tried_cmd);
2029         len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n",
2030                          htt_stats_buf->mpdu_queue_stats_cmd);
2031         len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n",
2032                          htt_stats_buf->mpdu_head_info_cmd);
2033         len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n",
2034                          htt_stats_buf->msdu_flow_stats_cmd);
2035         len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n",
2036                          htt_stats_buf->remove_msdu_cmd);
2037         len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n",
2038                          htt_stats_buf->remove_msdu_ttl_cmd);
2039         len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n",
2040                          htt_stats_buf->flush_cache_cmd);
2041         len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n",
2042                          htt_stats_buf->update_mpduq_cmd);
2043         len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n",
2044                          htt_stats_buf->enqueue);
2045         len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n",
2046                          htt_stats_buf->enqueue_notify);
2047         len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n",
2048                          htt_stats_buf->notify_mpdu_at_head);
2049         len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n",
2050                          htt_stats_buf->notify_mpdu_state_valid);
2051         len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n",
2052                          htt_stats_buf->sched_udp_notify1);
2053         len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n",
2054                          htt_stats_buf->sched_udp_notify2);
2055         len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n",
2056                          htt_stats_buf->sched_nonudp_notify1);
2057         len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n",
2058                          htt_stats_buf->sched_nonudp_notify2);
2059
2060         if (len >= buf_len)
2061                 buf[buf_len - 1] = 0;
2062         else
2063                 buf[len] = 0;
2064
2065         stats_req->buf_len = len;
2066 }
2067
2068 static inline void htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf,
2069                                                   struct debug_htt_stats_req *stats_req)
2070 {
2071         const struct htt_tx_tqm_cmn_stats_tlv *htt_stats_buf = tag_buf;
2072         u8 *buf = stats_req->buf;
2073         u32 len = stats_req->buf_len;
2074         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2075
2076         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n");
2077         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2078                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2079         len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n",
2080                          htt_stats_buf->max_cmdq_id);
2081         len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n",
2082                          htt_stats_buf->list_mpdu_cnt_hist_intvl);
2083         len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n",
2084                          htt_stats_buf->add_msdu);
2085         len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n",
2086                          htt_stats_buf->q_empty);
2087         len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n",
2088                          htt_stats_buf->q_not_empty);
2089         len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n",
2090                          htt_stats_buf->drop_notification);
2091         len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n\n",
2092                          htt_stats_buf->desc_threshold);
2093
2094         if (len >= buf_len)
2095                 buf[buf_len - 1] = 0;
2096         else
2097                 buf[len] = 0;
2098
2099         stats_req->buf_len = len;
2100 }
2101
2102 static inline void htt_print_tx_tqm_error_stats_tlv(const void *tag_buf,
2103                                                     struct debug_htt_stats_req *stats_req)
2104 {
2105         const struct htt_tx_tqm_error_stats_tlv *htt_stats_buf = tag_buf;
2106         u8 *buf = stats_req->buf;
2107         u32 len = stats_req->buf_len;
2108         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2109
2110         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n");
2111         len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n",
2112                          htt_stats_buf->q_empty_failure);
2113         len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n",
2114                          htt_stats_buf->q_not_empty_failure);
2115         len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n",
2116                          htt_stats_buf->add_msdu_failure);
2117
2118         if (len >= buf_len)
2119                 buf[buf_len - 1] = 0;
2120         else
2121                 buf[len] = 0;
2122
2123         stats_req->buf_len = len;
2124 }
2125
2126 static inline void htt_print_tx_tqm_cmdq_status_tlv(const void *tag_buf,
2127                                                     struct debug_htt_stats_req *stats_req)
2128 {
2129         const struct htt_tx_tqm_cmdq_status_tlv *htt_stats_buf = tag_buf;
2130         u8 *buf = stats_req->buf;
2131         u32 len = stats_req->buf_len;
2132         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2133
2134         len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMDQ_STATUS_TLV:\n");
2135         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2136                          FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_MAC_ID,
2137                                    htt_stats_buf->mac_id__cmdq_id__word));
2138         len += scnprintf(buf + len, buf_len - len, "cmdq_id = %lu\n\n",
2139                          FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID,
2140                                    htt_stats_buf->mac_id__cmdq_id__word));
2141         len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
2142                          htt_stats_buf->sync_cmd);
2143         len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
2144                          htt_stats_buf->write_cmd);
2145         len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n",
2146                          htt_stats_buf->gen_mpdu_cmd);
2147         len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n",
2148                          htt_stats_buf->mpdu_queue_stats_cmd);
2149         len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n",
2150                          htt_stats_buf->mpdu_head_info_cmd);
2151         len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n",
2152                          htt_stats_buf->msdu_flow_stats_cmd);
2153         len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n",
2154                          htt_stats_buf->remove_mpdu_cmd);
2155         len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n",
2156                          htt_stats_buf->remove_msdu_cmd);
2157         len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n",
2158                          htt_stats_buf->flush_cache_cmd);
2159         len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n",
2160                          htt_stats_buf->update_mpduq_cmd);
2161         len += scnprintf(buf + len, buf_len - len, "update_msduq_cmd = %u\n\n",
2162                          htt_stats_buf->update_msduq_cmd);
2163
2164         if (len >= buf_len)
2165                 buf[buf_len - 1] = 0;
2166         else
2167                 buf[len] = 0;
2168
2169         stats_req->buf_len = len;
2170 }
2171
2172 static inline void
2173 htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf,
2174                                         struct debug_htt_stats_req *stats_req)
2175 {
2176         const struct htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf;
2177         u8 *buf = stats_req->buf;
2178         u32 len = stats_req->buf_len;
2179         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2180
2181         len += scnprintf(buf + len, buf_len - len,
2182                            "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n");
2183         len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n",
2184                          htt_stats_buf->m1_packets);
2185         len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n",
2186                          htt_stats_buf->m2_packets);
2187         len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n",
2188                          htt_stats_buf->m3_packets);
2189         len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n",
2190                          htt_stats_buf->m4_packets);
2191         len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n",
2192                          htt_stats_buf->g1_packets);
2193         len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n\n",
2194                          htt_stats_buf->g2_packets);
2195
2196         if (len >= buf_len)
2197                 buf[buf_len - 1] = 0;
2198         else
2199                 buf[len] = 0;
2200
2201         stats_req->buf_len = len;
2202 }
2203
2204 static inline void
2205 htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf,
2206                                           struct debug_htt_stats_req *stats_req)
2207 {
2208         const struct htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf;
2209         u8 *buf = stats_req->buf;
2210         u32 len = stats_req->buf_len;
2211         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2212
2213         len += scnprintf(buf + len, buf_len - len,
2214                            "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n");
2215         len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n",
2216                          htt_stats_buf->ap_bss_peer_not_found);
2217         len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n",
2218                          htt_stats_buf->ap_bcast_mcast_no_peer);
2219         len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n",
2220                          htt_stats_buf->sta_delete_in_progress);
2221         len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n",
2222                          htt_stats_buf->ibss_no_bss_peer);
2223         len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n",
2224                          htt_stats_buf->invalid_vdev_type);
2225         len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n",
2226                          htt_stats_buf->invalid_ast_peer_entry);
2227         len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n",
2228                          htt_stats_buf->peer_entry_invalid);
2229         len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n",
2230                          htt_stats_buf->ethertype_not_ip);
2231         len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n",
2232                          htt_stats_buf->eapol_lookup_failed);
2233         len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n",
2234                          htt_stats_buf->qpeer_not_allow_data);
2235         len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n",
2236                          htt_stats_buf->fse_tid_override);
2237         len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n",
2238                          htt_stats_buf->ipv6_jumbogram_zero_length);
2239         len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n\n",
2240                          htt_stats_buf->qos_to_non_qos_in_prog);
2241
2242         if (len >= buf_len)
2243                 buf[buf_len - 1] = 0;
2244         else
2245                 buf[len] = 0;
2246
2247         stats_req->buf_len = len;
2248 }
2249
2250 static inline void
2251 htt_print_tx_de_classify_stats_tlv(const void *tag_buf,
2252                                    struct debug_htt_stats_req *stats_req)
2253 {
2254         const struct htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf;
2255         u8 *buf = stats_req->buf;
2256         u32 len = stats_req->buf_len;
2257         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2258
2259         len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n");
2260         len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n",
2261                          htt_stats_buf->arp_packets);
2262         len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n",
2263                          htt_stats_buf->igmp_packets);
2264         len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n",
2265                          htt_stats_buf->dhcp_packets);
2266         len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n",
2267                          htt_stats_buf->host_inspected);
2268         len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n",
2269                          htt_stats_buf->htt_included);
2270         len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n",
2271                          htt_stats_buf->htt_valid_mcs);
2272         len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n",
2273                          htt_stats_buf->htt_valid_nss);
2274         len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n",
2275                          htt_stats_buf->htt_valid_preamble_type);
2276         len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n",
2277                          htt_stats_buf->htt_valid_chainmask);
2278         len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n",
2279                          htt_stats_buf->htt_valid_guard_interval);
2280         len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n",
2281                          htt_stats_buf->htt_valid_retries);
2282         len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n",
2283                          htt_stats_buf->htt_valid_bw_info);
2284         len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n",
2285                          htt_stats_buf->htt_valid_power);
2286         len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n",
2287                          htt_stats_buf->htt_valid_key_flags);
2288         len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n",
2289                          htt_stats_buf->htt_valid_no_encryption);
2290         len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n",
2291                          htt_stats_buf->fse_entry_count);
2292         len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n",
2293                          htt_stats_buf->fse_priority_be);
2294         len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n",
2295                          htt_stats_buf->fse_priority_high);
2296         len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n",
2297                          htt_stats_buf->fse_priority_low);
2298         len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n",
2299                          htt_stats_buf->fse_traffic_ptrn_be);
2300         len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n",
2301                          htt_stats_buf->fse_traffic_ptrn_over_sub);
2302         len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n",
2303                          htt_stats_buf->fse_traffic_ptrn_bursty);
2304         len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n",
2305                          htt_stats_buf->fse_traffic_ptrn_interactive);
2306         len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n",
2307                          htt_stats_buf->fse_traffic_ptrn_periodic);
2308         len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n",
2309                          htt_stats_buf->fse_hwqueue_alloc);
2310         len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n",
2311                          htt_stats_buf->fse_hwqueue_created);
2312         len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n",
2313                          htt_stats_buf->fse_hwqueue_send_to_host);
2314         len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n",
2315                          htt_stats_buf->mcast_entry);
2316         len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n",
2317                          htt_stats_buf->bcast_entry);
2318         len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n",
2319                          htt_stats_buf->htt_update_peer_cache);
2320         len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n",
2321                          htt_stats_buf->htt_learning_frame);
2322         len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n",
2323                          htt_stats_buf->fse_invalid_peer);
2324         len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n",
2325                          htt_stats_buf->mec_notify);
2326
2327         if (len >= buf_len)
2328                 buf[buf_len - 1] = 0;
2329         else
2330                 buf[len] = 0;
2331
2332         stats_req->buf_len = len;
2333 }
2334
2335 static inline void
2336 htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf,
2337                                           struct debug_htt_stats_req *stats_req)
2338 {
2339         const struct htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf;
2340         u8 *buf = stats_req->buf;
2341         u32 len = stats_req->buf_len;
2342         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2343
2344         len += scnprintf(buf + len, buf_len - len,
2345                            "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n");
2346         len += scnprintf(buf + len, buf_len - len, "eok = %u\n",
2347                          htt_stats_buf->eok);
2348         len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n",
2349                          htt_stats_buf->classify_done);
2350         len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n",
2351                          htt_stats_buf->lookup_failed);
2352         len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n",
2353                          htt_stats_buf->send_host_dhcp);
2354         len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n",
2355                          htt_stats_buf->send_host_mcast);
2356         len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n",
2357                          htt_stats_buf->send_host_unknown_dest);
2358         len += scnprintf(buf + len, buf_len - len, "send_host = %u\n",
2359                          htt_stats_buf->send_host);
2360         len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n",
2361                          htt_stats_buf->status_invalid);
2362
2363         if (len >= buf_len)
2364                 buf[buf_len - 1] = 0;
2365         else
2366                 buf[len] = 0;
2367
2368         stats_req->buf_len = len;
2369 }
2370
2371 static inline void
2372 htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf,
2373                                           struct debug_htt_stats_req *stats_req)
2374 {
2375         const struct htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf;
2376         u8 *buf = stats_req->buf;
2377         u32 len = stats_req->buf_len;
2378         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2379
2380         len += scnprintf(buf + len, buf_len - len,
2381                          "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n");
2382         len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n",
2383                          htt_stats_buf->enqueued_pkts);
2384         len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n",
2385                          htt_stats_buf->to_tqm);
2386         len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n",
2387                          htt_stats_buf->to_tqm_bypass);
2388
2389         if (len >= buf_len)
2390                 buf[buf_len - 1] = 0;
2391         else
2392                 buf[len] = 0;
2393
2394         stats_req->buf_len = len;
2395 }
2396
2397 static inline void
2398 htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf,
2399                                           struct debug_htt_stats_req *stats_req)
2400 {
2401         const struct htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf;
2402         u8 *buf = stats_req->buf;
2403         u32 len = stats_req->buf_len;
2404         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2405
2406         len += scnprintf(buf + len, buf_len - len,
2407                          "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n");
2408         len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n",
2409                          htt_stats_buf->discarded_pkts);
2410         len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n",
2411                          htt_stats_buf->local_frames);
2412         len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n",
2413                          htt_stats_buf->is_ext_msdu);
2414
2415         if (len >= buf_len)
2416                 buf[buf_len - 1] = 0;
2417         else
2418                 buf[len] = 0;
2419
2420         stats_req->buf_len = len;
2421 }
2422
2423 static inline void htt_print_tx_de_compl_stats_tlv(const void *tag_buf,
2424                                                    struct debug_htt_stats_req *stats_req)
2425 {
2426         const struct htt_tx_de_compl_stats_tlv *htt_stats_buf = tag_buf;
2427         u8 *buf = stats_req->buf;
2428         u32 len = stats_req->buf_len;
2429         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2430
2431         len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n");
2432         len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n",
2433                          htt_stats_buf->tcl_dummy_frame);
2434         len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n",
2435                          htt_stats_buf->tqm_dummy_frame);
2436         len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n",
2437                          htt_stats_buf->tqm_notify_frame);
2438         len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n",
2439                          htt_stats_buf->fw2wbm_enq);
2440         len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n",
2441                          htt_stats_buf->tqm_bypass_frame);
2442
2443         if (len >= buf_len)
2444                 buf[buf_len - 1] = 0;
2445         else
2446                 buf[len] = 0;
2447
2448         stats_req->buf_len = len;
2449 }
2450
2451 static inline void
2452 htt_print_tx_de_fw2wbm_ring_full_hist_tlv(const void *tag_buf,
2453                                           u16 tag_len,
2454                                           struct debug_htt_stats_req *stats_req)
2455 {
2456         const struct htt_tx_de_fw2wbm_ring_full_hist_tlv *htt_stats_buf = tag_buf;
2457         u8 *buf = stats_req->buf;
2458         u32 len = stats_req->buf_len;
2459         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2460         u16  num_elements = tag_len >> 2;
2461
2462         len += scnprintf(buf + len, buf_len - len,
2463                          "HTT_TX_DE_FW2WBM_RING_FULL_HIST_TLV");
2464
2465         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw2wbm_ring_full_hist,
2466                            "fw2wbm_ring_full_hist", num_elements, "\n\n");
2467
2468         if (len >= buf_len)
2469                 buf[buf_len - 1] = 0;
2470         else
2471                 buf[len] = 0;
2472
2473         stats_req->buf_len = len;
2474 }
2475
2476 static inline void
2477 htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, struct debug_htt_stats_req *stats_req)
2478 {
2479         const struct htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf;
2480         u8 *buf = stats_req->buf;
2481         u32 len = stats_req->buf_len;
2482         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2483
2484         len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
2485         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2486                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2487         len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
2488                          htt_stats_buf->tcl2fw_entry_count);
2489         len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
2490                          htt_stats_buf->not_to_fw);
2491         len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n",
2492                          htt_stats_buf->invalid_pdev_vdev_peer);
2493         len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n",
2494                          htt_stats_buf->tcl_res_invalid_addrx);
2495         len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n",
2496                          htt_stats_buf->wbm2fw_entry_count);
2497         len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n\n",
2498                          htt_stats_buf->invalid_pdev);
2499
2500         if (len >= buf_len)
2501                 buf[buf_len - 1] = 0;
2502         else
2503                 buf[len] = 0;
2504
2505         stats_req->buf_len = len;
2506 }
2507
2508 static inline void htt_print_ring_if_stats_tlv(const void *tag_buf,
2509                                                struct debug_htt_stats_req *stats_req)
2510 {
2511         const struct htt_ring_if_stats_tlv *htt_stats_buf = tag_buf;
2512         u8 *buf = stats_req->buf;
2513         u32 len = stats_req->buf_len;
2514         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2515
2516         len += scnprintf(buf + len, buf_len - len, "HTT_RING_IF_STATS_TLV:\n");
2517         len += scnprintf(buf + len, buf_len - len, "base_addr = %u\n",
2518                          htt_stats_buf->base_addr);
2519         len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
2520                          htt_stats_buf->elem_size);
2521         len += scnprintf(buf + len, buf_len - len, "num_elems = %lu\n",
2522                          FIELD_GET(HTT_RING_IF_STATS_NUM_ELEMS,
2523                                    htt_stats_buf->num_elems__prefetch_tail_idx));
2524         len += scnprintf(buf + len, buf_len - len, "prefetch_tail_idx = %lu\n",
2525                          FIELD_GET(HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX,
2526                                    htt_stats_buf->num_elems__prefetch_tail_idx));
2527         len += scnprintf(buf + len, buf_len - len, "head_idx = %lu\n",
2528                          FIELD_GET(HTT_RING_IF_STATS_HEAD_IDX,
2529                                    htt_stats_buf->head_idx__tail_idx));
2530         len += scnprintf(buf + len, buf_len - len, "tail_idx = %lu\n",
2531                          FIELD_GET(HTT_RING_IF_STATS_TAIL_IDX,
2532                                    htt_stats_buf->head_idx__tail_idx));
2533         len += scnprintf(buf + len, buf_len - len, "shadow_head_idx = %lu\n",
2534                          FIELD_GET(HTT_RING_IF_STATS_SHADOW_HEAD_IDX,
2535                                    htt_stats_buf->shadow_head_idx__shadow_tail_idx));
2536         len += scnprintf(buf + len, buf_len - len, "shadow_tail_idx = %lu\n",
2537                          FIELD_GET(HTT_RING_IF_STATS_SHADOW_TAIL_IDX,
2538                                    htt_stats_buf->shadow_head_idx__shadow_tail_idx));
2539         len += scnprintf(buf + len, buf_len - len, "num_tail_incr = %u\n",
2540                          htt_stats_buf->num_tail_incr);
2541         len += scnprintf(buf + len, buf_len - len, "lwm_thresh = %lu\n",
2542                          FIELD_GET(HTT_RING_IF_STATS_LWM_THRESH,
2543                                    htt_stats_buf->lwm_thresh__hwm_thresh));
2544         len += scnprintf(buf + len, buf_len - len, "hwm_thresh = %lu\n",
2545                          FIELD_GET(HTT_RING_IF_STATS_HWM_THRESH,
2546                                    htt_stats_buf->lwm_thresh__hwm_thresh));
2547         len += scnprintf(buf + len, buf_len - len, "overrun_hit_count = %u\n",
2548                          htt_stats_buf->overrun_hit_count);
2549         len += scnprintf(buf + len, buf_len - len, "underrun_hit_count = %u\n",
2550                          htt_stats_buf->underrun_hit_count);
2551         len += scnprintf(buf + len, buf_len - len, "prod_blockwait_count = %u\n",
2552                          htt_stats_buf->prod_blockwait_count);
2553         len += scnprintf(buf + len, buf_len - len, "cons_blockwait_count = %u\n",
2554                          htt_stats_buf->cons_blockwait_count);
2555
2556         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->low_wm_hit_count,
2557                            "low_wm_hit_count", HTT_STATS_LOW_WM_BINS, "\n");
2558         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->high_wm_hit_count,
2559                            "high_wm_hit_count", HTT_STATS_HIGH_WM_BINS, "\n\n");
2560
2561         if (len >= buf_len)
2562                 buf[buf_len - 1] = 0;
2563         else
2564                 buf[len] = 0;
2565
2566         stats_req->buf_len = len;
2567 }
2568
2569 static inline void htt_print_ring_if_cmn_tlv(const void *tag_buf,
2570                                              struct debug_htt_stats_req *stats_req)
2571 {
2572         const struct htt_ring_if_cmn_tlv *htt_stats_buf = tag_buf;
2573         u8 *buf = stats_req->buf;
2574         u32 len = stats_req->buf_len;
2575         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2576
2577         len += scnprintf(buf + len, buf_len - len, "HTT_RING_IF_CMN_TLV:\n");
2578         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2579                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2580         len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2581                          htt_stats_buf->num_records);
2582
2583         if (len >= buf_len)
2584                 buf[buf_len - 1] = 0;
2585         else
2586                 buf[len] = 0;
2587
2588         stats_req->buf_len = len;
2589 }
2590
2591 static inline void htt_print_sfm_client_user_tlv_v(const void *tag_buf,
2592                                                    u16 tag_len,
2593                                                    struct debug_htt_stats_req *stats_req)
2594 {
2595         const struct htt_sfm_client_user_tlv_v *htt_stats_buf = tag_buf;
2596         u8 *buf = stats_req->buf;
2597         u32 len = stats_req->buf_len;
2598         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2599         u16 num_elems = tag_len >> 2;
2600
2601         len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV_V:\n");
2602
2603         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->dwords_used_by_user_n,
2604                            "dwords_used_by_user_n", num_elems, "\n\n");
2605
2606         if (len >= buf_len)
2607                 buf[buf_len - 1] = 0;
2608         else
2609                 buf[len] = 0;
2610
2611         stats_req->buf_len = len;
2612 }
2613
2614 static inline void htt_print_sfm_client_tlv(const void *tag_buf,
2615                                             struct debug_htt_stats_req *stats_req)
2616 {
2617         const struct htt_sfm_client_tlv *htt_stats_buf = tag_buf;
2618         u8 *buf = stats_req->buf;
2619         u32 len = stats_req->buf_len;
2620         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2621
2622         len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CLIENT_TLV:\n");
2623         len += scnprintf(buf + len, buf_len - len, "client_id = %u\n",
2624                          htt_stats_buf->client_id);
2625         len += scnprintf(buf + len, buf_len - len, "buf_min = %u\n",
2626                          htt_stats_buf->buf_min);
2627         len += scnprintf(buf + len, buf_len - len, "buf_max = %u\n",
2628                          htt_stats_buf->buf_max);
2629         len += scnprintf(buf + len, buf_len - len, "buf_busy = %u\n",
2630                          htt_stats_buf->buf_busy);
2631         len += scnprintf(buf + len, buf_len - len, "buf_alloc = %u\n",
2632                          htt_stats_buf->buf_alloc);
2633         len += scnprintf(buf + len, buf_len - len, "buf_avail = %u\n",
2634                          htt_stats_buf->buf_avail);
2635         len += scnprintf(buf + len, buf_len - len, "num_users = %u\n\n",
2636                          htt_stats_buf->num_users);
2637
2638         if (len >= buf_len)
2639                 buf[buf_len - 1] = 0;
2640         else
2641                 buf[len] = 0;
2642
2643         stats_req->buf_len = len;
2644 }
2645
2646 static inline void htt_print_sfm_cmn_tlv(const void *tag_buf,
2647                                          struct debug_htt_stats_req *stats_req)
2648 {
2649         const struct htt_sfm_cmn_tlv *htt_stats_buf = tag_buf;
2650         u8 *buf = stats_req->buf;
2651         u32 len = stats_req->buf_len;
2652         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2653
2654         len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n");
2655         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2656                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2657         len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n",
2658                          htt_stats_buf->buf_total);
2659         len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n",
2660                          htt_stats_buf->mem_empty);
2661         len += scnprintf(buf + len, buf_len - len, "deallocate_bufs = %u\n",
2662                          htt_stats_buf->deallocate_bufs);
2663         len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2664                          htt_stats_buf->num_records);
2665
2666         if (len >= buf_len)
2667                 buf[buf_len - 1] = 0;
2668         else
2669                 buf[len] = 0;
2670
2671         stats_req->buf_len = len;
2672 }
2673
2674 static inline void htt_print_sring_stats_tlv(const void *tag_buf,
2675                                              struct debug_htt_stats_req *stats_req)
2676 {
2677         const struct htt_sring_stats_tlv *htt_stats_buf = tag_buf;
2678         u8 *buf = stats_req->buf;
2679         u32 len = stats_req->buf_len;
2680         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2681
2682         len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n");
2683         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2684                          FIELD_GET(HTT_SRING_STATS_MAC_ID,
2685                                    htt_stats_buf->mac_id__ring_id__arena__ep));
2686         len += scnprintf(buf + len, buf_len - len, "ring_id = %lu\n",
2687                          FIELD_GET(HTT_SRING_STATS_RING_ID,
2688                                    htt_stats_buf->mac_id__ring_id__arena__ep));
2689         len += scnprintf(buf + len, buf_len - len, "arena = %lu\n",
2690                          FIELD_GET(HTT_SRING_STATS_ARENA,
2691                                    htt_stats_buf->mac_id__ring_id__arena__ep));
2692         len += scnprintf(buf + len, buf_len - len, "ep = %lu\n",
2693                          FIELD_GET(HTT_SRING_STATS_EP,
2694                                    htt_stats_buf->mac_id__ring_id__arena__ep));
2695         len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n",
2696                          htt_stats_buf->base_addr_lsb);
2697         len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n",
2698                          htt_stats_buf->base_addr_msb);
2699         len += scnprintf(buf + len, buf_len - len, "ring_size = %u\n",
2700                          htt_stats_buf->ring_size);
2701         len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
2702                          htt_stats_buf->elem_size);
2703         len += scnprintf(buf + len, buf_len - len, "num_avail_words = %lu\n",
2704                          FIELD_GET(HTT_SRING_STATS_NUM_AVAIL_WORDS,
2705                                    htt_stats_buf->num_avail_words__num_valid_words));
2706         len += scnprintf(buf + len, buf_len - len, "num_valid_words = %lu\n",
2707                          FIELD_GET(HTT_SRING_STATS_NUM_VALID_WORDS,
2708                                    htt_stats_buf->num_avail_words__num_valid_words));
2709         len += scnprintf(buf + len, buf_len - len, "head_ptr = %lu\n",
2710                          FIELD_GET(HTT_SRING_STATS_HEAD_PTR,
2711                                    htt_stats_buf->head_ptr__tail_ptr));
2712         len += scnprintf(buf + len, buf_len - len, "tail_ptr = %lu\n",
2713                          FIELD_GET(HTT_SRING_STATS_TAIL_PTR,
2714                                    htt_stats_buf->head_ptr__tail_ptr));
2715         len += scnprintf(buf + len, buf_len - len, "consumer_empty = %lu\n",
2716                          FIELD_GET(HTT_SRING_STATS_CONSUMER_EMPTY,
2717                                    htt_stats_buf->consumer_empty__producer_full));
2718         len += scnprintf(buf + len, buf_len - len, "producer_full = %lu\n",
2719                          FIELD_GET(HTT_SRING_STATS_PRODUCER_FULL,
2720                                    htt_stats_buf->consumer_empty__producer_full));
2721         len += scnprintf(buf + len, buf_len - len, "prefetch_count = %lu\n",
2722                          FIELD_GET(HTT_SRING_STATS_PREFETCH_COUNT,
2723                                    htt_stats_buf->prefetch_count__internal_tail_ptr));
2724         len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %lu\n\n",
2725                          FIELD_GET(HTT_SRING_STATS_INTERNAL_TAIL_PTR,
2726                                    htt_stats_buf->prefetch_count__internal_tail_ptr));
2727
2728         if (len >= buf_len)
2729                 buf[buf_len - 1] = 0;
2730         else
2731                 buf[len] = 0;
2732
2733         stats_req->buf_len = len;
2734 }
2735
2736 static inline void htt_print_sring_cmn_tlv(const void *tag_buf,
2737                                            struct debug_htt_stats_req *stats_req)
2738 {
2739         const struct htt_sring_cmn_tlv *htt_stats_buf = tag_buf;
2740         u8 *buf = stats_req->buf;
2741         u32 len = stats_req->buf_len;
2742         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2743
2744         len += scnprintf(buf + len, buf_len - len, "HTT_SRING_CMN_TLV:\n");
2745         len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
2746                          htt_stats_buf->num_records);
2747
2748         if (len >= buf_len)
2749                 buf[buf_len - 1] = 0;
2750         else
2751                 buf[len] = 0;
2752
2753         stats_req->buf_len = len;
2754 }
2755
2756 static inline void htt_print_tx_pdev_rate_stats_tlv(const void *tag_buf,
2757                                                     struct debug_htt_stats_req *stats_req)
2758 {
2759         const struct htt_tx_pdev_rate_stats_tlv *htt_stats_buf = tag_buf;
2760         u8 *buf = stats_req->buf;
2761         u32 len = stats_req->buf_len;
2762         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2763         u8 j;
2764
2765         len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_RATE_STATS_TLV:\n");
2766         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2767                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2768         len += scnprintf(buf + len, buf_len - len, "tx_ldpc = %u\n",
2769                          htt_stats_buf->tx_ldpc);
2770         len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_tx_ldpc = %u\n",
2771                          htt_stats_buf->ac_mu_mimo_tx_ldpc);
2772         len += scnprintf(buf + len, buf_len - len, "ax_mu_mimo_tx_ldpc = %u\n",
2773                          htt_stats_buf->ax_mu_mimo_tx_ldpc);
2774         len += scnprintf(buf + len, buf_len - len, "ofdma_tx_ldpc = %u\n",
2775                          htt_stats_buf->ofdma_tx_ldpc);
2776         len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n",
2777                          htt_stats_buf->rts_cnt);
2778         len += scnprintf(buf + len, buf_len - len, "rts_success = %u\n",
2779                          htt_stats_buf->rts_success);
2780         len += scnprintf(buf + len, buf_len - len, "ack_rssi = %u\n",
2781                          htt_stats_buf->ack_rssi);
2782
2783         len += scnprintf(buf + len, buf_len - len,
2784                          "Legacy CCK Rates: 1 Mbps: %u, 2 Mbps: %u, 5.5 Mbps: %u, 11 Mbps: %u\n",
2785                          htt_stats_buf->tx_legacy_cck_rate[0],
2786                          htt_stats_buf->tx_legacy_cck_rate[1],
2787                          htt_stats_buf->tx_legacy_cck_rate[2],
2788                          htt_stats_buf->tx_legacy_cck_rate[3]);
2789
2790         len += scnprintf(buf + len, buf_len - len,
2791                          "Legacy OFDM Rates: 6 Mbps: %u, 9 Mbps: %u, 12 Mbps: %u, 18 Mbps: %u\n"
2792                          "                   24 Mbps: %u, 36 Mbps: %u, 48 Mbps: %u, 54 Mbps: %u\n",
2793                          htt_stats_buf->tx_legacy_ofdm_rate[0],
2794                          htt_stats_buf->tx_legacy_ofdm_rate[1],
2795                          htt_stats_buf->tx_legacy_ofdm_rate[2],
2796                          htt_stats_buf->tx_legacy_ofdm_rate[3],
2797                          htt_stats_buf->tx_legacy_ofdm_rate[4],
2798                          htt_stats_buf->tx_legacy_ofdm_rate[5],
2799                          htt_stats_buf->tx_legacy_ofdm_rate[6],
2800                          htt_stats_buf->tx_legacy_ofdm_rate[7]);
2801
2802         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_mcs, "tx_mcs",
2803                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2804         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_mcs,
2805                            "ac_mu_mimo_tx_mcs", HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2806         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_mcs,
2807                            "ax_mu_mimo_tx_mcs", HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2808         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_mcs, "ofdma_tx_mcs",
2809                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2810         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_nss, "tx_nss",
2811                            HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
2812         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_nss,
2813                            "ac_mu_mimo_tx_nss",
2814                            HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
2815         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_nss,
2816                            "ax_mu_mimo_tx_nss",
2817                            HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
2818         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_nss, "ofdma_tx_nss",
2819                            HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
2820         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_bw, "tx_bw",
2821                            HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2822         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_bw,
2823                            "ac_mu_mimo_tx_bw", HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2824         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_bw,
2825                            "ax_mu_mimo_tx_bw",
2826                            HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2827         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_bw, "ofdma_tx_bw",
2828                            HTT_TX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2829         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_stbc, "tx_stbc",
2830                            HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2831         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_pream, "tx_pream",
2832                            HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n");
2833
2834         len += scnprintf(buf + len, buf_len - len, "HE LTF: 1x: %u, 2x: %u, 4x: %u\n",
2835                          htt_stats_buf->tx_he_ltf[1],
2836                          htt_stats_buf->tx_he_ltf[2],
2837                          htt_stats_buf->tx_he_ltf[3]);
2838
2839         /* SU GI Stats */
2840         for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
2841                 len += scnprintf(buf + len, (buf_len - len),
2842                                  "tx_gi[%u] = ", j);
2843                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_gi[j], NULL,
2844                                    HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2845         }
2846
2847         /* AC MU-MIMO GI Stats */
2848         for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
2849                 len += scnprintf(buf + len, (buf_len - len),
2850                                  "ac_mu_mimo_tx_gi[%u] = ", j);
2851                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ac_mu_mimo_tx_gi[j],
2852                                    NULL, HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2853         }
2854
2855         /* AX MU-MIMO GI Stats */
2856         for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
2857                 len += scnprintf(buf + len, (buf_len - len),
2858                                  "ax_mu_mimo_tx_gi[%u] = ", j);
2859                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ax_mu_mimo_tx_gi[j],
2860                                    NULL, HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2861         }
2862
2863         /* DL OFDMA GI Stats */
2864         for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
2865                 len += scnprintf(buf + len, (buf_len - len),
2866                                  "ofdma_tx_gi[%u] = ", j);
2867                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ofdma_tx_gi[j], NULL,
2868                                    HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2869         }
2870
2871         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->tx_dcm, "tx_dcm",
2872                            HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS, "\n\n");
2873
2874         if (len >= buf_len)
2875                 buf[buf_len - 1] = 0;
2876         else
2877                 buf[len] = 0;
2878
2879         stats_req->buf_len = len;
2880 }
2881
2882 static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf,
2883                                                     struct debug_htt_stats_req *stats_req)
2884 {
2885         const struct htt_rx_pdev_rate_stats_tlv *htt_stats_buf = tag_buf;
2886         u8 *buf = stats_req->buf;
2887         u32 len = stats_req->buf_len;
2888         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
2889         u8 i, j;
2890
2891         len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_RATE_STATS_TLV:\n");
2892         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
2893                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
2894         len += scnprintf(buf + len, buf_len - len, "nsts = %u\n",
2895                          htt_stats_buf->nsts);
2896         len += scnprintf(buf + len, buf_len - len, "rx_ldpc = %u\n",
2897                          htt_stats_buf->rx_ldpc);
2898         len += scnprintf(buf + len, buf_len - len, "rts_cnt = %u\n",
2899                          htt_stats_buf->rts_cnt);
2900         len += scnprintf(buf + len, buf_len - len, "rssi_mgmt = %u\n",
2901                          htt_stats_buf->rssi_mgmt);
2902         len += scnprintf(buf + len, buf_len - len, "rssi_data = %u\n",
2903                          htt_stats_buf->rssi_data);
2904         len += scnprintf(buf + len, buf_len - len, "rssi_comb = %u\n",
2905                          htt_stats_buf->rssi_comb);
2906         len += scnprintf(buf + len, buf_len - len, "rssi_in_dbm = %d\n",
2907                          htt_stats_buf->rssi_in_dbm);
2908
2909         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_mcs, "rx_mcs",
2910                            HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2911         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_nss, "rx_nss",
2912                            HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
2913         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_dcm, "rx_dcm",
2914                            HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS, "\n");
2915         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_stbc, "rx_stbc",
2916                            HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2917         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_bw, "rx_bw",
2918                            HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2919
2920         len += scnprintf(buf + len, buf_len - len, "rx_evm_nss_count = %u\n",
2921                          htt_stats_buf->nss_count);
2922
2923         len += scnprintf(buf + len, buf_len - len, "rx_evm_pilot_count = %u\n",
2924                          htt_stats_buf->pilot_count);
2925
2926         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
2927                 len += scnprintf(buf + len, buf_len - len,
2928                                  "pilot_evm_db[%u] = ", j);
2929                 for (i = 0; i < HTT_RX_PDEV_STATS_RXEVM_MAX_PILOTS_PER_NSS; i++)
2930                         len += scnprintf(buf + len,
2931                                          buf_len - len,
2932                                          " %u:%d,",
2933                                          i,
2934                                          htt_stats_buf->rx_pilot_evm_db[j][i]);
2935                 len += scnprintf(buf + len, buf_len - len, "\n");
2936         }
2937
2938         len += scnprintf(buf + len, buf_len - len,
2939                          "pilot_evm_db_mean = ");
2940         for (i = 0; i < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
2941                 len += scnprintf(buf + len,
2942                                  buf_len - len,
2943                                  " %u:%d,", i,
2944                                  htt_stats_buf->rx_pilot_evm_db_mean[i]);
2945         len += scnprintf(buf + len, buf_len - len, "\n");
2946
2947         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
2948                 len += scnprintf(buf + len, buf_len - len,
2949                                  "rssi_chain[%u] = ", j);
2950                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rssi_chain[j], NULL,
2951                                    HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
2952         }
2953
2954         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
2955                 len += scnprintf(buf + len, buf_len - len,
2956                                  "rx_gi[%u] = ", j);
2957                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_gi[j], NULL,
2958                                    HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
2959         }
2960
2961         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_pream, "rx_pream",
2962                            HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES, "\n");
2963
2964         len += scnprintf(buf + len, buf_len - len, "rx_11ax_su_ext = %u\n",
2965                          htt_stats_buf->rx_11ax_su_ext);
2966         len += scnprintf(buf + len, buf_len - len, "rx_11ac_mumimo = %u\n",
2967                          htt_stats_buf->rx_11ac_mumimo);
2968         len += scnprintf(buf + len, buf_len - len, "rx_11ax_mumimo = %u\n",
2969                          htt_stats_buf->rx_11ax_mumimo);
2970         len += scnprintf(buf + len, buf_len - len, "rx_11ax_ofdma = %u\n",
2971                          htt_stats_buf->rx_11ax_ofdma);
2972         len += scnprintf(buf + len, buf_len - len, "txbf = %u\n",
2973                          htt_stats_buf->txbf);
2974
2975         len += scnprintf(buf + len, buf_len - len, "\nrx_su_ndpa = %u",
2976                          htt_stats_buf->rx_su_ndpa);
2977         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_su_txbf_mcs,
2978                            "rx_11ax_su_txbf_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS,
2979                            "\n");
2980
2981         len += scnprintf(buf + len, buf_len - len, "\nrx_mu_ndpa = %u",
2982                          htt_stats_buf->rx_mu_ndpa);
2983         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_mu_txbf_mcs,
2984                            "rx_11ax_mu_txbf_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS,
2985                            "\n");
2986
2987         len += scnprintf(buf + len, buf_len - len, "\nrx_br_poll = %u",
2988                          htt_stats_buf->rx_br_poll);
2989
2990         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_legacy_cck_rate,
2991                            "rx_legacy_cck_rate",
2992                            HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS, "\n");
2993
2994         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_legacy_ofdm_rate,
2995                            "rx_legacy_ofdm_rate",
2996                            HTT_RX_PDEV_STATS_NUM_LEGACY_OFDM_STATS, "\n");
2997
2998         len += scnprintf(buf + len, buf_len - len, "rx_active_dur_us_low = %u\n",
2999                          htt_stats_buf->rx_active_dur_us_low);
3000         len += scnprintf(buf + len, buf_len - len, "rx_active_dur_us_high = %u\n",
3001                          htt_stats_buf->rx_active_dur_us_high);
3002         len += scnprintf(buf + len, buf_len - len, "rx_11ax_ul_ofdma = %u\n",
3003                          htt_stats_buf->rx_11ax_ul_ofdma);
3004
3005         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_mcs,
3006                            "ul_ofdma_rx_mcs",
3007                            HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
3008
3009         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
3010                 len += scnprintf(buf + len, buf_len - len,
3011                                  "ul_ofdma_rx_gi[%u] = ", j);
3012                 PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_gi[j], NULL,
3013                                    HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, "\n");
3014         }
3015
3016         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_nss,
3017                            "ul_ofdma_rx_nss",
3018                            HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS, "\n");
3019
3020         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->ul_ofdma_rx_bw, "ul_ofdma_rx_bw",
3021                            HTT_RX_PDEV_STATS_NUM_BW_COUNTERS, "\n");
3022
3023         len += scnprintf(buf + len, buf_len - len, "ul_ofdma_rx_stbc = %u\n",
3024                         htt_stats_buf->ul_ofdma_rx_stbc);
3025         len += scnprintf(buf + len, buf_len - len, "ul_ofdma_rx_ldpc = %u\n",
3026                         htt_stats_buf->ul_ofdma_rx_ldpc);
3027
3028         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_non_data_ppdu,
3029                            "rx_ulofdma_non_data_ppdu",
3030                            HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n");
3031
3032         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_data_ppdu,
3033                            "rx_ulofdma_data_ppdu", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n");
3034
3035         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_mpdu_ok,
3036                            "rx_ulofdma_mpdu_ok", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n");
3037
3038         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_mpdu_fail,
3039                            "rx_ulofdma_mpdu_fail", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, "\n");
3040
3041         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
3042                 len += scnprintf(buf + len, buf_len - len,
3043                                  "rx_ul_fd_rssi: nss[%u] = ", j);
3044                 for (i = 0; i < HTT_RX_PDEV_MAX_OFDMA_NUM_USER; i++)
3045                         len += scnprintf(buf + len,
3046                                          buf_len - len,
3047                                          " %u:%d,",
3048                                          i, htt_stats_buf->rx_ul_fd_rssi[j][i]);
3049                 len += scnprintf(buf + len, buf_len - len, "\n");
3050         }
3051
3052         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_non_data_nusers,
3053                            "rx_ulofdma_non_data_nusers", HTT_RX_PDEV_MAX_OFDMA_NUM_USER,
3054                            "\n");
3055
3056         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_data_nusers,
3057                            "rx_ulofdma_data_nusers", HTT_RX_PDEV_MAX_OFDMA_NUM_USER,
3058                            "\n");
3059
3060         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_dl_ofdma_mcs,
3061                            "rx_11ax_dl_ofdma_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS,
3062                            "\n");
3063
3064         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_dl_ofdma_ru,
3065                            "rx_11ax_dl_ofdma_ru", HTT_RX_PDEV_STATS_NUM_RU_SIZE_COUNTERS,
3066                            "\n");
3067
3068         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_non_data_ppdu,
3069                            "rx_ulmumimo_non_data_ppdu", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER,
3070                            "\n");
3071
3072         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_data_ppdu,
3073                            "rx_ulmumimo_data_ppdu", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER,
3074                            "\n");
3075
3076         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_mpdu_ok,
3077                            "rx_ulmumimo_mpdu_ok", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER,
3078                            "\n");
3079
3080         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_mpdu_fail,
3081                            "rx_ulmumimo_mpdu_fail", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER,
3082                            "\n");
3083
3084         len += scnprintf(buf + len, buf_len - len, "per_chain_rssi_pkt_type = %#x\n",
3085                          htt_stats_buf->per_chain_rssi_pkt_type);
3086
3087         for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
3088                 len += scnprintf(buf + len, buf_len - len,
3089                                  "rx_per_chain_rssi_in_dbm[%u] = ", j);
3090                 for (i = 0; i < HTT_RX_PDEV_STATS_NUM_BW_COUNTERS; i++)
3091                         len += scnprintf(buf + len,
3092                                          buf_len - len,
3093                                          " %u:%d,",
3094                                          i,
3095                                          htt_stats_buf->rx_per_chain_rssi_in_dbm[j][i]);
3096                 len += scnprintf(buf + len, buf_len - len, "\n");
3097         }
3098         len += scnprintf(buf + len, buf_len - len, "\n");
3099
3100         if (len >= buf_len)
3101                 buf[buf_len - 1] = 0;
3102         else
3103                 buf[len] = 0;
3104
3105         stats_req->buf_len = len;
3106 }
3107
3108 static inline void htt_print_rx_soc_fw_stats_tlv(const void *tag_buf,
3109                                                  struct debug_htt_stats_req *stats_req)
3110 {
3111         const struct htt_rx_soc_fw_stats_tlv *htt_stats_buf = tag_buf;
3112         u8 *buf = stats_req->buf;
3113         u32 len = stats_req->buf_len;
3114         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3115
3116         len += scnprintf(buf + len, buf_len - len, "HTT_RX_SOC_FW_STATS_TLV:\n");
3117         len += scnprintf(buf + len, buf_len - len, "fw_reo_ring_data_msdu = %u\n",
3118                          htt_stats_buf->fw_reo_ring_data_msdu);
3119         len += scnprintf(buf + len, buf_len - len, "fw_to_host_data_msdu_bcmc = %u\n",
3120                          htt_stats_buf->fw_to_host_data_msdu_bcmc);
3121         len += scnprintf(buf + len, buf_len - len, "fw_to_host_data_msdu_uc = %u\n",
3122                          htt_stats_buf->fw_to_host_data_msdu_uc);
3123         len += scnprintf(buf + len, buf_len - len,
3124                          "ofld_remote_data_buf_recycle_cnt = %u\n",
3125                          htt_stats_buf->ofld_remote_data_buf_recycle_cnt);
3126         len += scnprintf(buf + len, buf_len - len,
3127                          "ofld_remote_free_buf_indication_cnt = %u\n",
3128                          htt_stats_buf->ofld_remote_free_buf_indication_cnt);
3129         len += scnprintf(buf + len, buf_len - len,
3130                          "ofld_buf_to_host_data_msdu_uc = %u\n",
3131                          htt_stats_buf->ofld_buf_to_host_data_msdu_uc);
3132         len += scnprintf(buf + len, buf_len - len,
3133                          "reo_fw_ring_to_host_data_msdu_uc = %u\n",
3134                          htt_stats_buf->reo_fw_ring_to_host_data_msdu_uc);
3135         len += scnprintf(buf + len, buf_len - len, "wbm_sw_ring_reap = %u\n",
3136                          htt_stats_buf->wbm_sw_ring_reap);
3137         len += scnprintf(buf + len, buf_len - len, "wbm_forward_to_host_cnt = %u\n",
3138                          htt_stats_buf->wbm_forward_to_host_cnt);
3139         len += scnprintf(buf + len, buf_len - len, "wbm_target_recycle_cnt = %u\n",
3140                          htt_stats_buf->wbm_target_recycle_cnt);
3141         len += scnprintf(buf + len, buf_len - len,
3142                          "target_refill_ring_recycle_cnt = %u\n",
3143                          htt_stats_buf->target_refill_ring_recycle_cnt);
3144
3145         if (len >= buf_len)
3146                 buf[buf_len - 1] = 0;
3147         else
3148                 buf[len] = 0;
3149
3150         stats_req->buf_len = len;
3151 }
3152
3153 static inline void
3154 htt_print_rx_soc_fw_refill_ring_empty_tlv_v(const void *tag_buf,
3155                                             u16 tag_len,
3156                                             struct debug_htt_stats_req *stats_req)
3157 {
3158         const struct htt_rx_soc_fw_refill_ring_empty_tlv_v *htt_stats_buf = tag_buf;
3159         u8 *buf = stats_req->buf;
3160         u32 len = stats_req->buf_len;
3161         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3162         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_REFILL_MAX_RING);
3163
3164         len += scnprintf(buf + len, buf_len - len,
3165                          "HTT_RX_SOC_FW_REFILL_RING_EMPTY_TLV_V:\n");
3166
3167         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->refill_ring_empty_cnt,
3168                            "refill_ring_empty_cnt", num_elems, "\n\n");
3169
3170         if (len >= buf_len)
3171                 buf[buf_len - 1] = 0;
3172         else
3173                 buf[len] = 0;
3174
3175         stats_req->buf_len = len;
3176 }
3177
3178 static inline void
3179 htt_print_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v(const void *tag_buf,
3180                                                     u16 tag_len,
3181                                                     struct debug_htt_stats_req *stats_req)
3182 {
3183         const struct htt_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v *htt_stats_buf =
3184                 tag_buf;
3185         u8 *buf = stats_req->buf;
3186         u32 len = stats_req->buf_len;
3187         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3188         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_RXDMA_MAX_ERR_CODE);
3189
3190         len += scnprintf(buf + len, buf_len - len,
3191                          "HTT_RX_SOC_FW_REFILL_RING_NUM_RXDMA_ERR_TLV_V:\n");
3192
3193         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rxdma_err, "rxdma_err",
3194                            num_elems, "\n\n");
3195
3196         if (len >= buf_len)
3197                 buf[buf_len - 1] = 0;
3198         else
3199                 buf[len] = 0;
3200
3201         stats_req->buf_len = len;
3202 }
3203
3204 static inline void
3205 htt_print_rx_soc_fw_refill_ring_num_reo_err_tlv_v(const void *tag_buf,
3206                                                   u16 tag_len,
3207                                                   struct debug_htt_stats_req *stats_req)
3208 {
3209         const struct htt_rx_soc_fw_refill_ring_num_reo_err_tlv_v *htt_stats_buf = tag_buf;
3210         u8 *buf = stats_req->buf;
3211         u32 len = stats_req->buf_len;
3212         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3213         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_REO_MAX_ERR_CODE);
3214
3215         len += scnprintf(buf + len, buf_len - len,
3216                          "HTT_RX_SOC_FW_REFILL_RING_NUM_REO_ERR_TLV_V:\n");
3217
3218         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->reo_err, "reo_err",
3219                            num_elems, "\n\n");
3220
3221         if (len >= buf_len)
3222                 buf[buf_len - 1] = 0;
3223         else
3224                 buf[len] = 0;
3225
3226         stats_req->buf_len = len;
3227 }
3228
3229 static inline void
3230 htt_print_rx_reo_debug_stats_tlv_v(const void *tag_buf,
3231                                    struct debug_htt_stats_req *stats_req)
3232 {
3233         const struct htt_rx_reo_resource_stats_tlv_v *htt_stats_buf = tag_buf;
3234         u8 *buf = stats_req->buf;
3235         u32 len = stats_req->buf_len;
3236         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3237
3238         len += scnprintf(buf + len, buf_len - len, "HTT_RX_REO_RESOURCE_STATS_TLV:\n");
3239         len += scnprintf(buf + len, buf_len - len, "sample_id = %u\n",
3240                          htt_stats_buf->sample_id);
3241         len += scnprintf(buf + len, buf_len - len, "total_max = %u\n",
3242                          htt_stats_buf->total_max);
3243         len += scnprintf(buf + len, buf_len - len, "total_avg = %u\n",
3244                          htt_stats_buf->total_avg);
3245         len += scnprintf(buf + len, buf_len - len, "total_sample = %u\n",
3246                          htt_stats_buf->total_sample);
3247         len += scnprintf(buf + len, buf_len - len, "non_zeros_avg = %u\n",
3248                          htt_stats_buf->non_zeros_avg);
3249         len += scnprintf(buf + len, buf_len - len, "non_zeros_sample = %u\n",
3250                          htt_stats_buf->non_zeros_sample);
3251         len += scnprintf(buf + len, buf_len - len, "last_non_zeros_max = %u\n",
3252                          htt_stats_buf->last_non_zeros_max);
3253         len += scnprintf(buf + len, buf_len - len, "last_non_zeros_min %u\n",
3254                          htt_stats_buf->last_non_zeros_min);
3255         len += scnprintf(buf + len, buf_len - len, "last_non_zeros_avg %u\n",
3256                          htt_stats_buf->last_non_zeros_avg);
3257         len += scnprintf(buf + len, buf_len - len, "last_non_zeros_sample %u\n\n",
3258                          htt_stats_buf->last_non_zeros_sample);
3259
3260         if (len >= buf_len)
3261                 buf[buf_len - 1] = 0;
3262         else
3263                 buf[len] = 0;
3264
3265         stats_req->buf_len = len;
3266 }
3267
3268 static inline void
3269 htt_print_rx_soc_fw_refill_ring_num_refill_tlv_v(const void *tag_buf,
3270                                                  u16 tag_len,
3271                                                  struct debug_htt_stats_req *stats_req)
3272 {
3273         const struct htt_rx_soc_fw_refill_ring_num_refill_tlv_v *htt_stats_buf = tag_buf;
3274         u8 *buf = stats_req->buf;
3275         u32 len = stats_req->buf_len;
3276         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3277         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_REFILL_MAX_RING);
3278
3279         len += scnprintf(buf + len, buf_len - len,
3280                          "HTT_RX_SOC_FW_REFILL_RING_NUM_REFILL_TLV_V:\n");
3281
3282         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->refill_ring_num_refill,
3283                            "refill_ring_num_refill", num_elems, "\n\n");
3284
3285         if (len >= buf_len)
3286                 buf[buf_len - 1] = 0;
3287         else
3288                 buf[len] = 0;
3289
3290         stats_req->buf_len = len;
3291 }
3292
3293 static inline void htt_print_rx_pdev_fw_stats_tlv(const void *tag_buf,
3294                                                   struct debug_htt_stats_req *stats_req)
3295 {
3296         const struct htt_rx_pdev_fw_stats_tlv *htt_stats_buf = tag_buf;
3297         u8 *buf = stats_req->buf;
3298         u32 len = stats_req->buf_len;
3299         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3300
3301         len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n");
3302         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
3303                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
3304         len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n",
3305                          htt_stats_buf->ppdu_recvd);
3306         len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n",
3307                          htt_stats_buf->mpdu_cnt_fcs_ok);
3308         len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_err = %u\n",
3309                          htt_stats_buf->mpdu_cnt_fcs_err);
3310         len += scnprintf(buf + len, buf_len - len, "tcp_msdu_cnt = %u\n",
3311                          htt_stats_buf->tcp_msdu_cnt);
3312         len += scnprintf(buf + len, buf_len - len, "tcp_ack_msdu_cnt = %u\n",
3313                          htt_stats_buf->tcp_ack_msdu_cnt);
3314         len += scnprintf(buf + len, buf_len - len, "udp_msdu_cnt = %u\n",
3315                          htt_stats_buf->udp_msdu_cnt);
3316         len += scnprintf(buf + len, buf_len - len, "other_msdu_cnt = %u\n",
3317                          htt_stats_buf->other_msdu_cnt);
3318         len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u\n",
3319                          htt_stats_buf->fw_ring_mpdu_ind);
3320
3321         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_mgmt_subtype,
3322                            "fw_ring_mgmt_subtype", HTT_STATS_SUBTYPE_MAX, "\n");
3323
3324         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_ctrl_subtype,
3325                            "fw_ring_ctrl_subtype", HTT_STATS_SUBTYPE_MAX, "\n");
3326
3327         len += scnprintf(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u\n",
3328                          htt_stats_buf->fw_ring_mcast_data_msdu);
3329         len += scnprintf(buf + len, buf_len - len, "fw_ring_bcast_data_msdu = %u\n",
3330                          htt_stats_buf->fw_ring_bcast_data_msdu);
3331         len += scnprintf(buf + len, buf_len - len, "fw_ring_ucast_data_msdu = %u\n",
3332                          htt_stats_buf->fw_ring_ucast_data_msdu);
3333         len += scnprintf(buf + len, buf_len - len, "fw_ring_null_data_msdu = %u\n",
3334                          htt_stats_buf->fw_ring_null_data_msdu);
3335         len += scnprintf(buf + len, buf_len - len, "fw_ring_mpdu_drop = %u\n",
3336                          htt_stats_buf->fw_ring_mpdu_drop);
3337         len += scnprintf(buf + len, buf_len - len, "ofld_local_data_ind_cnt = %u\n",
3338                          htt_stats_buf->ofld_local_data_ind_cnt);
3339         len += scnprintf(buf + len, buf_len - len,
3340                          "ofld_local_data_buf_recycle_cnt = %u\n",
3341                          htt_stats_buf->ofld_local_data_buf_recycle_cnt);
3342         len += scnprintf(buf + len, buf_len - len, "drx_local_data_ind_cnt = %u\n",
3343                          htt_stats_buf->drx_local_data_ind_cnt);
3344         len += scnprintf(buf + len, buf_len - len,
3345                          "drx_local_data_buf_recycle_cnt = %u\n",
3346                          htt_stats_buf->drx_local_data_buf_recycle_cnt);
3347         len += scnprintf(buf + len, buf_len - len, "local_nondata_ind_cnt = %u\n",
3348                          htt_stats_buf->local_nondata_ind_cnt);
3349         len += scnprintf(buf + len, buf_len - len, "local_nondata_buf_recycle_cnt = %u\n",
3350                          htt_stats_buf->local_nondata_buf_recycle_cnt);
3351         len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_refill_cnt = %u\n",
3352                          htt_stats_buf->fw_status_buf_ring_refill_cnt);
3353         len += scnprintf(buf + len, buf_len - len, "fw_status_buf_ring_empty_cnt = %u\n",
3354                          htt_stats_buf->fw_status_buf_ring_empty_cnt);
3355         len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_refill_cnt = %u\n",
3356                          htt_stats_buf->fw_pkt_buf_ring_refill_cnt);
3357         len += scnprintf(buf + len, buf_len - len, "fw_pkt_buf_ring_empty_cnt = %u\n",
3358                          htt_stats_buf->fw_pkt_buf_ring_empty_cnt);
3359         len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_refill_cnt = %u\n",
3360                          htt_stats_buf->fw_link_buf_ring_refill_cnt);
3361         len += scnprintf(buf + len, buf_len - len, "fw_link_buf_ring_empty_cnt = %u\n",
3362                          htt_stats_buf->fw_link_buf_ring_empty_cnt);
3363         len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_refill_cnt = %u\n",
3364                          htt_stats_buf->host_pkt_buf_ring_refill_cnt);
3365         len += scnprintf(buf + len, buf_len - len, "host_pkt_buf_ring_empty_cnt = %u\n",
3366                          htt_stats_buf->host_pkt_buf_ring_empty_cnt);
3367         len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_refill_cnt = %u\n",
3368                          htt_stats_buf->mon_pkt_buf_ring_refill_cnt);
3369         len += scnprintf(buf + len, buf_len - len, "mon_pkt_buf_ring_empty_cnt = %u\n",
3370                          htt_stats_buf->mon_pkt_buf_ring_empty_cnt);
3371         len += scnprintf(buf + len, buf_len - len,
3372                          "mon_status_buf_ring_refill_cnt = %u\n",
3373                          htt_stats_buf->mon_status_buf_ring_refill_cnt);
3374         len += scnprintf(buf + len, buf_len - len, "mon_status_buf_ring_empty_cnt = %u\n",
3375                          htt_stats_buf->mon_status_buf_ring_empty_cnt);
3376         len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_refill_cnt = %u\n",
3377                          htt_stats_buf->mon_desc_buf_ring_refill_cnt);
3378         len += scnprintf(buf + len, buf_len - len, "mon_desc_buf_ring_empty_cnt = %u\n",
3379                          htt_stats_buf->mon_desc_buf_ring_empty_cnt);
3380         len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_update_cnt = %u\n",
3381                          htt_stats_buf->mon_dest_ring_update_cnt);
3382         len += scnprintf(buf + len, buf_len - len, "mon_dest_ring_full_cnt = %u\n",
3383                          htt_stats_buf->mon_dest_ring_full_cnt);
3384         len += scnprintf(buf + len, buf_len - len, "rx_suspend_cnt = %u\n",
3385                          htt_stats_buf->rx_suspend_cnt);
3386         len += scnprintf(buf + len, buf_len - len, "rx_suspend_fail_cnt = %u\n",
3387                          htt_stats_buf->rx_suspend_fail_cnt);
3388         len += scnprintf(buf + len, buf_len - len, "rx_resume_cnt = %u\n",
3389                          htt_stats_buf->rx_resume_cnt);
3390         len += scnprintf(buf + len, buf_len - len, "rx_resume_fail_cnt = %u\n",
3391                          htt_stats_buf->rx_resume_fail_cnt);
3392         len += scnprintf(buf + len, buf_len - len, "rx_ring_switch_cnt = %u\n",
3393                          htt_stats_buf->rx_ring_switch_cnt);
3394         len += scnprintf(buf + len, buf_len - len, "rx_ring_restore_cnt = %u\n",
3395                          htt_stats_buf->rx_ring_restore_cnt);
3396         len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n",
3397                          htt_stats_buf->rx_flush_cnt);
3398         len += scnprintf(buf + len, buf_len - len, "rx_recovery_reset_cnt = %u\n\n",
3399                          htt_stats_buf->rx_recovery_reset_cnt);
3400
3401         if (len >= buf_len)
3402                 buf[buf_len - 1] = 0;
3403         else
3404                 buf[len] = 0;
3405
3406         stats_req->buf_len = len;
3407 }
3408
3409 static inline void
3410 htt_print_rx_pdev_fw_ring_mpdu_err_tlv_v(const void *tag_buf,
3411                                          struct debug_htt_stats_req *stats_req)
3412 {
3413         const struct htt_rx_pdev_fw_ring_mpdu_err_tlv_v *htt_stats_buf = tag_buf;
3414         u8 *buf = stats_req->buf;
3415         u32 len = stats_req->buf_len;
3416         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3417
3418         len += scnprintf(buf + len, buf_len - len,
3419                          "HTT_RX_PDEV_FW_RING_MPDU_ERR_TLV_V:\n");
3420
3421         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_ring_mpdu_err,
3422                            "fw_ring_mpdu_err", HTT_RX_STATS_RXDMA_MAX_ERR, "\n");
3423
3424         if (len >= buf_len)
3425                 buf[buf_len - 1] = 0;
3426         else
3427                 buf[len] = 0;
3428
3429         stats_req->buf_len = len;
3430 }
3431
3432 static inline void
3433 htt_print_rx_pdev_fw_mpdu_drop_tlv_v(const void *tag_buf,
3434                                      u16 tag_len,
3435                                      struct debug_htt_stats_req *stats_req)
3436 {
3437         const struct htt_rx_pdev_fw_mpdu_drop_tlv_v *htt_stats_buf = tag_buf;
3438         u8 *buf = stats_req->buf;
3439         u32 len = stats_req->buf_len;
3440         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3441         u16 num_elems = min_t(u16, (tag_len >> 2), HTT_RX_STATS_FW_DROP_REASON_MAX);
3442
3443         len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_MPDU_DROP_TLV_V:\n");
3444
3445         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->fw_mpdu_drop, "fw_mpdu_drop",
3446                            num_elems, "\n\n");
3447
3448         if (len >= buf_len)
3449                 buf[buf_len - 1] = 0;
3450         else
3451                 buf[len] = 0;
3452
3453         stats_req->buf_len = len;
3454 }
3455
3456 static inline void
3457 htt_print_rx_pdev_fw_stats_phy_err_tlv(const void *tag_buf,
3458                                        struct debug_htt_stats_req *stats_req)
3459 {
3460         const struct htt_rx_pdev_fw_stats_phy_err_tlv *htt_stats_buf = tag_buf;
3461         u8 *buf = stats_req->buf;
3462         u32 len = stats_req->buf_len;
3463         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3464
3465         len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_PHY_ERR_TLV:\n");
3466         len += scnprintf(buf + len, buf_len - len, "mac_id__word = %u\n",
3467                          htt_stats_buf->mac_id__word);
3468         len += scnprintf(buf + len, buf_len - len, "total_phy_err_nct = %u\n",
3469                          htt_stats_buf->total_phy_err_cnt);
3470
3471         PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->phy_err, "phy_errs",
3472                            HTT_STATS_PHY_ERR_MAX, "\n\n");
3473
3474         if (len >= buf_len)
3475                 buf[buf_len - 1] = 0;
3476         else
3477                 buf[len] = 0;
3478
3479         stats_req->buf_len = len;
3480 }
3481
3482 static inline void
3483 htt_print_pdev_cca_stats_hist_tlv(const void *tag_buf,
3484                                   struct debug_htt_stats_req *stats_req)
3485 {
3486         const struct htt_pdev_cca_stats_hist_v1_tlv *htt_stats_buf = tag_buf;
3487         u8 *buf = stats_req->buf;
3488         u32 len = stats_req->buf_len;
3489         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3490
3491         len += scnprintf(buf + len, buf_len - len, "\nHTT_PDEV_CCA_STATS_HIST_TLV:\n");
3492         len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
3493                          htt_stats_buf->chan_num);
3494         len += scnprintf(buf + len, buf_len - len, "num_records = %u\n",
3495                          htt_stats_buf->num_records);
3496         len += scnprintf(buf + len, buf_len - len, "valid_cca_counters_bitmap = 0x%x\n",
3497                          htt_stats_buf->valid_cca_counters_bitmap);
3498         len += scnprintf(buf + len, buf_len - len, "collection_interval = %u\n\n",
3499                          htt_stats_buf->collection_interval);
3500
3501         len += scnprintf(buf + len, buf_len - len,
3502                          "HTT_PDEV_STATS_CCA_COUNTERS_TLV:(in usec)\n");
3503         len += scnprintf(buf + len, buf_len - len,
3504                          "|  tx_frame|   rx_frame|   rx_clear| my_rx_frame|        cnt| med_rx_idle| med_tx_idle_global|   cca_obss|\n");
3505
3506         if (len >= buf_len)
3507                 buf[buf_len - 1] = 0;
3508         else
3509                 buf[len] = 0;
3510
3511         stats_req->buf_len = len;
3512 }
3513
3514 static inline void
3515 htt_print_pdev_stats_cca_counters_tlv(const void *tag_buf,
3516                                       struct debug_htt_stats_req *stats_req)
3517 {
3518         const struct htt_pdev_stats_cca_counters_tlv *htt_stats_buf = tag_buf;
3519         u8 *buf = stats_req->buf;
3520         u32 len = stats_req->buf_len;
3521         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3522
3523         len += scnprintf(buf + len, buf_len - len,
3524                          "|%10u| %10u| %10u| %11u| %10u| %11u| %18u| %10u|\n",
3525                          htt_stats_buf->tx_frame_usec,
3526                          htt_stats_buf->rx_frame_usec,
3527                          htt_stats_buf->rx_clear_usec,
3528                          htt_stats_buf->my_rx_frame_usec,
3529                          htt_stats_buf->usec_cnt,
3530                          htt_stats_buf->med_rx_idle_usec,
3531                          htt_stats_buf->med_tx_idle_global_usec,
3532                          htt_stats_buf->cca_obss_usec);
3533
3534         if (len >= buf_len)
3535                 buf[buf_len - 1] = 0;
3536         else
3537                 buf[len] = 0;
3538
3539         stats_req->buf_len = len;
3540 }
3541
3542 static inline void htt_print_hw_stats_whal_tx_tlv(const void *tag_buf,
3543                                                   struct debug_htt_stats_req *stats_req)
3544 {
3545         const struct htt_hw_stats_whal_tx_tlv *htt_stats_buf = tag_buf;
3546         u8 *buf = stats_req->buf;
3547         u32 len = stats_req->buf_len;
3548         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3549
3550         len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n");
3551         len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
3552                          FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
3553         len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n",
3554                          htt_stats_buf->last_unpause_ppdu_id);
3555         len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n",
3556                          htt_stats_buf->hwsch_unpause_wait_tqm_write);
3557         len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n",
3558                          htt_stats_buf->hwsch_dummy_tlv_skipped);
3559         len += scnprintf(buf + len, buf_len - len,
3560                          "hwsch_misaligned_offset_received = %u\n",
3561                          htt_stats_buf->hwsch_misaligned_offset_received);
3562         len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n",
3563                          htt_stats_buf->hwsch_reset_count);
3564         len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n",
3565                          htt_stats_buf->hwsch_dev_reset_war);
3566         len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n",
3567                          htt_stats_buf->hwsch_delayed_pause);
3568         len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n",
3569                          htt_stats_buf->hwsch_long_delayed_pause);
3570         len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n",
3571                          htt_stats_buf->sch_rx_ppdu_no_response);
3572         len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n",
3573                          htt_stats_buf->sch_selfgen_response);
3574         len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n",
3575                          htt_stats_buf->sch_rx_sifs_resp_trigger);
3576
3577         if (len >= buf_len)
3578                 buf[buf_len - 1] = 0;
3579         else
3580                 buf[len] = 0;
3581
3582         stats_req->buf_len = len;
3583 }
3584
3585 static inline void
3586 htt_print_pdev_stats_twt_sessions_tlv(const void *tag_buf,
3587                                       struct debug_htt_stats_req *stats_req)
3588 {
3589         const struct htt_pdev_stats_twt_sessions_tlv *htt_stats_buf = tag_buf;
3590         u8 *buf = stats_req->buf;
3591         u32 len = stats_req->buf_len;
3592         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3593
3594         len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSIONS_TLV:\n");
3595         len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3596                          htt_stats_buf->pdev_id);
3597         len += scnprintf(buf + len, buf_len - len, "num_sessions = %u\n\n",
3598                          htt_stats_buf->num_sessions);
3599
3600         if (len >= buf_len)
3601                 buf[buf_len - 1] = 0;
3602         else
3603                 buf[len] = 0;
3604
3605         stats_req->buf_len = len;
3606 }
3607
3608 static inline void
3609 htt_print_pdev_stats_twt_session_tlv(const void *tag_buf,
3610                                      struct debug_htt_stats_req *stats_req)
3611 {
3612         const struct htt_pdev_stats_twt_session_tlv *htt_stats_buf = tag_buf;
3613         u8 *buf = stats_req->buf;
3614         u32 len = stats_req->buf_len;
3615         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3616
3617         len += scnprintf(buf + len, buf_len - len, "HTT_PDEV_STATS_TWT_SESSION_TLV:\n");
3618         len += scnprintf(buf + len, buf_len - len, "vdev_id = %u\n",
3619                          htt_stats_buf->vdev_id);
3620         len += scnprintf(buf + len, buf_len - len,
3621                          "peer_mac = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
3622                          FIELD_GET(HTT_MAC_ADDR_L32_0,
3623                                    htt_stats_buf->peer_mac.mac_addr_l32),
3624                          FIELD_GET(HTT_MAC_ADDR_L32_1,
3625                                    htt_stats_buf->peer_mac.mac_addr_l32),
3626                          FIELD_GET(HTT_MAC_ADDR_L32_2,
3627                                    htt_stats_buf->peer_mac.mac_addr_l32),
3628                          FIELD_GET(HTT_MAC_ADDR_L32_3,
3629                                    htt_stats_buf->peer_mac.mac_addr_l32),
3630                          FIELD_GET(HTT_MAC_ADDR_H16_0,
3631                                    htt_stats_buf->peer_mac.mac_addr_h16),
3632                          FIELD_GET(HTT_MAC_ADDR_H16_1,
3633                                    htt_stats_buf->peer_mac.mac_addr_h16));
3634         len += scnprintf(buf + len, buf_len - len, "flow_id_flags = %u\n",
3635                          htt_stats_buf->flow_id_flags);
3636         len += scnprintf(buf + len, buf_len - len, "dialog_id = %u\n",
3637                          htt_stats_buf->dialog_id);
3638         len += scnprintf(buf + len, buf_len - len, "wake_dura_us = %u\n",
3639                          htt_stats_buf->wake_dura_us);
3640         len += scnprintf(buf + len, buf_len - len, "wake_intvl_us = %u\n",
3641                          htt_stats_buf->wake_intvl_us);
3642         len += scnprintf(buf + len, buf_len - len, "sp_offset_us = %u\n\n",
3643                          htt_stats_buf->sp_offset_us);
3644
3645         if (len >= buf_len)
3646                 buf[buf_len - 1] = 0;
3647         else
3648                 buf[len] = 0;
3649
3650         stats_req->buf_len = len;
3651 }
3652
3653 static inline void
3654 htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf,
3655                                    struct debug_htt_stats_req *stats_req)
3656 {
3657         const struct htt_pdev_obss_pd_stats_tlv *htt_stats_buf = tag_buf;
3658         u8 *buf = stats_req->buf;
3659         u32 len = stats_req->buf_len;
3660         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3661
3662         len += scnprintf(buf + len, buf_len - len, "OBSS Tx success PPDU = %u\n",
3663                            htt_stats_buf->num_obss_tx_ppdu_success);
3664         len += scnprintf(buf + len, buf_len - len, "OBSS Tx failures PPDU = %u\n",
3665                            htt_stats_buf->num_obss_tx_ppdu_failure);
3666         len += scnprintf(buf + len, buf_len - len, "Non-SRG Opportunities = %u\n",
3667                            htt_stats_buf->num_non_srg_opportunities);
3668         len += scnprintf(buf + len, buf_len - len, "Non-SRG tried PPDU = %u\n",
3669                            htt_stats_buf->num_non_srg_ppdu_tried);
3670         len += scnprintf(buf + len, buf_len - len, "Non-SRG success PPDU = %u\n",
3671                            htt_stats_buf->num_non_srg_ppdu_success);
3672         len += scnprintf(buf + len, buf_len - len, "SRG Opportunities = %u\n",
3673                            htt_stats_buf->num_srg_opportunities);
3674         len += scnprintf(buf + len, buf_len - len, "SRG tried PPDU = %u\n",
3675                            htt_stats_buf->num_srg_ppdu_tried);
3676         len += scnprintf(buf + len, buf_len - len, "SRG success PPDU = %u\n\n",
3677                            htt_stats_buf->num_srg_ppdu_success);
3678
3679         if (len >= buf_len)
3680                 buf[buf_len - 1] = 0;
3681         else
3682                 buf[len] = 0;
3683
3684         stats_req->buf_len = len;
3685 }
3686
3687 static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf,
3688                                                       u8 *data)
3689 {
3690         struct debug_htt_stats_req *stats_req =
3691                         (struct debug_htt_stats_req *)data;
3692         struct htt_ring_backpressure_stats_tlv *htt_stats_buf =
3693                         (struct htt_ring_backpressure_stats_tlv *)tag_buf;
3694         int i;
3695         u8 *buf = stats_req->buf;
3696         u32 len = stats_req->buf_len;
3697         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3698
3699         len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
3700                          htt_stats_buf->pdev_id);
3701         len += scnprintf(buf + len, buf_len - len, "current_head_idx = %u\n",
3702                          htt_stats_buf->current_head_idx);
3703         len += scnprintf(buf + len, buf_len - len, "current_tail_idx = %u\n",
3704                          htt_stats_buf->current_tail_idx);
3705         len += scnprintf(buf + len, buf_len - len, "num_htt_msgs_sent = %u\n",
3706                          htt_stats_buf->num_htt_msgs_sent);
3707         len += scnprintf(buf + len, buf_len - len,
3708                          "backpressure_time_ms = %u\n",
3709                          htt_stats_buf->backpressure_time_ms);
3710
3711         for (i = 0; i < 5; i++)
3712                 len += scnprintf(buf + len, buf_len - len,
3713                                  "backpressure_hist_%u = %u\n",
3714                                  i + 1, htt_stats_buf->backpressure_hist[i]);
3715
3716         len += scnprintf(buf + len, buf_len - len,
3717                          "============================\n");
3718
3719         if (len >= buf_len) {
3720                 buf[buf_len - 1] = 0;
3721                 stats_req->buf_len = buf_len - 1;
3722         } else {
3723                 buf[len] = 0;
3724                 stats_req->buf_len = len;
3725         }
3726 }
3727
3728 static inline
3729 void htt_print_pdev_tx_rate_txbf_stats_tlv(const void *tag_buf,
3730                                            struct debug_htt_stats_req *stats_req)
3731 {
3732         const struct htt_pdev_txrate_txbf_stats_tlv *htt_stats_buf = tag_buf;
3733         u8 *buf = stats_req->buf;
3734         u32 len = stats_req->buf_len;
3735         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3736         int i;
3737
3738         len += scnprintf(buf + len, buf_len - len,
3739                          "HTT_STATS_PDEV_TX_RATE_TXBF_STATS:\n");
3740
3741         len += scnprintf(buf + len, buf_len - len, "tx_ol_mcs = ");
3742         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
3743                 len += scnprintf(buf + len, buf_len - len,
3744                                  "%d:%u,", i, htt_stats_buf->tx_su_ol_mcs[i]);
3745         len--;
3746
3747         len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_mcs = ");
3748         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
3749                 len += scnprintf(buf + len, buf_len - len,
3750                                  "%d:%u,", i, htt_stats_buf->tx_su_ibf_mcs[i]);
3751         len--;
3752
3753         len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_mcs =");
3754         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
3755                 len += scnprintf(buf + len, buf_len - len,
3756                                  "%d:%u,", i, htt_stats_buf->tx_su_txbf_mcs[i]);
3757         len--;
3758
3759         len += scnprintf(buf + len, buf_len - len, "\ntx_ol_nss = ");
3760         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
3761                 len += scnprintf(buf + len, buf_len - len,
3762                                  "%d:%u,", i, htt_stats_buf->tx_su_ol_nss[i]);
3763         len--;
3764
3765         len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_nss = ");
3766         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
3767                 len += scnprintf(buf + len, buf_len - len,
3768                                  "%d:%u,", i, htt_stats_buf->tx_su_ibf_nss[i]);
3769         len--;
3770
3771         len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_nss = ");
3772         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
3773                 len += scnprintf(buf + len, buf_len - len,
3774                                  "%d:%u,", i, htt_stats_buf->tx_su_txbf_nss[i]);
3775         len--;
3776
3777         len += scnprintf(buf + len, buf_len - len, "\ntx_ol_bw = ");
3778         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
3779                 len += scnprintf(buf + len, buf_len - len,
3780                                  "%d:%u,", i, htt_stats_buf->tx_su_ol_bw[i]);
3781         len--;
3782
3783         len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_bw = ");
3784         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
3785                 len += scnprintf(buf + len, buf_len - len,
3786                                  "%d:%u,", i, htt_stats_buf->tx_su_ibf_bw[i]);
3787         len--;
3788
3789         len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_bw = ");
3790         for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
3791                 len += scnprintf(buf + len, buf_len - len,
3792                                  "%d:%u,", i, htt_stats_buf->tx_su_txbf_bw[i]);
3793         len--;
3794
3795         len += scnprintf(buf + len, buf_len - len, "\n");
3796
3797         stats_req->buf_len = len;
3798 }
3799
3800 static inline
3801 void htt_print_txbf_ofdma_ndpa_stats_tlv(const void *tag_buf,
3802                                          struct debug_htt_stats_req *stats_req)
3803 {
3804         const struct htt_txbf_ofdma_ndpa_stats_tlv *htt_stats_buf = tag_buf;
3805         u8 *buf = stats_req->buf;
3806         u32 len = stats_req->buf_len;
3807         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3808         int i;
3809
3810         len += scnprintf(buf + len, buf_len - len,
3811                          "HTT_TXBF_OFDMA_NDPA_STATS_TLV:\n");
3812
3813         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
3814                 len += scnprintf(buf + len, buf_len - len,
3815                                  "ax_ofdma_ndpa_queued_user%d = %u\n",
3816                                  i, htt_stats_buf->ax_ofdma_ndpa_queued[i]);
3817                 len += scnprintf(buf + len, buf_len - len,
3818                                  "ax_ofdma_ndpa_tried_user%d = %u\n",
3819                                  i, htt_stats_buf->ax_ofdma_ndpa_tried[i]);
3820                 len += scnprintf(buf + len, buf_len - len,
3821                                  "ax_ofdma_ndpa_flushed_user%d = %u\n",
3822                                  i, htt_stats_buf->ax_ofdma_ndpa_flushed[i]);
3823                 len += scnprintf(buf + len, buf_len - len,
3824                                  "ax_ofdma_ndpa_err_user%d = %u\n",
3825                                  i, htt_stats_buf->ax_ofdma_ndpa_err[i]);
3826                 len += scnprintf(buf + len, buf_len - len, "\n");
3827         }
3828
3829         stats_req->buf_len = len;
3830 }
3831
3832 static inline
3833 void htt_print_txbf_ofdma_ndp_stats_tlv(const void *tag_buf,
3834                                         struct debug_htt_stats_req *stats_req)
3835 {
3836         const struct htt_txbf_ofdma_ndp_stats_tlv *htt_stats_buf = tag_buf;
3837         u8 *buf = stats_req->buf;
3838         u32 len = stats_req->buf_len;
3839         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3840         int i;
3841
3842         len += scnprintf(buf + len, buf_len - len,
3843                          "HTT_TXBF_OFDMA_NDP_STATS_TLV:\n");
3844
3845         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
3846                 len += scnprintf(buf + len, buf_len - len,
3847                                  "ax_ofdma_ndp_queued_user%d = %u\n",
3848                                  i, htt_stats_buf->ax_ofdma_ndp_queued[i]);
3849                 len += scnprintf(buf + len, buf_len - len,
3850                                  "ax_ofdma_ndp_tried_user%d = %u\n",
3851                                  i, htt_stats_buf->ax_ofdma_ndp_tried[i]);
3852                 len += scnprintf(buf + len, buf_len - len,
3853                                  "ax_ofdma_ndp_flushed_user%d = %u\n",
3854                                  i, htt_stats_buf->ax_ofdma_ndp_flushed[i]);
3855                 len += scnprintf(buf + len, buf_len - len,
3856                                  "ax_ofdma_ndp_err_user%d = %u\n",
3857                                  i, htt_stats_buf->ax_ofdma_ndp_err[i]);
3858                 len += scnprintf(buf + len, buf_len - len, "\n");
3859         }
3860
3861         stats_req->buf_len = len;
3862 }
3863
3864 static inline
3865 void htt_print_txbf_ofdma_brp_stats_tlv(const void *tag_buf,
3866                                         struct debug_htt_stats_req *stats_req)
3867 {
3868         const struct htt_txbf_ofdma_brp_stats_tlv *htt_stats_buf = tag_buf;
3869         u8 *buf = stats_req->buf;
3870         u32 len = stats_req->buf_len;
3871         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3872         int i;
3873
3874         len += scnprintf(buf + len, buf_len - len,
3875                          "HTT_TXBF_OFDMA_BRP_STATS_TLV:\n");
3876
3877         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
3878                 len += scnprintf(buf + len, buf_len - len,
3879                                  "ax_ofdma_brpoll_queued_user%d = %u\n",
3880                                  i, htt_stats_buf->ax_ofdma_brpoll_queued[i]);
3881                 len += scnprintf(buf + len, buf_len - len,
3882                                  "ax_ofdma_brpoll_tried_user%d = %u\n",
3883                                  i, htt_stats_buf->ax_ofdma_brpoll_tried[i]);
3884                 len += scnprintf(buf + len, buf_len - len,
3885                                  "ax_ofdma_brpoll_flushed_user%d = %u\n",
3886                                  i, htt_stats_buf->ax_ofdma_brpoll_flushed[i]);
3887                 len += scnprintf(buf + len, buf_len - len,
3888                                  "ax_ofdma_brp_err_user%d = %u\n",
3889                                  i, htt_stats_buf->ax_ofdma_brp_err[i]);
3890                 len += scnprintf(buf + len, buf_len - len,
3891                                  "ax_ofdma_brp_err_num_cbf_rcvd_user%d = %u\n",
3892                                  i, htt_stats_buf->ax_ofdma_brp_err_num_cbf_rcvd[i]);
3893                 len += scnprintf(buf + len, buf_len - len, "\n");
3894         }
3895
3896         stats_req->buf_len = len;
3897 }
3898
3899 static inline
3900 void htt_print_txbf_ofdma_steer_stats_tlv(const void *tag_buf,
3901                                           struct debug_htt_stats_req *stats_req)
3902 {
3903         const struct htt_txbf_ofdma_steer_stats_tlv *htt_stats_buf = tag_buf;
3904         u8 *buf = stats_req->buf;
3905         u32 len = stats_req->buf_len;
3906         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3907         int i;
3908
3909         len += scnprintf(buf + len, buf_len - len,
3910                          "HTT_TXBF_OFDMA_STEER_STATS_TLV:\n");
3911
3912         for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
3913                 len += scnprintf(buf + len, buf_len - len,
3914                                  "ax_ofdma_num_ppdu_steer_user%d = %u\n",
3915                                  i, htt_stats_buf->ax_ofdma_num_ppdu_steer[i]);
3916                 len += scnprintf(buf + len, buf_len - len,
3917                                  "ax_ofdma_num_ppdu_ol_user%d = %u\n",
3918                                  i, htt_stats_buf->ax_ofdma_num_ppdu_ol[i]);
3919                 len += scnprintf(buf + len, buf_len - len,
3920                                  "ax_ofdma_num_usrs_prefetch_user%d = %u\n",
3921                                  i, htt_stats_buf->ax_ofdma_num_usrs_prefetch[i]);
3922                 len += scnprintf(buf + len, buf_len - len,
3923                                  "ax_ofdma_num_usrs_sound_user%d = %u\n",
3924                                  i, htt_stats_buf->ax_ofdma_num_usrs_sound[i]);
3925                 len += scnprintf(buf + len, buf_len - len,
3926                                  "ax_ofdma_num_usrs_force_sound_user%d = %u\n",
3927                                  i, htt_stats_buf->ax_ofdma_num_usrs_force_sound[i]);
3928                 len += scnprintf(buf + len, buf_len - len, "\n");
3929         }
3930
3931         stats_req->buf_len = len;
3932 }
3933
3934 static inline
3935 void htt_print_phy_counters_tlv(const void *tag_buf,
3936                                 struct debug_htt_stats_req *stats_req)
3937 {
3938         const struct htt_phy_counters_tlv *htt_stats_buf = tag_buf;
3939         u8 *buf = stats_req->buf;
3940         u32 len = stats_req->buf_len;
3941         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3942         int i;
3943
3944         len += scnprintf(buf + len, buf_len - len, "HTT_PHY_COUNTERS_TLV:\n");
3945         len += scnprintf(buf + len, buf_len - len, "rx_ofdma_timing_err_cnt = %u\n",
3946                          htt_stats_buf->rx_ofdma_timing_err_cnt);
3947         len += scnprintf(buf + len, buf_len - len, "rx_cck_fail_cnt = %u\n",
3948                          htt_stats_buf->rx_cck_fail_cnt);
3949         len += scnprintf(buf + len, buf_len - len, "mactx_abort_cnt = %u\n",
3950                          htt_stats_buf->mactx_abort_cnt);
3951         len += scnprintf(buf + len, buf_len - len, "macrx_abort_cnt = %u\n",
3952                          htt_stats_buf->macrx_abort_cnt);
3953         len += scnprintf(buf + len, buf_len - len, "phytx_abort_cnt = %u\n",
3954                          htt_stats_buf->phytx_abort_cnt);
3955         len += scnprintf(buf + len, buf_len - len, "phyrx_abort_cnt = %u\n",
3956                          htt_stats_buf->phyrx_abort_cnt);
3957         len += scnprintf(buf + len, buf_len - len, "phyrx_defer_abort_cnt = %u\n",
3958                          htt_stats_buf->phyrx_defer_abort_cnt);
3959         len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_lstf_event_cnt = %u\n",
3960                          htt_stats_buf->rx_gain_adj_lstf_event_cnt);
3961         len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_non_legacy_cnt = %u\n",
3962                          htt_stats_buf->rx_gain_adj_non_legacy_cnt);
3963
3964         for (i = 0; i < HTT_MAX_RX_PKT_CNT; i++)
3965                 len += scnprintf(buf + len, buf_len - len, "rx_pkt_cnt[%d] = %u\n",
3966                                  i, htt_stats_buf->rx_pkt_cnt[i]);
3967
3968         for (i = 0; i < HTT_MAX_RX_PKT_CRC_PASS_CNT; i++)
3969                 len += scnprintf(buf + len, buf_len - len,
3970                                  "rx_pkt_crc_pass_cnt[%d] = %u\n",
3971                                  i, htt_stats_buf->rx_pkt_crc_pass_cnt[i]);
3972
3973         for (i = 0; i < HTT_MAX_PER_BLK_ERR_CNT; i++)
3974                 len += scnprintf(buf + len, buf_len - len,
3975                                  "per_blk_err_cnt[%d] = %u\n",
3976                                  i, htt_stats_buf->per_blk_err_cnt[i]);
3977
3978         for (i = 0; i < HTT_MAX_RX_OTA_ERR_CNT; i++)
3979                 len += scnprintf(buf + len, buf_len - len,
3980                                  "rx_ota_err_cnt[%d] = %u\n",
3981                                  i, htt_stats_buf->rx_ota_err_cnt[i]);
3982
3983         stats_req->buf_len = len;
3984 }
3985
3986 static inline
3987 void htt_print_phy_stats_tlv(const void *tag_buf,
3988                              struct debug_htt_stats_req *stats_req)
3989 {
3990         const struct htt_phy_stats_tlv *htt_stats_buf = tag_buf;
3991         u8 *buf = stats_req->buf;
3992         u32 len = stats_req->buf_len;
3993         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
3994         int i;
3995
3996         len += scnprintf(buf + len, buf_len - len, "HTT_PHY_STATS_TLV:\n");
3997
3998         for (i = 0; i < HTT_STATS_MAX_CHAINS; i++)
3999                 len += scnprintf(buf + len, buf_len - len, "nf_chain[%d] = %d\n",
4000                                  i, htt_stats_buf->nf_chain[i]);
4001
4002         len += scnprintf(buf + len, buf_len - len, "false_radar_cnt = %u\n",
4003                          htt_stats_buf->false_radar_cnt);
4004         len += scnprintf(buf + len, buf_len - len, "radar_cs_cnt = %u\n",
4005                          htt_stats_buf->radar_cs_cnt);
4006         len += scnprintf(buf + len, buf_len - len, "ani_level = %d\n",
4007                          htt_stats_buf->ani_level);
4008         len += scnprintf(buf + len, buf_len - len, "fw_run_time = %u\n",
4009                          htt_stats_buf->fw_run_time);
4010
4011         stats_req->buf_len = len;
4012 }
4013
4014 static inline void
4015 htt_print_phy_reset_counters_tlv(const void *tag_buf,
4016                                  u16 tag_len,
4017                                  struct debug_htt_stats_req *stats_req)
4018 {
4019         const struct htt_phy_reset_counters_tlv *htt_stats_buf = tag_buf;
4020         u8 *buf = stats_req->buf;
4021         u32 len = stats_req->buf_len;
4022         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
4023
4024         if (tag_len < sizeof(*htt_stats_buf))
4025                 return;
4026
4027         len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_COUNTERS_TLV:\n");
4028
4029         len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
4030                          htt_stats_buf->pdev_id);
4031         len += scnprintf(buf + len, buf_len - len, "cf_active_low_fail_cnt = %u\n",
4032                          htt_stats_buf->cf_active_low_fail_cnt);
4033         len += scnprintf(buf + len, buf_len - len, "cf_active_low_pass_cnt = %u\n",
4034                          htt_stats_buf->cf_active_low_pass_cnt);
4035         len += scnprintf(buf + len, buf_len - len, "phy_off_through_vreg_cnt = %u\n",
4036                          htt_stats_buf->phy_off_through_vreg_cnt);
4037         len += scnprintf(buf + len, buf_len - len, "force_calibration_cnt = %u\n",
4038                          htt_stats_buf->force_calibration_cnt);
4039         len += scnprintf(buf + len, buf_len - len, "rf_mode_switch_phy_off_cnt = %u\n",
4040                          htt_stats_buf->rf_mode_switch_phy_off_cnt);
4041
4042         stats_req->buf_len = len;
4043 }
4044
4045 static inline void
4046 htt_print_phy_reset_stats_tlv(const void *tag_buf,
4047                               u16 tag_len,
4048                               struct debug_htt_stats_req *stats_req)
4049 {
4050         const struct htt_phy_reset_stats_tlv *htt_stats_buf = tag_buf;
4051         u8 *buf = stats_req->buf;
4052         u32 len = stats_req->buf_len;
4053         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
4054
4055         if (tag_len < sizeof(*htt_stats_buf))
4056                 return;
4057
4058         len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_STATS_TLV:\n");
4059
4060         len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
4061                          htt_stats_buf->pdev_id);
4062         len += scnprintf(buf + len, buf_len - len, "chan_mhz = %u\n",
4063                          htt_stats_buf->chan_mhz);
4064         len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq1 = %u\n",
4065                          htt_stats_buf->chan_band_center_freq1);
4066         len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq2 = %u\n",
4067                          htt_stats_buf->chan_band_center_freq2);
4068         len += scnprintf(buf + len, buf_len - len, "chan_phy_mode = %u\n",
4069                          htt_stats_buf->chan_phy_mode);
4070         len += scnprintf(buf + len, buf_len - len, "chan_flags = 0x%0x\n",
4071                          htt_stats_buf->chan_flags);
4072         len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n",
4073                          htt_stats_buf->chan_num);
4074         len += scnprintf(buf + len, buf_len - len, "reset_cause = 0x%0x\n",
4075                          htt_stats_buf->reset_cause);
4076         len += scnprintf(buf + len, buf_len - len, "prev_reset_cause = 0x%0x\n",
4077                          htt_stats_buf->prev_reset_cause);
4078         len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_src = 0x%0x\n",
4079                          htt_stats_buf->phy_warm_reset_src);
4080         len += scnprintf(buf + len, buf_len - len, "rx_gain_tbl_mode = %d\n",
4081                          htt_stats_buf->rx_gain_tbl_mode);
4082         len += scnprintf(buf + len, buf_len - len, "xbar_val = 0x%0x\n",
4083                          htt_stats_buf->xbar_val);
4084         len += scnprintf(buf + len, buf_len - len, "force_calibration = %u\n",
4085                          htt_stats_buf->force_calibration);
4086         len += scnprintf(buf + len, buf_len - len, "phyrf_mode = %u\n",
4087                          htt_stats_buf->phyrf_mode);
4088         len += scnprintf(buf + len, buf_len - len, "phy_homechan = %u\n",
4089                          htt_stats_buf->phy_homechan);
4090         len += scnprintf(buf + len, buf_len - len, "phy_tx_ch_mask = 0x%0x\n",
4091                          htt_stats_buf->phy_tx_ch_mask);
4092         len += scnprintf(buf + len, buf_len - len, "phy_rx_ch_mask = 0x%0x\n",
4093                          htt_stats_buf->phy_rx_ch_mask);
4094         len += scnprintf(buf + len, buf_len - len, "phybb_ini_mask = 0x%0x\n",
4095                          htt_stats_buf->phybb_ini_mask);
4096         len += scnprintf(buf + len, buf_len - len, "phyrf_ini_mask = 0x%0x\n",
4097                          htt_stats_buf->phyrf_ini_mask);
4098         len += scnprintf(buf + len, buf_len - len, "phy_dfs_en_mask = 0x%0x\n",
4099                          htt_stats_buf->phy_dfs_en_mask);
4100         len += scnprintf(buf + len, buf_len - len, "phy_sscan_en_mask = 0x%0x\n",
4101                          htt_stats_buf->phy_sscan_en_mask);
4102         len += scnprintf(buf + len, buf_len - len, "phy_synth_sel_mask = 0x%0x\n",
4103                          htt_stats_buf->phy_synth_sel_mask);
4104         len += scnprintf(buf + len, buf_len - len, "phy_adfs_freq = %u\n",
4105                          htt_stats_buf->phy_adfs_freq);
4106         len += scnprintf(buf + len, buf_len - len, "cck_fir_settings = 0x%0x\n",
4107                          htt_stats_buf->cck_fir_settings);
4108         len += scnprintf(buf + len, buf_len - len, "phy_dyn_pri_chan = %u\n",
4109                          htt_stats_buf->phy_dyn_pri_chan);
4110         len += scnprintf(buf + len, buf_len - len, "cca_thresh = 0x%0x\n",
4111                          htt_stats_buf->cca_thresh);
4112         len += scnprintf(buf + len, buf_len - len, "dyn_cca_status = %u\n",
4113                          htt_stats_buf->dyn_cca_status);
4114         len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_hw = 0x%x\n",
4115                          htt_stats_buf->rxdesense_thresh_hw);
4116         len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_sw = 0x%x\n",
4117                          htt_stats_buf->rxdesense_thresh_sw);
4118
4119         stats_req->buf_len = len;
4120 }
4121
4122 static inline
4123 void htt_print_peer_ctrl_path_txrx_stats_tlv(const void *tag_buf,
4124                                              struct debug_htt_stats_req *stats_req)
4125 {
4126         const struct htt_peer_ctrl_path_txrx_stats_tlv *htt_stat_buf = tag_buf;
4127         u8 *buf = stats_req->buf;
4128         u32 len = stats_req->buf_len;
4129         u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
4130         int i;
4131         const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1] = {
4132                 "assoc_req", "assoc_resp",
4133                 "reassoc_req", "reassoc_resp",
4134                 "probe_req", "probe_resp",
4135                 "timing_advertisement", "reserved",
4136                 "beacon", "atim", "disassoc",
4137                 "auth", "deauth", "action", "action_no_ack"};
4138
4139         len += scnprintf(buf + len, buf_len - len,
4140                          "HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG:\n");
4141         len += scnprintf(buf + len, buf_len - len,
4142                          "peer_mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
4143                          htt_stat_buf->peer_mac_addr[0], htt_stat_buf->peer_mac_addr[1],
4144                          htt_stat_buf->peer_mac_addr[2], htt_stat_buf->peer_mac_addr[3],
4145                          htt_stat_buf->peer_mac_addr[4], htt_stat_buf->peer_mac_addr[5]);
4146
4147         len += scnprintf(buf + len, buf_len - len, "peer_tx_mgmt_subtype:\n");
4148         for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++)
4149                 len += scnprintf(buf + len, buf_len - len, "%s:%u\n",
4150                                  mgmt_frm_type[i],
4151                                  htt_stat_buf->peer_rx_mgmt_subtype[i]);
4152
4153         len += scnprintf(buf + len, buf_len - len, "peer_rx_mgmt_subtype:\n");
4154         for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++)
4155                 len += scnprintf(buf + len, buf_len - len, "%s:%u\n",
4156                                  mgmt_frm_type[i],
4157                                  htt_stat_buf->peer_rx_mgmt_subtype[i]);
4158
4159         len += scnprintf(buf + len, buf_len - len, "\n");
4160
4161         stats_req->buf_len = len;
4162 }
4163
4164 static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab,
4165                                           u16 tag, u16 len, const void *tag_buf,
4166                                           void *user_data)
4167 {
4168         struct debug_htt_stats_req *stats_req = user_data;
4169
4170         switch (tag) {
4171         case HTT_STATS_TX_PDEV_CMN_TAG:
4172                 htt_print_tx_pdev_stats_cmn_tlv(tag_buf, stats_req);
4173                 break;
4174         case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
4175                 htt_print_tx_pdev_stats_urrn_tlv_v(tag_buf, len, stats_req);
4176                 break;
4177         case HTT_STATS_TX_PDEV_SIFS_TAG:
4178                 htt_print_tx_pdev_stats_sifs_tlv_v(tag_buf, len, stats_req);
4179                 break;
4180         case HTT_STATS_TX_PDEV_FLUSH_TAG:
4181                 htt_print_tx_pdev_stats_flush_tlv_v(tag_buf, len, stats_req);
4182                 break;
4183         case HTT_STATS_TX_PDEV_PHY_ERR_TAG:
4184                 htt_print_tx_pdev_stats_phy_err_tlv_v(tag_buf, len, stats_req);
4185                 break;
4186         case HTT_STATS_TX_PDEV_SIFS_HIST_TAG:
4187                 htt_print_tx_pdev_stats_sifs_hist_tlv_v(tag_buf, len, stats_req);
4188                 break;
4189
4190         case HTT_STATS_TX_PDEV_TX_PPDU_STATS_TAG:
4191                 htt_print_tx_pdev_stats_tx_ppdu_stats_tlv_v(tag_buf, stats_req);
4192                 break;
4193
4194         case HTT_STATS_TX_PDEV_TRIED_MPDU_CNT_HIST_TAG:
4195                 htt_print_tx_pdev_stats_tried_mpdu_cnt_hist_tlv_v(tag_buf, len,
4196                                                                   stats_req);
4197                 break;
4198
4199         case HTT_STATS_STRING_TAG:
4200                 htt_print_stats_string_tlv(tag_buf, len, stats_req);
4201                 break;
4202
4203         case HTT_STATS_TX_HWQ_CMN_TAG:
4204                 htt_print_tx_hwq_stats_cmn_tlv(tag_buf, stats_req);
4205                 break;
4206
4207         case HTT_STATS_TX_HWQ_DIFS_LATENCY_TAG:
4208                 htt_print_tx_hwq_difs_latency_stats_tlv_v(tag_buf, len, stats_req);
4209                 break;
4210
4211         case HTT_STATS_TX_HWQ_CMD_RESULT_TAG:
4212                 htt_print_tx_hwq_cmd_result_stats_tlv_v(tag_buf, len, stats_req);
4213                 break;
4214
4215         case HTT_STATS_TX_HWQ_CMD_STALL_TAG:
4216                 htt_print_tx_hwq_cmd_stall_stats_tlv_v(tag_buf, len, stats_req);
4217                 break;
4218
4219         case HTT_STATS_TX_HWQ_FES_STATUS_TAG:
4220                 htt_print_tx_hwq_fes_result_stats_tlv_v(tag_buf, len, stats_req);
4221                 break;
4222
4223         case HTT_STATS_TX_HWQ_TRIED_MPDU_CNT_HIST_TAG:
4224                 htt_print_tx_hwq_tried_mpdu_cnt_hist_tlv_v(tag_buf, len, stats_req);
4225                 break;
4226
4227         case HTT_STATS_TX_HWQ_TXOP_USED_CNT_HIST_TAG:
4228                 htt_print_tx_hwq_txop_used_cnt_hist_tlv_v(tag_buf, len, stats_req);
4229                 break;
4230         case HTT_STATS_TX_TQM_GEN_MPDU_TAG:
4231                 htt_print_tx_tqm_gen_mpdu_stats_tlv_v(tag_buf, len, stats_req);
4232                 break;
4233
4234         case HTT_STATS_TX_TQM_LIST_MPDU_TAG:
4235                 htt_print_tx_tqm_list_mpdu_stats_tlv_v(tag_buf, len, stats_req);
4236                 break;
4237
4238         case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG:
4239                 htt_print_tx_tqm_list_mpdu_cnt_tlv_v(tag_buf, len, stats_req);
4240                 break;
4241
4242         case HTT_STATS_TX_TQM_CMN_TAG:
4243                 htt_print_tx_tqm_cmn_stats_tlv(tag_buf, stats_req);
4244                 break;
4245
4246         case HTT_STATS_TX_TQM_PDEV_TAG:
4247                 htt_print_tx_tqm_pdev_stats_tlv_v(tag_buf, stats_req);
4248                 break;
4249
4250         case HTT_STATS_TX_TQM_CMDQ_STATUS_TAG:
4251                 htt_print_tx_tqm_cmdq_status_tlv(tag_buf, stats_req);
4252                 break;
4253
4254         case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG:
4255                 htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, stats_req);
4256                 break;
4257
4258         case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG:
4259                 htt_print_tx_de_classify_failed_stats_tlv(tag_buf, stats_req);
4260                 break;
4261
4262         case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG:
4263                 htt_print_tx_de_classify_stats_tlv(tag_buf, stats_req);
4264                 break;
4265
4266         case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG:
4267                 htt_print_tx_de_classify_status_stats_tlv(tag_buf, stats_req);
4268                 break;
4269
4270         case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG:
4271                 htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, stats_req);
4272                 break;
4273
4274         case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG:
4275                 htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, stats_req);
4276                 break;
4277
4278         case HTT_STATS_TX_DE_FW2WBM_RING_FULL_HIST_TAG:
4279                 htt_print_tx_de_fw2wbm_ring_full_hist_tlv(tag_buf, len, stats_req);
4280                 break;
4281
4282         case HTT_STATS_TX_DE_CMN_TAG:
4283                 htt_print_tx_de_cmn_stats_tlv(tag_buf, stats_req);
4284                 break;
4285
4286         case HTT_STATS_RING_IF_TAG:
4287                 htt_print_ring_if_stats_tlv(tag_buf, stats_req);
4288                 break;
4289
4290         case HTT_STATS_TX_PDEV_MU_MIMO_STATS_TAG:
4291                 htt_print_tx_pdev_mu_mimo_sch_stats_tlv(tag_buf, stats_req);
4292                 break;
4293
4294         case HTT_STATS_SFM_CMN_TAG:
4295                 htt_print_sfm_cmn_tlv(tag_buf, stats_req);
4296                 break;
4297
4298         case HTT_STATS_SRING_STATS_TAG:
4299                 htt_print_sring_stats_tlv(tag_buf, stats_req);
4300                 break;
4301
4302         case HTT_STATS_RX_PDEV_FW_STATS_TAG:
4303                 htt_print_rx_pdev_fw_stats_tlv(tag_buf, stats_req);
4304                 break;
4305
4306         case HTT_STATS_RX_PDEV_FW_RING_MPDU_ERR_TAG:
4307                 htt_print_rx_pdev_fw_ring_mpdu_err_tlv_v(tag_buf, stats_req);
4308                 break;
4309
4310         case HTT_STATS_RX_PDEV_FW_MPDU_DROP_TAG:
4311                 htt_print_rx_pdev_fw_mpdu_drop_tlv_v(tag_buf, len, stats_req);
4312                 break;
4313
4314         case HTT_STATS_RX_SOC_FW_STATS_TAG:
4315                 htt_print_rx_soc_fw_stats_tlv(tag_buf, stats_req);
4316                 break;
4317
4318         case HTT_STATS_RX_SOC_FW_REFILL_RING_EMPTY_TAG:
4319                 htt_print_rx_soc_fw_refill_ring_empty_tlv_v(tag_buf, len, stats_req);
4320                 break;
4321
4322         case HTT_STATS_RX_SOC_FW_REFILL_RING_NUM_REFILL_TAG:
4323                 htt_print_rx_soc_fw_refill_ring_num_refill_tlv_v(
4324                                 tag_buf, len, stats_req);
4325                 break;
4326         case HTT_STATS_RX_REFILL_RXDMA_ERR_TAG:
4327                 htt_print_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v(
4328                                 tag_buf, len, stats_req);
4329                 break;
4330
4331         case HTT_STATS_RX_REFILL_REO_ERR_TAG:
4332                 htt_print_rx_soc_fw_refill_ring_num_reo_err_tlv_v(
4333                                 tag_buf, len, stats_req);
4334                 break;
4335
4336         case HTT_STATS_RX_REO_RESOURCE_STATS_TAG:
4337                 htt_print_rx_reo_debug_stats_tlv_v(
4338                                 tag_buf, stats_req);
4339                 break;
4340         case HTT_STATS_RX_PDEV_FW_STATS_PHY_ERR_TAG:
4341                 htt_print_rx_pdev_fw_stats_phy_err_tlv(tag_buf, stats_req);
4342                 break;
4343
4344         case HTT_STATS_TX_PDEV_RATE_STATS_TAG:
4345                 htt_print_tx_pdev_rate_stats_tlv(tag_buf, stats_req);
4346                 break;
4347
4348         case HTT_STATS_RX_PDEV_RATE_STATS_TAG:
4349                 htt_print_rx_pdev_rate_stats_tlv(tag_buf, stats_req);
4350                 break;
4351
4352         case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG:
4353                 htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, stats_req);
4354                 break;
4355         case HTT_STATS_TX_SCHED_CMN_TAG:
4356                 htt_print_stats_tx_sched_cmn_tlv(tag_buf, stats_req);
4357                 break;
4358
4359         case HTT_STATS_TX_PDEV_MPDU_STATS_TAG:
4360                 htt_print_tx_pdev_mu_mimo_mpdu_stats_tlv(tag_buf, stats_req);
4361                 break;
4362
4363         case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG:
4364                 htt_print_sched_txq_cmd_posted_tlv_v(tag_buf, len, stats_req);
4365                 break;
4366
4367         case HTT_STATS_RING_IF_CMN_TAG:
4368                 htt_print_ring_if_cmn_tlv(tag_buf, stats_req);
4369                 break;
4370
4371         case HTT_STATS_SFM_CLIENT_USER_TAG:
4372                 htt_print_sfm_client_user_tlv_v(tag_buf, len, stats_req);
4373                 break;
4374
4375         case HTT_STATS_SFM_CLIENT_TAG:
4376                 htt_print_sfm_client_tlv(tag_buf, stats_req);
4377                 break;
4378
4379         case HTT_STATS_TX_TQM_ERROR_STATS_TAG:
4380                 htt_print_tx_tqm_error_stats_tlv(tag_buf, stats_req);
4381                 break;
4382
4383         case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG:
4384                 htt_print_sched_txq_cmd_reaped_tlv_v(tag_buf, len, stats_req);
4385                 break;
4386
4387         case HTT_STATS_SRING_CMN_TAG:
4388                 htt_print_sring_cmn_tlv(tag_buf, stats_req);
4389                 break;
4390
4391         case HTT_STATS_TX_SOUNDING_STATS_TAG:
4392                 htt_print_tx_sounding_stats_tlv(tag_buf, stats_req);
4393                 break;
4394
4395         case HTT_STATS_TX_SELFGEN_AC_ERR_STATS_TAG:
4396                 htt_print_tx_selfgen_ac_err_stats_tlv(tag_buf, stats_req);
4397                 break;
4398
4399         case HTT_STATS_TX_SELFGEN_CMN_STATS_TAG:
4400                 htt_print_tx_selfgen_cmn_stats_tlv(tag_buf, stats_req);
4401                 break;
4402
4403         case HTT_STATS_TX_SELFGEN_AC_STATS_TAG:
4404                 htt_print_tx_selfgen_ac_stats_tlv(tag_buf, stats_req);
4405                 break;
4406
4407         case HTT_STATS_TX_SELFGEN_AX_STATS_TAG:
4408                 htt_print_tx_selfgen_ax_stats_tlv(tag_buf, stats_req);
4409                 break;
4410
4411         case HTT_STATS_TX_SELFGEN_AX_ERR_STATS_TAG:
4412                 htt_print_tx_selfgen_ax_err_stats_tlv(tag_buf, stats_req);
4413                 break;
4414
4415         case HTT_STATS_TX_HWQ_MUMIMO_SCH_STATS_TAG:
4416                 htt_print_tx_hwq_mu_mimo_sch_stats_tlv(tag_buf, stats_req);
4417                 break;
4418
4419         case HTT_STATS_TX_HWQ_MUMIMO_MPDU_STATS_TAG:
4420                 htt_print_tx_hwq_mu_mimo_mpdu_stats_tlv(tag_buf, stats_req);
4421                 break;
4422
4423         case HTT_STATS_TX_HWQ_MUMIMO_CMN_STATS_TAG:
4424                 htt_print_tx_hwq_mu_mimo_cmn_stats_tlv(tag_buf, stats_req);
4425                 break;
4426
4427         case HTT_STATS_HW_INTR_MISC_TAG:
4428                 htt_print_hw_stats_intr_misc_tlv(tag_buf, stats_req);
4429                 break;
4430
4431         case HTT_STATS_HW_WD_TIMEOUT_TAG:
4432                 htt_print_hw_stats_wd_timeout_tlv(tag_buf, stats_req);
4433                 break;
4434
4435         case HTT_STATS_HW_PDEV_ERRS_TAG:
4436                 htt_print_hw_stats_pdev_errs_tlv(tag_buf, stats_req);
4437                 break;
4438
4439         case HTT_STATS_COUNTER_NAME_TAG:
4440                 htt_print_counter_tlv(tag_buf, stats_req);
4441                 break;
4442
4443         case HTT_STATS_TX_TID_DETAILS_TAG:
4444                 htt_print_tx_tid_stats_tlv(tag_buf, stats_req);
4445                 break;
4446
4447         case HTT_STATS_TX_TID_DETAILS_V1_TAG:
4448                 htt_print_tx_tid_stats_v1_tlv(tag_buf, stats_req);
4449                 break;
4450
4451         case HTT_STATS_RX_TID_DETAILS_TAG:
4452                 htt_print_rx_tid_stats_tlv(tag_buf, stats_req);
4453                 break;
4454
4455         case HTT_STATS_PEER_STATS_CMN_TAG:
4456                 htt_print_peer_stats_cmn_tlv(tag_buf, stats_req);
4457                 break;
4458
4459         case HTT_STATS_PEER_DETAILS_TAG:
4460                 htt_print_peer_details_tlv(tag_buf, stats_req);
4461                 break;
4462
4463         case HTT_STATS_PEER_MSDU_FLOWQ_TAG:
4464                 htt_print_msdu_flow_stats_tlv(tag_buf, stats_req);
4465                 break;
4466
4467         case HTT_STATS_PEER_TX_RATE_STATS_TAG:
4468                 htt_print_tx_peer_rate_stats_tlv(tag_buf, stats_req);
4469                 break;
4470
4471         case HTT_STATS_PEER_RX_RATE_STATS_TAG:
4472                 htt_print_rx_peer_rate_stats_tlv(tag_buf, stats_req);
4473                 break;
4474
4475         case HTT_STATS_TX_DE_COMPL_STATS_TAG:
4476                 htt_print_tx_de_compl_stats_tlv(tag_buf, stats_req);
4477                 break;
4478
4479         case HTT_STATS_PDEV_CCA_1SEC_HIST_TAG:
4480         case HTT_STATS_PDEV_CCA_100MSEC_HIST_TAG:
4481         case HTT_STATS_PDEV_CCA_STAT_CUMULATIVE_TAG:
4482                 htt_print_pdev_cca_stats_hist_tlv(tag_buf, stats_req);
4483                 break;
4484
4485         case HTT_STATS_PDEV_CCA_COUNTERS_TAG:
4486                 htt_print_pdev_stats_cca_counters_tlv(tag_buf, stats_req);
4487                 break;
4488
4489         case HTT_STATS_WHAL_TX_TAG:
4490                 htt_print_hw_stats_whal_tx_tlv(tag_buf, stats_req);
4491                 break;
4492
4493         case HTT_STATS_PDEV_TWT_SESSIONS_TAG:
4494                 htt_print_pdev_stats_twt_sessions_tlv(tag_buf, stats_req);
4495                 break;
4496
4497         case HTT_STATS_PDEV_TWT_SESSION_TAG:
4498                 htt_print_pdev_stats_twt_session_tlv(tag_buf, stats_req);
4499                 break;
4500
4501         case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG:
4502                 htt_print_sched_txq_sched_order_su_tlv_v(tag_buf, len, stats_req);
4503                 break;
4504
4505         case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG:
4506                 htt_print_sched_txq_sched_ineligibility_tlv_v(tag_buf, len, stats_req);
4507                 break;
4508
4509         case HTT_STATS_PDEV_OBSS_PD_TAG:
4510                 htt_print_pdev_obss_pd_stats_tlv_v(tag_buf, stats_req);
4511                 break;
4512         case HTT_STATS_RING_BACKPRESSURE_STATS_TAG:
4513                 htt_print_backpressure_stats_tlv_v(tag_buf, user_data);
4514                 break;
4515         case HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG:
4516                 htt_print_pdev_tx_rate_txbf_stats_tlv(tag_buf, stats_req);
4517                 break;
4518         case HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG:
4519                 htt_print_txbf_ofdma_ndpa_stats_tlv(tag_buf, stats_req);
4520                 break;
4521         case HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG:
4522                 htt_print_txbf_ofdma_ndp_stats_tlv(tag_buf, stats_req);
4523                 break;
4524         case HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG:
4525                 htt_print_txbf_ofdma_brp_stats_tlv(tag_buf, stats_req);
4526                 break;
4527         case HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG:
4528                 htt_print_txbf_ofdma_steer_stats_tlv(tag_buf, stats_req);
4529                 break;
4530         case HTT_STATS_PHY_COUNTERS_TAG:
4531                 htt_print_phy_counters_tlv(tag_buf, stats_req);
4532                 break;
4533         case HTT_STATS_PHY_STATS_TAG:
4534                 htt_print_phy_stats_tlv(tag_buf, stats_req);
4535                 break;
4536         case HTT_STATS_PHY_RESET_COUNTERS_TAG:
4537                 htt_print_phy_reset_counters_tlv(tag_buf, len, stats_req);
4538                 break;
4539         case HTT_STATS_PHY_RESET_STATS_TAG:
4540                 htt_print_phy_reset_stats_tlv(tag_buf, len, stats_req);
4541                 break;
4542         case HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG:
4543                 htt_print_peer_ctrl_path_txrx_stats_tlv(tag_buf, stats_req);
4544                 break;
4545         default:
4546                 break;
4547         }
4548
4549         return 0;
4550 }
4551
4552 void ath11k_debugfs_htt_ext_stats_handler(struct ath11k_base *ab,
4553                                           struct sk_buff *skb)
4554 {
4555         struct ath11k_htt_extd_stats_msg *msg;
4556         struct debug_htt_stats_req *stats_req;
4557         struct ath11k *ar;
4558         u32 len;
4559         u64 cookie;
4560         int ret;
4561         bool send_completion = false;
4562         u8 pdev_id;
4563
4564         msg = (struct ath11k_htt_extd_stats_msg *)skb->data;
4565         cookie = msg->cookie;
4566
4567         if (FIELD_GET(HTT_STATS_COOKIE_MSB, cookie) != HTT_STATS_MAGIC_VALUE) {
4568                 ath11k_warn(ab, "received invalid htt ext stats event\n");
4569                 return;
4570         }
4571
4572         pdev_id = FIELD_GET(HTT_STATS_COOKIE_LSB, cookie);
4573         rcu_read_lock();
4574         ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id);
4575         rcu_read_unlock();
4576         if (!ar) {
4577                 ath11k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
4578                 return;
4579         }
4580
4581         stats_req = ar->debug.htt_stats.stats_req;
4582         if (!stats_req)
4583                 return;
4584
4585         spin_lock_bh(&ar->debug.htt_stats.lock);
4586
4587         stats_req->done = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_DONE, msg->info1);
4588         if (stats_req->done)
4589                 send_completion = true;
4590
4591         spin_unlock_bh(&ar->debug.htt_stats.lock);
4592
4593         len = FIELD_GET(HTT_T2H_EXT_STATS_INFO1_LENGTH, msg->info1);
4594         ret = ath11k_dp_htt_tlv_iter(ab, msg->data, len,
4595                                      ath11k_dbg_htt_ext_stats_parse,
4596                                      stats_req);
4597         if (ret)
4598                 ath11k_warn(ab, "Failed to parse tlv %d\n", ret);
4599
4600         if (send_completion)
4601                 complete(&stats_req->cmpln);
4602 }
4603
4604 static ssize_t ath11k_read_htt_stats_type(struct file *file,
4605                                           char __user *user_buf,
4606                                           size_t count, loff_t *ppos)
4607 {
4608         struct ath11k *ar = file->private_data;
4609         char buf[32];
4610         size_t len;
4611
4612         len = scnprintf(buf, sizeof(buf), "%u\n", ar->debug.htt_stats.type);
4613
4614         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
4615 }
4616
4617 static ssize_t ath11k_write_htt_stats_type(struct file *file,
4618                                            const char __user *user_buf,
4619                                            size_t count, loff_t *ppos)
4620 {
4621         struct ath11k *ar = file->private_data;
4622         u8 type;
4623         int ret;
4624
4625         ret = kstrtou8_from_user(user_buf, count, 0, &type);
4626         if (ret)
4627                 return ret;
4628
4629         if (type >= ATH11K_DBG_HTT_NUM_EXT_STATS)
4630                 return -E2BIG;
4631
4632         if (type == ATH11K_DBG_HTT_EXT_STATS_RESET)
4633                 return -EPERM;
4634
4635         ar->debug.htt_stats.type = type;
4636
4637         ret = count;
4638
4639         return ret;
4640 }
4641
4642 static const struct file_operations fops_htt_stats_type = {
4643         .read = ath11k_read_htt_stats_type,
4644         .write = ath11k_write_htt_stats_type,
4645         .open = simple_open,
4646         .owner = THIS_MODULE,
4647         .llseek = default_llseek,
4648 };
4649
4650 static int ath11k_prep_htt_stats_cfg_params(struct ath11k *ar, u8 type,
4651                                             const u8 *mac_addr,
4652                                             struct htt_ext_stats_cfg_params *cfg_params)
4653 {
4654         if (!cfg_params)
4655                 return -EINVAL;
4656
4657         switch (type) {
4658         case ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ:
4659         case ATH11K_DBG_HTT_EXT_STATS_TX_MU_HWQ:
4660                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ALL_HWQS;
4661                 break;
4662         case ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED:
4663                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ALL_TXQS;
4664                 break;
4665         case ATH11K_DBG_HTT_EXT_STATS_TQM_CMDQ:
4666                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ALL_CMDQS;
4667                 break;
4668         case ATH11K_DBG_HTT_EXT_STATS_PEER_INFO:
4669                 cfg_params->cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR;
4670                 cfg_params->cfg0 |= FIELD_PREP(GENMASK(15, 1),
4671                                         HTT_PEER_STATS_REQ_MODE_FLUSH_TQM);
4672                 cfg_params->cfg1 = HTT_STAT_DEFAULT_PEER_REQ_TYPE;
4673                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(7, 0), mac_addr[0]);
4674                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(15, 8), mac_addr[1]);
4675                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(23, 16), mac_addr[2]);
4676                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(31, 24), mac_addr[3]);
4677                 cfg_params->cfg3 |= FIELD_PREP(GENMASK(7, 0), mac_addr[4]);
4678                 cfg_params->cfg3 |= FIELD_PREP(GENMASK(15, 8), mac_addr[5]);
4679                 break;
4680         case ATH11K_DBG_HTT_EXT_STATS_RING_IF_INFO:
4681         case ATH11K_DBG_HTT_EXT_STATS_SRNG_INFO:
4682                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ALL_RINGS;
4683                 break;
4684         case ATH11K_DBG_HTT_EXT_STATS_ACTIVE_PEERS_LIST:
4685                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ACTIVE_PEERS;
4686                 break;
4687         case ATH11K_DBG_HTT_EXT_STATS_PDEV_CCA_STATS:
4688                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_CCA_CUMULATIVE;
4689                 break;
4690         case ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO:
4691                 cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS;
4692                 break;
4693         case ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS:
4694                 cfg_params->cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR;
4695                 cfg_params->cfg1 |= FIELD_PREP(GENMASK(7, 0), mac_addr[0]);
4696                 cfg_params->cfg1 |= FIELD_PREP(GENMASK(15, 8), mac_addr[1]);
4697                 cfg_params->cfg1 |= FIELD_PREP(GENMASK(23, 16), mac_addr[2]);
4698                 cfg_params->cfg1 |= FIELD_PREP(GENMASK(31, 24), mac_addr[3]);
4699                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(7, 0), mac_addr[4]);
4700                 cfg_params->cfg2 |= FIELD_PREP(GENMASK(15, 8), mac_addr[5]);
4701                 break;
4702         default:
4703                 break;
4704         }
4705
4706         return 0;
4707 }
4708
4709 int ath11k_debugfs_htt_stats_req(struct ath11k *ar)
4710 {
4711         struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
4712         u8 type = stats_req->type;
4713         u64 cookie = 0;
4714         int ret, pdev_id = ar->pdev->pdev_id;
4715         struct htt_ext_stats_cfg_params cfg_params = { 0 };
4716
4717         init_completion(&stats_req->cmpln);
4718
4719         stats_req->done = false;
4720         stats_req->pdev_id = pdev_id;
4721
4722         cookie = FIELD_PREP(HTT_STATS_COOKIE_MSB, HTT_STATS_MAGIC_VALUE) |
4723                  FIELD_PREP(HTT_STATS_COOKIE_LSB, pdev_id);
4724
4725         ret = ath11k_prep_htt_stats_cfg_params(ar, type, stats_req->peer_addr,
4726                                                &cfg_params);
4727         if (ret) {
4728                 ath11k_warn(ar->ab, "failed to set htt stats cfg params: %d\n", ret);
4729                 return ret;
4730         }
4731
4732         ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
4733         if (ret) {
4734                 ath11k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
4735                 return ret;
4736         }
4737
4738         while (!wait_for_completion_timeout(&stats_req->cmpln, 3 * HZ)) {
4739                 spin_lock_bh(&ar->debug.htt_stats.lock);
4740                 if (!stats_req->done) {
4741                         stats_req->done = true;
4742                         spin_unlock_bh(&ar->debug.htt_stats.lock);
4743                         ath11k_warn(ar->ab, "stats request timed out\n");
4744                         return -ETIMEDOUT;
4745                 }
4746                 spin_unlock_bh(&ar->debug.htt_stats.lock);
4747         }
4748
4749         return 0;
4750 }
4751
4752 static int ath11k_open_htt_stats(struct inode *inode, struct file *file)
4753 {
4754         struct ath11k *ar = inode->i_private;
4755         struct debug_htt_stats_req *stats_req;
4756         u8 type = ar->debug.htt_stats.type;
4757         int ret;
4758
4759         if (type == ATH11K_DBG_HTT_EXT_STATS_RESET ||
4760             type == ATH11K_DBG_HTT_EXT_STATS_PEER_INFO ||
4761             type == ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS)
4762                 return -EPERM;
4763
4764         mutex_lock(&ar->conf_mutex);
4765
4766         if (ar->state != ATH11K_STATE_ON) {
4767                 ret = -ENETDOWN;
4768                 goto err_unlock;
4769         }
4770
4771         if (ar->debug.htt_stats.stats_req) {
4772                 ret = -EAGAIN;
4773                 goto err_unlock;
4774         }
4775
4776         stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE);
4777         if (!stats_req) {
4778                 ret = -ENOMEM;
4779                 goto err_unlock;
4780         }
4781
4782         ar->debug.htt_stats.stats_req = stats_req;
4783         stats_req->type = type;
4784
4785         ret = ath11k_debugfs_htt_stats_req(ar);
4786         if (ret < 0)
4787                 goto out;
4788
4789         file->private_data = stats_req;
4790
4791         mutex_unlock(&ar->conf_mutex);
4792
4793         return 0;
4794 out:
4795         vfree(stats_req);
4796         ar->debug.htt_stats.stats_req = NULL;
4797 err_unlock:
4798         mutex_unlock(&ar->conf_mutex);
4799
4800         return ret;
4801 }
4802
4803 static int ath11k_release_htt_stats(struct inode *inode, struct file *file)
4804 {
4805         struct ath11k *ar = inode->i_private;
4806
4807         mutex_lock(&ar->conf_mutex);
4808         vfree(file->private_data);
4809         ar->debug.htt_stats.stats_req = NULL;
4810         mutex_unlock(&ar->conf_mutex);
4811
4812         return 0;
4813 }
4814
4815 static ssize_t ath11k_read_htt_stats(struct file *file,
4816                                      char __user *user_buf,
4817                                      size_t count, loff_t *ppos)
4818 {
4819         struct debug_htt_stats_req *stats_req = file->private_data;
4820         char *buf;
4821         u32 length = 0;
4822
4823         buf = stats_req->buf;
4824         length = min_t(u32, stats_req->buf_len, ATH11K_HTT_STATS_BUF_SIZE);
4825         return simple_read_from_buffer(user_buf, count, ppos, buf, length);
4826 }
4827
4828 static const struct file_operations fops_dump_htt_stats = {
4829         .open = ath11k_open_htt_stats,
4830         .release = ath11k_release_htt_stats,
4831         .read = ath11k_read_htt_stats,
4832         .owner = THIS_MODULE,
4833         .llseek = default_llseek,
4834 };
4835
4836 static ssize_t ath11k_read_htt_stats_reset(struct file *file,
4837                                            char __user *user_buf,
4838                                            size_t count, loff_t *ppos)
4839 {
4840         struct ath11k *ar = file->private_data;
4841         char buf[32];
4842         size_t len;
4843
4844         len = scnprintf(buf, sizeof(buf), "%u\n", ar->debug.htt_stats.reset);
4845
4846         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
4847 }
4848
4849 static ssize_t ath11k_write_htt_stats_reset(struct file *file,
4850                                             const char __user *user_buf,
4851                                             size_t count, loff_t *ppos)
4852 {
4853         struct ath11k *ar = file->private_data;
4854         u8 type;
4855         struct htt_ext_stats_cfg_params cfg_params = { 0 };
4856         int ret;
4857
4858         ret = kstrtou8_from_user(user_buf, count, 0, &type);
4859         if (ret)
4860                 return ret;
4861
4862         if (type >= ATH11K_DBG_HTT_NUM_EXT_STATS ||
4863             type == ATH11K_DBG_HTT_EXT_STATS_RESET)
4864                 return -E2BIG;
4865
4866         mutex_lock(&ar->conf_mutex);
4867         cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET;
4868         cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type);
4869         ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar,
4870                                                  ATH11K_DBG_HTT_EXT_STATS_RESET,
4871                                                  &cfg_params,
4872                                                  0ULL);
4873         if (ret) {
4874                 ath11k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
4875                 mutex_unlock(&ar->conf_mutex);
4876                 return ret;
4877         }
4878
4879         ar->debug.htt_stats.reset = type;
4880         mutex_unlock(&ar->conf_mutex);
4881
4882         ret = count;
4883
4884         return ret;
4885 }
4886
4887 static const struct file_operations fops_htt_stats_reset = {
4888         .read = ath11k_read_htt_stats_reset,
4889         .write = ath11k_write_htt_stats_reset,
4890         .open = simple_open,
4891         .owner = THIS_MODULE,
4892         .llseek = default_llseek,
4893 };
4894
4895 void ath11k_debugfs_htt_stats_init(struct ath11k *ar)
4896 {
4897         spin_lock_init(&ar->debug.htt_stats.lock);
4898         debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev,
4899                             ar, &fops_htt_stats_type);
4900         debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev,
4901                             ar, &fops_dump_htt_stats);
4902         debugfs_create_file("htt_stats_reset", 0600, ar->debug.debugfs_pdev,
4903                             ar, &fops_htt_stats_reset);
4904 }