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