brintos

brintos / linux-shallow public Read only

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