Linux Audio

Check our new training course

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