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