Commit adf6df96 authored by Dinesh Karthikeyan's avatar Dinesh Karthikeyan Committed by Kalle Valo

wifi: ath12k: Add support to parse requested stats_type

Add extended htt stats parser and print the corresponding TLVs associated
with the requested htt_stats_type.
Add support for TX PDEV related htt stats.

Sample output:
--------------
echo 1 > /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats_type
cat /sys/kernel/debug/ath12k/pci-0000\:06\:00.0/mac0/htt_stats

HTT_TX_PDEV_STATS_CMN_TLV:
mac_id = 0
comp_delivered = 0
self_triggers = 256
hw_queued = 275
hw_reaped = 275
underrun = 241
hw_paused = 0
hw_flush = 0
hw_filt = 1
tx_abort = 0
ppdu_ok = 246
mpdu_requeued = 0
tx_xretry = 0
data_rc = 3
mpdu_dropped_xretry = 0
illegal_rate_phy_err = 0
cont_xretry = 0
tx_timeout = 0
tx_time_dur_data = 0
pdev_resets = 0
phy_underrun = 0
txop_ovf = 0
seq_posted = 247
seq_failed_queueing = 0
seq_completed = 247
seq_restarted = 0
seq_txop_repost_stop = 0
next_seq_cancel = 0
dl_mu_mimo_seq_posted = 0
dl_mu_ofdma_seq_posted = 0
ul_mu_mimo_seq_posted = 0
ul_mu_ofdma_seq_posted = 0
mu_mimo_peer_blacklisted = 0
seq_qdepth_repost_stop = 0
seq_min_msdu_repost_stop = 0
mu_seq_min_msdu_repost_stop = 0
seq_switch_hw_paused = 0
next_seq_posted_dsr = 0
seq_posted_isr = 0
seq_ctrl_cached = 0
mpdu_count_tqm = 0
msdu_count_tqm = 0
mpdu_removed_tqm = 0
msdu_removed_tqm = 0
remove_mpdus_max_retries = 0
mpdus_sw_flush = 0
mpdus_hw_filter = 0
mpdus_truncated = 0
mpdus_ack_failed = 0
mpdus_expired = 0
mpdus_seq_hw_retry = 0
ack_tlv_proc = 0
coex_abort_mpdu_cnt_valid = 0
coex_abort_mpdu_cnt = 5
num_total_ppdus_tried_ota = 5
num_data_ppdus_tried_ota = 0
local_ctrl_mgmt_enqued = 247
local_ctrl_mgmt_freed = 247
local_data_enqued = 0
local_data_freed = 0
mpdu_tried = 0
isr_wait_seq_posted = 0
tx_active_dur_us_low = 0
tx_active_dur_us_high = 0
fes_offsets_err_cnt = 0

HTT_TX_PDEV_STATS_URRN_TLV:
urrn_stats =  0:0, 1:241, 2:0

HTT_TX_PDEV_STATS_SIFS_TLV:
sifs_status =  0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0

HTT_TX_PDEV_STATS_FLUSH_TLV:
flush_errs =  0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 10:0,
11:0, 12:0, 13:0, 14:0, 15:0, 16:0, 17:0, 18:0, 19:0, 20:0, 21:0, 22:0,
23:0, 24:0, 25:0, 26:0, 27:0, 28:0, 29:0, 30:0, 31:0, 32:0, 33:0, 34:0,
35:0, 36:0, 37:0, 38:0, 39:0, 40:0, 41:0, 42:0, 43:0, 44:0, 45:0, 46:0,
47:0, 48:0, 49:0, 50:0, 51:0, 52:0, 53:0, 54:0, 55:0, 56:0, 57:0, 58:0,
59:0, 60:0, 61:0, 62:0, 63:0, 64:0, 65:0, 66:0, 67:0, 68:0, 69:0, 70:0,
71:0, 72:0, 73:0, 74:0, 75:0, 76:0, 77:0, 78:0, 79:0, 80:0, 81:0, 82:0,
83:0, 84:0, 85:0, 86:0, 87:0, 88:0, 89:0, 90:0, 91:0, 92:0, 93:0, 94:0,
95:0, 96:0, 97:0, 98:0, 99:0, 100:0, 101:0, 102:0, 103:0, 104:0, 105:0,
106:0, 107:0, 108:0, 109:0, 110:0, 111:0, 112:0, 113:0, 114:0, 115:0,
116:0, 117:0, 118:0, 119:0, 120:0, 121:0, 122:0, 123:0, 124:0, 125:0,
126:0, 127:0

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: default avatarDinesh Karthikeyan <quic_dinek@quicinc.com>
Co-developed-by: default avatarRamya Gnanasekar <quic_rgnanase@quicinc.com>
Signed-off-by: default avatarRamya Gnanasekar <quic_rgnanase@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240626085854.2500681-4-quic_rgnanase@quicinc.com
parent ad201b35
......@@ -9,6 +9,334 @@
#include "debug.h"
#include "debugfs_htt_stats.h"
#include "dp_tx.h"
#include "dp_rx.h"
static u32
print_array_to_buf(u8 *buf, u32 offset, const char *header,
const __le32 *array, u32 array_len, const char *footer)
{
int index = 0;
u8 i;
if (header) {
index += scnprintf(buf + offset,
ATH12K_HTT_STATS_BUF_SIZE - offset,
"%s = ", header);
}
for (i = 0; i < array_len; i++) {
index += scnprintf(buf + offset + index,
(ATH12K_HTT_STATS_BUF_SIZE - offset) - index,
" %u:%u,", i, le32_to_cpu(array[i]));
}
/* To overwrite the last trailing comma */
index--;
*(buf + offset + index) = '\0';
if (footer) {
index += scnprintf(buf + offset + index,
(ATH12K_HTT_STATS_BUF_SIZE - offset) - index,
"%s", footer);
}
return index;
}
static void
htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct ath12k_htt_tx_pdev_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__word);
len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_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, "comp_delivered = %u\n",
le32_to_cpu(htt_stats_buf->comp_delivered));
len += scnprintf(buf + len, buf_len - len, "self_triggers = %u\n",
le32_to_cpu(htt_stats_buf->self_triggers));
len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
le32_to_cpu(htt_stats_buf->hw_queued));
len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
le32_to_cpu(htt_stats_buf->hw_reaped));
len += scnprintf(buf + len, buf_len - len, "underrun = %u\n",
le32_to_cpu(htt_stats_buf->underrun));
len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n",
le32_to_cpu(htt_stats_buf->hw_paused));
len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n",
le32_to_cpu(htt_stats_buf->hw_flush));
len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n",
le32_to_cpu(htt_stats_buf->hw_filt));
len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
le32_to_cpu(htt_stats_buf->tx_abort));
len += scnprintf(buf + len, buf_len - len, "ppdu_ok = %u\n",
le32_to_cpu(htt_stats_buf->ppdu_ok));
len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_requed));
len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n",
le32_to_cpu(htt_stats_buf->tx_xretry));
len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n",
le32_to_cpu(htt_stats_buf->data_rc));
len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_dropped_xretry));
len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n",
le32_to_cpu(htt_stats_buf->illgl_rate_phy_err));
len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n",
le32_to_cpu(htt_stats_buf->cont_xretry));
len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n",
le32_to_cpu(htt_stats_buf->tx_timeout));
len += scnprintf(buf + len, buf_len - len, "tx_time_dur_data = %u\n",
le32_to_cpu(htt_stats_buf->tx_time_dur_data));
len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n",
le32_to_cpu(htt_stats_buf->pdev_resets));
len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n",
le32_to_cpu(htt_stats_buf->phy_underrun));
len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n",
le32_to_cpu(htt_stats_buf->txop_ovf));
len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->seq_posted));
len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n",
le32_to_cpu(htt_stats_buf->seq_failed_queueing));
len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n",
le32_to_cpu(htt_stats_buf->seq_completed));
len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n",
le32_to_cpu(htt_stats_buf->seq_restarted));
len += scnprintf(buf + len, buf_len - len, "seq_txop_repost_stop = %u\n",
le32_to_cpu(htt_stats_buf->seq_txop_repost_stop));
len += scnprintf(buf + len, buf_len - len, "next_seq_cancel = %u\n",
le32_to_cpu(htt_stats_buf->next_seq_cancel));
len += scnprintf(buf + len, buf_len - len, "dl_mu_mimo_seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->mu_seq_posted));
len += scnprintf(buf + len, buf_len - len, "dl_mu_ofdma_seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->mu_ofdma_seq_posted));
len += scnprintf(buf + len, buf_len - len, "ul_mu_mimo_seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->ul_mumimo_seq_posted));
len += scnprintf(buf + len, buf_len - len, "ul_mu_ofdma_seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->ul_ofdma_seq_posted));
len += scnprintf(buf + len, buf_len - len, "mu_mimo_peer_blacklisted = %u\n",
le32_to_cpu(htt_stats_buf->num_mu_peer_blacklisted));
len += scnprintf(buf + len, buf_len - len, "seq_qdepth_repost_stop = %u\n",
le32_to_cpu(htt_stats_buf->seq_qdepth_repost_stop));
len += scnprintf(buf + len, buf_len - len, "seq_min_msdu_repost_stop = %u\n",
le32_to_cpu(htt_stats_buf->seq_min_msdu_repost_stop));
len += scnprintf(buf + len, buf_len - len, "mu_seq_min_msdu_repost_stop = %u\n",
le32_to_cpu(htt_stats_buf->mu_seq_min_msdu_repost_stop));
len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n",
le32_to_cpu(htt_stats_buf->seq_switch_hw_paused));
len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n",
le32_to_cpu(htt_stats_buf->next_seq_posted_dsr));
len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n",
le32_to_cpu(htt_stats_buf->seq_posted_isr));
len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n",
le32_to_cpu(htt_stats_buf->seq_ctrl_cached));
len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_count_tqm));
len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n",
le32_to_cpu(htt_stats_buf->msdu_count_tqm));
len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_removed_tqm));
len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n",
le32_to_cpu(htt_stats_buf->msdu_removed_tqm));
len += scnprintf(buf + len, buf_len - len, "remove_mpdus_max_retries = %u\n",
le32_to_cpu(htt_stats_buf->remove_mpdus_max_retries));
len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_sw_flush));
len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_hw_filter));
len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_truncated));
len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_ack_failed));
len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_expired));
len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n",
le32_to_cpu(htt_stats_buf->mpdus_seq_hw_retry));
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, "coex_abort_mpdu_cnt_valid = %u\n",
le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt_valid));
len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n",
le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt));
len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n",
le32_to_cpu(htt_stats_buf->num_total_ppdus_tried_ota));
len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n",
le32_to_cpu(htt_stats_buf->num_data_ppdus_tried_ota));
len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n",
le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_enqued));
len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n",
le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_freed));
len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n",
le32_to_cpu(htt_stats_buf->local_data_enqued));
len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n",
le32_to_cpu(htt_stats_buf->local_data_freed));
len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n",
le32_to_cpu(htt_stats_buf->mpdu_tried));
len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n",
le32_to_cpu(htt_stats_buf->isr_wait_seq_posted));
len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n",
le32_to_cpu(htt_stats_buf->tx_active_dur_us_low));
len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n",
le32_to_cpu(htt_stats_buf->tx_active_dur_us_high));
len += scnprintf(buf + len, buf_len - len, "fes_offsets_err_cnt = %u\n\n",
le32_to_cpu(htt_stats_buf->fes_offsets_err_cnt));
stats_req->buf_len = len;
}
static void
htt_print_tx_pdev_stats_urrn_tlv(const void *tag_buf,
u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct ath12k_htt_tx_pdev_stats_urrn_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),
HTT_TX_PDEV_MAX_URRN_STATS);
len += scnprintf(buf + len, buf_len - len,
"HTT_TX_PDEV_STATS_URRN_TLV:\n");
len += print_array_to_buf(buf, len, "urrn_stats", htt_stats_buf->urrn_stats,
num_elems, "\n\n");
stats_req->buf_len = len;
}
static void
htt_print_tx_pdev_stats_flush_tlv(const void *tag_buf,
u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct ath12k_htt_tx_pdev_stats_flush_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_PDEV_MAX_FLUSH_REASON_STATS);
len += scnprintf(buf + len, buf_len - len,
"HTT_TX_PDEV_STATS_FLUSH_TLV:\n");
len += print_array_to_buf(buf, len, "flush_errs", htt_stats_buf->flush_errs,
num_elems, "\n\n");
stats_req->buf_len = len;
}
static void
htt_print_tx_pdev_stats_sifs_tlv(const void *tag_buf,
u16 tag_len,
struct debug_htt_stats_req *stats_req)
{
const struct ath12k_htt_tx_pdev_stats_sifs_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_PDEV_MAX_SIFS_BURST_STATS);
len += scnprintf(buf + len, buf_len - len,
"HTT_TX_PDEV_STATS_SIFS_TLV:\n");
len += print_array_to_buf(buf, len, "sifs_status", htt_stats_buf->sifs_status,
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)
{
struct debug_htt_stats_req *stats_req = user_data;
switch (tag) {
case HTT_STATS_TX_PDEV_CMN_TAG:
htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_TX_PDEV_UNDERRUN_TAG:
htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_TX_PDEV_SIFS_TAG:
htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req);
break;
case HTT_STATS_TX_PDEV_FLUSH_TAG:
htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req);
break;
default:
break;
}
return 0;
}
void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
struct sk_buff *skb)
{
struct ath12k_htt_extd_stats_msg *msg;
struct debug_htt_stats_req *stats_req;
struct ath12k *ar;
u32 len, pdev_id, stats_info;
u64 cookie;
int ret;
bool send_completion = false;
msg = (struct ath12k_htt_extd_stats_msg *)skb->data;
cookie = le64_to_cpu(msg->cookie);
if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) !=
ATH12K_HTT_STATS_MAGIC_VALUE) {
ath12k_warn(ab, "received invalid htt ext stats event\n");
return;
}
pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB);
rcu_read_lock();
ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
if (!ar) {
ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id);
goto exit;
}
stats_req = ar->debug.htt_stats.stats_req;
if (!stats_req)
goto exit;
spin_lock_bh(&ar->data_lock);
stats_info = le32_to_cpu(msg->info1);
stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE);
if (stats_req->done)
send_completion = true;
spin_unlock_bh(&ar->data_lock);
len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH);
if (len > skb->len) {
ath12k_warn(ab, "invalid length %d for HTT stats", len);
goto exit;
}
ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
ath12k_dbg_htt_ext_stats_parse,
stats_req);
if (ret)
ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
if (send_completion)
complete(&stats_req->htt_stats_rcvd);
exit:
rcu_read_unlock();
}
static ssize_t ath12k_read_htt_stats_type(struct file *file,
char __user *user_buf,
......
......@@ -21,14 +21,134 @@
void ath12k_debugfs_htt_stats_register(struct ath12k *ar);
#ifdef CONFIG_ATH12K_DEBUGFS
void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
struct sk_buff *skb);
#else /* CONFIG_ATH12K_DEBUGFS */
static inline void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab,
struct sk_buff *skb)
{
}
#endif
/**
* DOC: target -> host extended statistics upload
*
* The following field definitions describe the format of the HTT
* target to host stats upload confirmation message.
* The message contains a cookie echoed from the HTT host->target stats
* upload request, which identifies which request the confirmation is
* for, and a single stats can span over multiple HTT stats indication
* due to the HTT message size limitation so every HTT ext stats
* indication will have tag-length-value stats information elements.
* The tag-length header for each HTT stats IND message also includes a
* status field, to indicate whether the request for the stat type in
* question was fully met, partially met, unable to be met, or invalid
* (if the stat type in question is disabled in the target).
* A Done bit 1's indicate the end of the of stats info elements.
*
*
* |31 16|15 12|11|10 8|7 5|4 0|
* |--------------------------------------------------------------|
* | reserved | msg type |
* |--------------------------------------------------------------|
* | cookie LSBs |
* |--------------------------------------------------------------|
* | cookie MSBs |
* |--------------------------------------------------------------|
* | stats entry length | rsvd | D| S | stat type |
* |--------------------------------------------------------------|
* | type-specific stats info |
* | (see debugfs_htt_stats.h) |
* |--------------------------------------------------------------|
* Header fields:
* - MSG_TYPE
* Bits 7:0
* Purpose: Identifies this is a extended statistics upload confirmation
* message.
* Value: 0x1c
* - COOKIE_LSBS
* Bits 31:0
* Purpose: Provide a mechanism to match a target->host stats confirmation
* message with its preceding host->target stats request message.
* Value: MSBs of the opaque cookie specified by the host-side requestor
* - COOKIE_MSBS
* Bits 31:0
* Purpose: Provide a mechanism to match a target->host stats confirmation
* message with its preceding host->target stats request message.
* Value: MSBs of the opaque cookie specified by the host-side requestor
*
* Stats Information Element tag-length header fields:
* - STAT_TYPE
* Bits 7:0
* Purpose: identifies the type of statistics info held in the
* following information element
* Value: ath12k_dbg_htt_ext_stats_type
* - STATUS
* Bits 10:8
* Purpose: indicate whether the requested stats are present
* Value:
* 0 -> The requested stats have been delivered in full
* 1 -> The requested stats have been delivered in part
* 2 -> The requested stats could not be delivered (error case)
* 3 -> The requested stat type is either not recognized (invalid)
* - DONE
* Bits 11
* Purpose:
* Indicates the completion of the stats entry, this will be the last
* stats conf HTT segment for the requested stats type.
* Value:
* 0 -> the stats retrieval is ongoing
* 1 -> the stats retrieval is complete
* - LENGTH
* Bits 31:16
* Purpose: indicate the stats information size
* Value: This field specifies the number of bytes of stats information
* that follows the element tag-length header.
* It is expected but not required that this length is a multiple of
* 4 bytes.
*/
#define ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE BIT(11)
#define ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH GENMASK(31, 16)
struct ath12k_htt_extd_stats_msg {
__le32 info0;
__le64 cookie;
__le32 info1;
u8 data[];
} __packed;
/* htt_dbg_ext_stats_type */
enum ath12k_dbg_htt_ext_stats_type {
ATH12K_DBG_HTT_EXT_STATS_RESET = 0,
ATH12K_DBG_HTT_EXT_STATS_PDEV_TX = 1,
/* keep this last */
ATH12K_DBG_HTT_NUM_EXT_STATS,
};
enum ath12k_dbg_htt_tlv_tag {
HTT_STATS_TX_PDEV_CMN_TAG = 0,
HTT_STATS_TX_PDEV_UNDERRUN_TAG = 1,
HTT_STATS_TX_PDEV_SIFS_TAG = 2,
HTT_STATS_TX_PDEV_FLUSH_TAG = 3,
HTT_STATS_MAX_TAG,
};
#define ATH12K_HTT_STATS_MAC_ID GENMASK(7, 0)
#define ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS 9
#define ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS 150
enum ath12k_htt_tx_pdev_underrun_enum {
HTT_STATS_TX_PDEV_NO_DATA_UNDERRUN = 0,
HTT_STATS_TX_PDEV_DATA_UNDERRUN_BETWEEN_MPDU = 1,
HTT_STATS_TX_PDEV_DATA_UNDERRUN_WITHIN_MPDU = 2,
HTT_TX_PDEV_MAX_URRN_STATS = 3,
};
enum ath12k_htt_stats_reset_cfg_param_alloc_pos {
ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES = 1,
ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES,
......@@ -47,4 +167,95 @@ struct debug_htt_stats_req {
u8 buf[];
};
struct ath12k_htt_tx_pdev_stats_cmn_tlv {
__le32 mac_id__word;
__le32 hw_queued;
__le32 hw_reaped;
__le32 underrun;
__le32 hw_paused;
__le32 hw_flush;
__le32 hw_filt;
__le32 tx_abort;
__le32 mpdu_requed;
__le32 tx_xretry;
__le32 data_rc;
__le32 mpdu_dropped_xretry;
__le32 illgl_rate_phy_err;
__le32 cont_xretry;
__le32 tx_timeout;
__le32 pdev_resets;
__le32 phy_underrun;
__le32 txop_ovf;
__le32 seq_posted;
__le32 seq_failed_queueing;
__le32 seq_completed;
__le32 seq_restarted;
__le32 mu_seq_posted;
__le32 seq_switch_hw_paused;
__le32 next_seq_posted_dsr;
__le32 seq_posted_isr;
__le32 seq_ctrl_cached;
__le32 mpdu_count_tqm;
__le32 msdu_count_tqm;
__le32 mpdu_removed_tqm;
__le32 msdu_removed_tqm;
__le32 mpdus_sw_flush;
__le32 mpdus_hw_filter;
__le32 mpdus_truncated;
__le32 mpdus_ack_failed;
__le32 mpdus_expired;
__le32 mpdus_seq_hw_retry;
__le32 ack_tlv_proc;
__le32 coex_abort_mpdu_cnt_valid;
__le32 coex_abort_mpdu_cnt;
__le32 num_total_ppdus_tried_ota;
__le32 num_data_ppdus_tried_ota;
__le32 local_ctrl_mgmt_enqued;
__le32 local_ctrl_mgmt_freed;
__le32 local_data_enqued;
__le32 local_data_freed;
__le32 mpdu_tried;
__le32 isr_wait_seq_posted;
__le32 tx_active_dur_us_low;
__le32 tx_active_dur_us_high;
__le32 remove_mpdus_max_retries;
__le32 comp_delivered;
__le32 ppdu_ok;
__le32 self_triggers;
__le32 tx_time_dur_data;
__le32 seq_qdepth_repost_stop;
__le32 mu_seq_min_msdu_repost_stop;
__le32 seq_min_msdu_repost_stop;
__le32 seq_txop_repost_stop;
__le32 next_seq_cancel;
__le32 fes_offsets_err_cnt;
__le32 num_mu_peer_blacklisted;
__le32 mu_ofdma_seq_posted;
__le32 ul_mumimo_seq_posted;
__le32 ul_ofdma_seq_posted;
__le32 thermal_suspend_cnt;
__le32 dfs_suspend_cnt;
__le32 tx_abort_suspend_cnt;
__le32 tgt_specific_opaque_txq_suspend_info;
__le32 last_suspend_reason;
} __packed;
struct ath12k_htt_tx_pdev_stats_urrn_tlv {
DECLARE_FLEX_ARRAY(__le32, urrn_stats);
} __packed;
struct ath12k_htt_tx_pdev_stats_flush_tlv {
DECLARE_FLEX_ARRAY(__le32, flush_errs);
} __packed;
struct ath12k_htt_tx_pdev_stats_phy_err_tlv {
DECLARE_FLEX_ARRAY(__le32, phy_errs);
} __packed;
struct ath12k_htt_tx_pdev_stats_sifs_tlv {
DECLARE_FLEX_ARRAY(__le32, sifs_status);
} __packed;
#endif
......@@ -17,6 +17,7 @@
#include "dp_tx.h"
#include "peer.h"
#include "dp_mon.h"
#include "debugfs_htt_stats.h"
#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)
......@@ -1268,10 +1269,10 @@ static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab,
return 0;
}
static int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
const void *ptr, void *data),
void *data)
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
const void *ptr, void *data),
void *data)
{
const struct htt_tlv *tlv;
const void *begin = ptr;
......@@ -1741,6 +1742,7 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
ath12k_htt_pull_ppdu_stats(ab, skb);
break;
case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:
ath12k_debugfs_htt_ext_stats_handler(ab, skb);
break;
case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND:
ath12k_htt_mlo_offset_event_handler(ab, skb);
......
......@@ -139,4 +139,8 @@ ath12k_dp_rx_h_find_peer(struct ath12k_base *ab, struct sk_buff *msdu);
int ath12k_dp_rxdma_ring_sel_config_qcn9274(struct ath12k_base *ab);
int ath12k_dp_rxdma_ring_sel_config_wcn7850(struct ath12k_base *ab);
int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
const void *ptr, void *data),
void *data);
#endif /* ATH12K_DP_RX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment