@@ -1447,6 +1447,134 @@ ath12k_htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u16 tag_len,
stats_req->buf_len = len;
}
+static void
+htt_print_tx_hwq_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
+ struct debug_htt_stats_req *stats_req)
+{
+ const struct ath12k_htt_tx_hwq_stats_cmn_tlv *htt_stats_buf = tag_buf;
+ u8 *buf = stats_req->buf;
+ u32 len = stats_req->buf_len;
+ u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
+ u32 mac_id_word;
+
+ if (tag_len < sizeof(*htt_stats_buf))
+ return;
+
+ mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__hwq_id__word);
+
+ len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n");
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
+ u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID));
+ len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n",
+ u32_get_bits(mac_id_word, ATH12K_HTT_STATS_HWQ_ID));
+ len += scnprintf(buf + len, buf_len - len, "xretry = %u\n",
+ le32_to_cpu(htt_stats_buf->xretry));
+ len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->underrun_cnt));
+ len += scnprintf(buf + len, buf_len - len, "flush_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->flush_cnt));
+ len += scnprintf(buf + len, buf_len - len, "filt_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->filt_cnt));
+ len += scnprintf(buf + len, buf_len - len, "null_mpdu_bmap = %u\n",
+ le32_to_cpu(htt_stats_buf->null_mpdu_bmap));
+ len += scnprintf(buf + len, buf_len - len, "user_ack_failure = %u\n",
+ le32_to_cpu(htt_stats_buf->user_ack_failure));
+ len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n",
+ le32_to_cpu(htt_stats_buf->ack_tlv_proc));
+ len += scnprintf(buf + len, buf_len - len, "sched_id_proc = %u\n",
+ le32_to_cpu(htt_stats_buf->sched_id_proc));
+ len += scnprintf(buf + len, buf_len - len, "null_mpdu_tx_count = %u\n",
+ le32_to_cpu(htt_stats_buf->null_mpdu_tx_count));
+ len += scnprintf(buf + len, buf_len - len, "mpdu_bmap_not_recvd = %u\n",
+ le32_to_cpu(htt_stats_buf->mpdu_bmap_not_recvd));
+ len += scnprintf(buf + len, buf_len - len, "num_bar = %u\n",
+ le32_to_cpu(htt_stats_buf->num_bar));
+ len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
+ le32_to_cpu(htt_stats_buf->rts));
+ len += scnprintf(buf + len, buf_len - len, "cts2self = %u\n",
+ le32_to_cpu(htt_stats_buf->cts2self));
+ len += scnprintf(buf + len, buf_len - len, "qos_null = %u\n",
+ le32_to_cpu(htt_stats_buf->qos_null));
+ len += scnprintf(buf + len, buf_len - len, "mpdu_tried_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->mpdu_tried_cnt));
+ len += scnprintf(buf + len, buf_len - len, "mpdu_queued_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->mpdu_queued_cnt));
+ len += scnprintf(buf + len, buf_len - len, "mpdu_ack_fail_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->mpdu_ack_fail_cnt));
+ len += scnprintf(buf + len, buf_len - len, "mpdu_filt_cnt = %u\n",
+ le32_to_cpu(htt_stats_buf->mpdu_filt_cnt));
+ len += scnprintf(buf + len, buf_len - len, "false_mpdu_ack_count = %u\n",
+ le32_to_cpu(htt_stats_buf->false_mpdu_ack_count));
+ len += scnprintf(buf + len, buf_len - len, "txq_timeout = %u\n\n",
+ le32_to_cpu(htt_stats_buf->txq_timeout));
+
+ stats_req->buf_len = len;
+}
+
+static void
+htt_print_tx_hwq_cmd_result_stats_tlv(const void *tag_buf,
+ u16 tag_len,
+ struct debug_htt_stats_req *stats_req)
+{
+ const struct ath12k_htt_tx_hwq_cmd_result_stats_tlv *htt_stats_buf = tag_buf;
+ u8 *buf = stats_req->buf;
+ u32 len = stats_req->buf_len;
+ u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
+ u16 num_elems = min_t(u16, (tag_len >> 2),
+ ATH12K_HTT_TX_HWQ_MAX_CMD_RESULT_STATS);
+
+ len += scnprintf(buf + len, buf_len - len,
+ "HTT_TX_HWQ_CMD_RESULT_STATS_TLV:\n");
+
+ len += print_array_to_buf(buf, len, "cmd_result", htt_stats_buf->cmd_result,
+ num_elems, "\n\n");
+
+ stats_req->buf_len = len;
+}
+
+static void
+htt_print_tx_hwq_cmd_stall_stats_tlv(const void *tag_buf,
+ u16 tag_len,
+ struct debug_htt_stats_req *stats_req)
+{
+ const struct ath12k_htt_tx_hwq_cmd_stall_stats_tlv *htt_stats_buf = tag_buf;
+ u8 *buf = stats_req->buf;
+ u32 len = stats_req->buf_len;
+ u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
+ u16 num_elems = min_t(u16, (tag_len >> 2),
+ ATH12K_HTT_TX_HWQ_MAX_CMD_STALL_STATS);
+
+ len += scnprintf(buf + len, buf_len - len,
+ "HTT_TX_HWQ_CMD_STALL_STATS_TLV:\n");
+
+ len += print_array_to_buf(buf, len, "cmd_stall_status",
+ htt_stats_buf->cmd_stall_status,
+ num_elems, "\n\n");
+
+ stats_req->buf_len = len;
+}
+
+static void
+htt_print_tx_hwq_fes_result_stats_tlv(const void *tag_buf,
+ u16 tag_len,
+ struct debug_htt_stats_req *stats_req)
+{
+ const struct ath12k_htt_tx_hwq_fes_result_stats_tlv *htt_stats_buf = tag_buf;
+ u8 *buf = stats_req->buf;
+ u32 len = stats_req->buf_len;
+ u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE;
+ u16 num_elems = min_t(u16, (tag_len >> 2),
+ ATH12K_HTT_TX_HWQ_MAX_FES_RESULT_STATS);
+
+ len += scnprintf(buf + len, buf_len - len,
+ "HTT_TX_HWQ_FES_RESULT_STATS_TLV:\n");
+
+ len += print_array_to_buf(buf, len, "fes_result", htt_stats_buf->fes_result,
+ num_elems, "\n\n");
+
+ stats_req->buf_len = len;
+}
+
static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
u16 tag, u16 len, const void *tag_buf,
void *user_data)
@@ -1552,6 +1680,18 @@ static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab,
case HTT_STATS_TX_DE_COMPL_STATS_TAG:
ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req);
break;
+ case HTT_STATS_TX_HWQ_CMN_TAG:
+ htt_print_tx_hwq_stats_cmn_tlv(tag_buf, len, stats_req);
+ break;
+ case HTT_STATS_TX_HWQ_CMD_RESULT_TAG:
+ htt_print_tx_hwq_cmd_result_stats_tlv(tag_buf, len, stats_req);
+ break;
+ case HTT_STATS_TX_HWQ_CMD_STALL_TAG:
+ htt_print_tx_hwq_cmd_stall_stats_tlv(tag_buf, len, stats_req);
+ break;
+ case HTT_STATS_TX_HWQ_FES_STATUS_TAG:
+ htt_print_tx_hwq_fes_result_stats_tlv(tag_buf, len, stats_req);
+ break;
default:
break;
}
@@ -1683,6 +1823,24 @@ static const struct file_operations fops_htt_stats_type = {
.llseek = default_llseek,
};
+static int ath12k_prep_htt_stats_cfg_params(struct ath12k *ar,
+ enum ath12k_dbg_htt_ext_stats_type type,
+ struct htt_ext_stats_cfg_params *cfg_params)
+{
+ if (!cfg_params)
+ return -EINVAL;
+
+ switch (type) {
+ case ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ:
+ cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ALL_HWQS;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
{
struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req;
@@ -1703,6 +1861,12 @@ static int ath12k_debugfs_htt_stats_req(struct ath12k *ar)
ATH12K_HTT_STATS_COOKIE_MSB);
cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB);
+ ret = ath12k_prep_htt_stats_cfg_params(ar, type, &cfg_params);
+ if (ret) {
+ ath12k_warn(ar->ab, "failed to set htt stats cfg params: %d\n", ret);
+ return ret;
+ }
+
if (stats_req->override_cfg_param) {
cfg_params.cfg0 = stats_req->cfg_param[0];
cfg_params.cfg1 = stats_req->cfg_param[1];
@@ -125,6 +125,7 @@ struct ath12k_htt_extd_stats_msg {
enum ath12k_dbg_htt_ext_stats_type {
ATH12K_DBG_HTT_EXT_STATS_RESET = 0,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1,
+ ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_HWQ = 3,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX_SCHED = 4,
ATH12K_DBG_HTT_EXT_STATS_PDEV_ERROR = 5,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TQM = 6,
@@ -139,6 +140,10 @@ enum ath12k_dbg_htt_tlv_tag {
HTT_STATS_TX_PDEV_UNDERRUN_TAG = 1,
HTT_STATS_TX_PDEV_SIFS_TAG = 2,
HTT_STATS_TX_PDEV_FLUSH_TAG = 3,
+ HTT_STATS_TX_HWQ_CMN_TAG = 6,
+ HTT_STATS_TX_HWQ_CMD_RESULT_TAG = 8,
+ HTT_STATS_TX_HWQ_CMD_STALL_TAG = 9,
+ HTT_STATS_TX_HWQ_FES_STATUS_TAG = 10,
HTT_STATS_TX_TQM_GEN_MPDU_TAG = 11,
HTT_STATS_TX_TQM_LIST_MPDU_TAG = 12,
HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG = 13,
@@ -172,6 +177,7 @@ enum ath12k_dbg_htt_tlv_tag {
};
#define ATH12K_HTT_STATS_MAC_ID GENMASK(7, 0)
+#define ATH12K_HTT_STATS_HWQ_ID GENMASK(15, 8)
#define ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS 9
#define ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS 150
@@ -690,4 +696,44 @@ struct ath12k_htt_tx_de_compl_stats_tlv {
__le32 tqm_bypass_frame;
} __packed;
+#define ATH12K_HTT_TX_HWQ_MAX_CMD_RESULT_STATS 13
+#define ATH12K_HTT_TX_HWQ_MAX_CMD_STALL_STATS 5
+#define ATH12K_HTT_TX_HWQ_MAX_FES_RESULT_STATS 10
+
+struct ath12k_htt_tx_hwq_stats_cmn_tlv {
+ __le32 mac_id__hwq_id__word;
+ __le32 xretry;
+ __le32 underrun_cnt;
+ __le32 flush_cnt;
+ __le32 filt_cnt;
+ __le32 null_mpdu_bmap;
+ __le32 user_ack_failure;
+ __le32 ack_tlv_proc;
+ __le32 sched_id_proc;
+ __le32 null_mpdu_tx_count;
+ __le32 mpdu_bmap_not_recvd;
+ __le32 num_bar;
+ __le32 rts;
+ __le32 cts2self;
+ __le32 qos_null;
+ __le32 mpdu_tried_cnt;
+ __le32 mpdu_queued_cnt;
+ __le32 mpdu_ack_fail_cnt;
+ __le32 mpdu_filt_cnt;
+ __le32 false_mpdu_ack_count;
+ __le32 txq_timeout;
+} __packed;
+
+struct ath12k_htt_tx_hwq_cmd_result_stats_tlv {
+ DECLARE_FLEX_ARRAY(__le32, cmd_result);
+} __packed;
+
+struct ath12k_htt_tx_hwq_cmd_stall_stats_tlv {
+ DECLARE_FLEX_ARRAY(__le32, cmd_stall_status);
+} __packed;
+
+struct ath12k_htt_tx_hwq_fes_result_stats_tlv {
+ DECLARE_FLEX_ARRAY(__le32, fes_result);
+} __packed;
+
#endif