mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 04:42:20 +00:00
403 lines
15 KiB
Diff
403 lines
15 KiB
Diff
From b6440e6cb4f9e63d5c897d419191ef63bf1f3caf Mon Sep 17 00:00:00 2001
|
|
From: Hari Chandrakanthan <haric@codeaurora.org>
|
|
Date: Thu, 8 Jul 2021 14:19:48 +0530
|
|
Subject: [PATCH] ath11k : add support for tx completion stats
|
|
|
|
Tx completion stats provides the status of the tx completion of data pkts
|
|
reported in tx completion ring(WBM).
|
|
|
|
The stats support is added for each vif and peer.
|
|
|
|
To read vif specific stats:
|
|
cat /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/wbm_tx_comple
|
|
tion_stats
|
|
|
|
To read station specific stats:
|
|
cat /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/xx\:
|
|
xx\:xx\:xx\:xx\:xx/tx_stats
|
|
|
|
To clear vif specific stats:
|
|
echo 1 > /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/wbm_tx_comple
|
|
tion_stats
|
|
|
|
To clear station specific stats:
|
|
echo 1 > /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/xx\:
|
|
xx\:xx\:xx\:xx\:xx/reset_tx_stats
|
|
|
|
sample log:
|
|
cat /sys/kernel/debug/ieee80211/phy2/netdev\:wlan2/wbm_tx_comple
|
|
tion_stats
|
|
WBM tx completion stats of data pkts :
|
|
Acked pkt count : 13071
|
|
Status ttl pkt count : 1190
|
|
Dropped pkt count : 5729
|
|
Reinj pkt count : 594
|
|
Inspect pkt count : 434
|
|
MEC notify pkt count : 138
|
|
Signed-off-by: Hari Chandrakanthan <haric@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 6 +++
|
|
drivers/net/wireless/ath/ath11k/debugfs.c | 73 +++++++++++++++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/debugfs.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 25 +++++++--
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 3 +-
|
|
drivers/net/wireless/ath/ath11k/dp_tx.c | 22 ++++++--
|
|
drivers/net/wireless/ath/ath11k/hal_desc.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/mac.c | 10 ++++
|
|
8 files changed, 131 insertions(+), 10 deletions(-)
|
|
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/core.h
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -294,10 +294,12 @@ struct ath11k_vif {
|
|
struct dentry *amsdu_aggr_size;
|
|
struct dentry *wmi_ctrl_stat;
|
|
struct dentry *mac_filter;
|
|
+ struct dentry *wbm_tx_completion_stats;
|
|
struct ath11k_mgmt_frame_stats mgmt_stats;
|
|
/* protected by conf_mutex */
|
|
struct list_head mac_filters;
|
|
u32 mac_filter_count;
|
|
+ u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX];
|
|
struct arvif_nss nss;
|
|
struct list_head ap_vlan_arvifs;
|
|
/* VLAN keyidx map required for Dynamic VLAN */
|
|
@@ -405,6 +407,10 @@ struct ath11k_htt_data_stats {
|
|
u64 ru_loc[ATH11K_COUNTER_TYPE_MAX][HAL_RX_RU_ALLOC_TYPE_MAX];
|
|
};
|
|
|
|
+struct ath11k_wbm_tx_stats {
|
|
+ u64 wbm_tx_comp_stats[HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX];
|
|
+};
|
|
+
|
|
struct ath11k_htt_tx_stats {
|
|
struct ath11k_htt_data_stats stats[ATH11K_STATS_TYPE_MAX];
|
|
u64 tx_duration;
|
|
@@ -479,6 +485,7 @@ struct ath11k_sta {
|
|
u32 ps_start_jiffies;
|
|
u8 peer_current_ps_valid;
|
|
u32 ps_total_duration;
|
|
+ struct ath11k_wbm_tx_stats *wbm_tx_stats;
|
|
#ifdef CPTCFG_ATH11K_CFR
|
|
struct ath11k_per_peer_cfr_capture cfr_capture;
|
|
#endif
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
@@ -574,6 +574,81 @@ void ath11k_debugfs_wmi_ctrl_stats(struc
|
|
init_completion(&arvif->ar->debug.wmi_ctrl_path_stats_rcvd);
|
|
}
|
|
|
|
+static ssize_t ath11k_wbm_tx_comp_stats_read(struct file *file,
|
|
+ char __user *user_buf,
|
|
+ size_t count,
|
|
+ loff_t *ppos)
|
|
+{
|
|
+ struct ath11k_vif *arvif = file->private_data;
|
|
+ struct ath11k *ar = arvif->ar;
|
|
+ char buf[256] = {0};
|
|
+ int len = 0;
|
|
+ char *fields[] = {[HAL_WBM_REL_HTT_TX_COMP_STATUS_OK] = "Acked pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL] = "Status ttl pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP] = "Dropped pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ] = "Reinj pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT] = "Inspect pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY] = "MEC notify pkt count"};
|
|
+ int idx;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+
|
|
+ if (!arvif->is_started) {
|
|
+ len += scnprintf(buf + len, sizeof(buf) - len, "vif not started\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ len += scnprintf(buf + len, sizeof(buf) - len, "WBM tx completion stats of data pkts :\n");
|
|
+ for(idx = 0; idx <= HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY; idx++) {
|
|
+ len += scnprintf(buf + len, sizeof(buf) - len,
|
|
+ "%-23s : %llu\n",
|
|
+ fields[idx],
|
|
+ arvif->wbm_tx_comp_stats[idx]);
|
|
+ }
|
|
+
|
|
+out:
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+}
|
|
+
|
|
+static ssize_t ath11k_wbm_tx_comp_stats_write(struct file *file,
|
|
+ const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath11k_vif *arvif = file->private_data;
|
|
+ struct ath11k *ar = arvif->ar;
|
|
+ u8 reset;
|
|
+ int ret;
|
|
+
|
|
+ ret = kstrtou8_from_user(user_buf, count, 0, &reset);
|
|
+
|
|
+ if (ret || reset != 1)
|
|
+ return -EINVAL;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+ if (arvif->is_started)
|
|
+ memset(arvif->wbm_tx_comp_stats, 0, sizeof(arvif->wbm_tx_comp_stats));
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_wbm_tx_comp_stats = {
|
|
+ .write = ath11k_wbm_tx_comp_stats_write,
|
|
+ .read = ath11k_wbm_tx_comp_stats_read,
|
|
+ .open = simple_open,
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
+
|
|
+void ath11k_debugfs_wbm_tx_comp_stats(struct ath11k_vif *arvif)
|
|
+{
|
|
+ arvif->wbm_tx_completion_stats =
|
|
+ debugfs_create_file("wbm_tx_completion_stats",
|
|
+ S_IRUSR | S_IWUSR, arvif->vif->debugfs_dir,
|
|
+ arvif, &fops_wbm_tx_comp_stats);
|
|
+}
|
|
+
|
|
static ssize_t ath11k_write_ampdu_aggr_size(struct file *file,
|
|
const char __user *ubuf,
|
|
size_t count, loff_t *ppos)
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.h
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/debugfs.h
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs.h
|
|
@@ -194,6 +194,7 @@ static void ath11k_debugfs_dbg_mac_filte
|
|
}
|
|
#endif
|
|
|
|
+void ath11k_debugfs_wbm_tx_comp_stats(struct ath11k_vif *arvif);
|
|
void ath11k_debug_aggr_size_config_init(struct ath11k_vif *arvif);
|
|
void ath11k_debugfs_wmi_ctrl_stats(struct ath11k_vif *arvif);
|
|
void ath11k_wmi_crl_path_stats_list_free(struct list_head *head);
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
@@ -316,8 +316,15 @@ static ssize_t ath11k_dbg_sta_dump_tx_st
|
|
const int size = 2 * 4096;
|
|
char *buf, mu_group_id[MAX_MU_GROUP_LENGTH] = {0};
|
|
u32 index;
|
|
+ char *fields[] = {[HAL_WBM_REL_HTT_TX_COMP_STATUS_OK] = "Acked pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL] = "Status ttl pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP] = "Dropped pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ] = "Reinj pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT] = "Inspect pkt count",
|
|
+ [HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY] = "MEC notify pkt count"};
|
|
+ int idx;
|
|
|
|
- if (!arsta->tx_stats)
|
|
+ if (!arsta->tx_stats || !arsta->wbm_tx_stats)
|
|
return -ENOENT;
|
|
|
|
buf = kzalloc(size, GFP_KERNEL);
|
|
@@ -449,7 +456,15 @@ static ssize_t ath11k_dbg_sta_dump_tx_st
|
|
len += scnprintf(buf + len, size - len,
|
|
"BA fails\n %llu\n", arsta->tx_stats->ba_fails);
|
|
len += scnprintf(buf + len, size - len,
|
|
- "ack fails\n %llu\n", arsta->tx_stats->ack_fails);
|
|
+ "ack fails\n %llu\n\n", arsta->tx_stats->ack_fails);
|
|
+
|
|
+ len += scnprintf(buf + len, size - len, "WBM tx completion stats of data pkts :\n");
|
|
+ for (idx = 0; idx <= HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY; idx++) {
|
|
+ len += scnprintf(buf + len, size - len,
|
|
+ "%-23s : %llu\n",
|
|
+ fields[idx],
|
|
+ arsta->wbm_tx_stats->wbm_tx_comp_stats[idx]);
|
|
+ }
|
|
|
|
spin_unlock_bh(&ar->data_lock);
|
|
|
|
@@ -1253,7 +1268,7 @@ static ssize_t ath11k_dbg_sta_reset_tx_s
|
|
struct ath11k *ar = arsta->arvif->ar;
|
|
int ret, reset;
|
|
|
|
- if (!arsta->tx_stats)
|
|
+ if (!arsta->tx_stats || !arsta->wbm_tx_stats)
|
|
return -ENOENT;
|
|
|
|
ret = kstrtoint_from_user(buf, count, 0, &reset);
|
|
@@ -1267,6 +1282,7 @@ static ssize_t ath11k_dbg_sta_reset_tx_s
|
|
memset(arsta->tx_stats, 0, sizeof(*arsta->tx_stats));
|
|
atomic_set(&arsta->drv_tx_pkts.pkts_in, 0);
|
|
atomic_set(&arsta->drv_tx_pkts.pkts_out, 0);
|
|
+ memset(arsta->wbm_tx_stats->wbm_tx_comp_stats, 0, sizeof(*arsta->wbm_tx_stats));
|
|
spin_unlock_bh(&ar->ab->base_lock);
|
|
|
|
ret = count;
|
|
@@ -1527,4 +1543,5 @@ void ath11k_debugfs_sta_op_add(struct ie
|
|
debugfs_create_file("cfr_capture", 0400, dir, sta,
|
|
&fops_peer_cfr_capture);
|
|
#endif/* CPTCFG_ATH11K_CFR */
|
|
+
|
|
}
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -1652,8 +1652,7 @@ ath11k_update_per_peer_tx_stats(struct a
|
|
peer_stats->mu_grpid = mu_grpid;
|
|
peer_stats->mu_pos = mu_pos;
|
|
peer_stats->ru_tones = arsta->txrate.he_ru_alloc;
|
|
-
|
|
- if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))
|
|
+ if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar)))
|
|
ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx);
|
|
}
|
|
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
@@ -530,7 +530,8 @@ static void ath11k_dp_tx_cache_peer_stat
|
|
|
|
static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
|
|
struct sk_buff *msdu,
|
|
- struct hal_tx_status *ts)
|
|
+ struct hal_tx_status *ts,
|
|
+ enum hal_wbm_htt_tx_comp_status wbm_status)
|
|
{
|
|
struct ieee80211_tx_status status = { 0 };
|
|
struct ath11k_base *ab = ar->ab;
|
|
@@ -538,8 +539,9 @@ static void ath11k_dp_tx_complete_msdu(s
|
|
struct ath11k_skb_cb *skb_cb;
|
|
struct ath11k_peer *peer;
|
|
struct ath11k_sta *arsta;
|
|
- struct ieee80211_vif *vif;
|
|
+ struct ieee80211_vif *vif = NULL;
|
|
struct rate_info rate;
|
|
+ struct ath11k_vif *arvif = NULL;
|
|
u8 flags = 0;
|
|
|
|
if (unlikely(WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) {
|
|
@@ -580,6 +582,9 @@ static void ath11k_dp_tx_complete_msdu(s
|
|
}
|
|
|
|
vif = skb_cb->vif;
|
|
+ arvif = (void *)vif->drv_priv;
|
|
+ if(arvif && wbm_status < HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX)
|
|
+ arvif->wbm_tx_comp_stats[wbm_status]++;
|
|
|
|
info = IEEE80211_SKB_CB(msdu);
|
|
memset(&info->status, 0, sizeof(info->status));
|
|
@@ -644,6 +649,11 @@ static void ath11k_dp_tx_complete_msdu(s
|
|
rate = arsta->last_txrate;
|
|
status.rate = &rate;
|
|
|
|
+ if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar))) {
|
|
+ if(arsta->wbm_tx_stats && wbm_status < HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX)
|
|
+ arsta->wbm_tx_stats->wbm_tx_comp_stats[wbm_status]++;
|
|
+ }
|
|
+
|
|
spin_unlock_bh(&ab->base_lock);
|
|
rcu_read_unlock();
|
|
|
|
@@ -712,11 +722,12 @@ void ath11k_dp_tx_completion_handler(str
|
|
struct sk_buff *msdu;
|
|
struct hal_tx_status ts = { 0 };
|
|
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
|
|
+ struct hal_wbm_release_ring *tx_status;
|
|
+ enum hal_wbm_htt_tx_comp_status wbm_status;
|
|
int valid_entries, count = 0, i = 0;
|
|
u32 *desc;
|
|
u32 msdu_id, desc_id;
|
|
u8 mac_id;
|
|
- struct hal_wbm_release_ring *tx_status;
|
|
|
|
spin_lock_bh(&status_ring->lock);
|
|
|
|
@@ -759,6 +770,9 @@ void ath11k_dp_tx_completion_handler(str
|
|
mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id);
|
|
msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id);
|
|
|
|
+ wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
|
|
+ tx_status->info0);
|
|
+
|
|
if (unlikely(ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) {
|
|
ath11k_dp_tx_process_htt_tx_complete(ab,
|
|
(void *)tx_status,
|
|
@@ -783,7 +797,7 @@ void ath11k_dp_tx_completion_handler(str
|
|
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
|
wake_up(&ar->dp.tx_empty_waitq);
|
|
|
|
- ath11k_dp_tx_complete_msdu(ar, msdu, &ts);
|
|
+ ath11k_dp_tx_complete_msdu(ar, msdu, &ts, wbm_status);
|
|
}
|
|
}
|
|
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/hal_desc.h
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/hal_desc.h
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/hal_desc.h
|
|
@@ -1020,6 +1020,7 @@ enum hal_wbm_htt_tx_comp_status {
|
|
HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ,
|
|
HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT,
|
|
HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY,
|
|
+ HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX
|
|
};
|
|
|
|
struct hal_tcl_data_cmd {
|
|
Index: backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/mac.c
|
|
===================================================================
|
|
--- backports-20210222_001-5.4.89-b157d2276.orig/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ backports-20210222_001-5.4.89-b157d2276/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -4956,6 +4956,11 @@ static int ath11k_mac_station_add(struct
|
|
ret = -ENOMEM;
|
|
goto free_peer;
|
|
}
|
|
+ arsta->wbm_tx_stats = kzalloc(sizeof(*arsta->wbm_tx_stats), GFP_KERNEL);
|
|
+ if(!arsta->wbm_tx_stats) {
|
|
+ ret = -ENOMEM;
|
|
+ goto free_peer;
|
|
+ }
|
|
}
|
|
|
|
if (ieee80211_vif_is_mesh(vif)) {
|
|
@@ -4994,6 +4999,8 @@ static int ath11k_mac_station_add(struct
|
|
free_tx_stats:
|
|
kfree(arsta->tx_stats);
|
|
arsta->tx_stats = NULL;
|
|
+ kfree(arsta->wbm_tx_stats);
|
|
+ arsta->wbm_tx_stats = NULL;
|
|
free_peer:
|
|
ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
|
|
free_rx_stats:
|
|
@@ -5093,6 +5100,8 @@ static int ath11k_mac_op_sta_state(struc
|
|
|
|
kfree(arsta->tx_stats);
|
|
arsta->tx_stats = NULL;
|
|
+ kfree(arsta->wbm_tx_stats);
|
|
+ arsta->wbm_tx_stats = NULL;
|
|
ret = ath11k_mac_ap_ps_recalc(ar);
|
|
if (ret)
|
|
ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret);
|
|
@@ -6769,6 +6778,7 @@ static int ath11k_mac_op_add_interface(s
|
|
}
|
|
|
|
ath11k_debugfs_dbg_mac_filter(arvif);
|
|
+ ath11k_debugfs_wbm_tx_comp_stats(arvif);
|
|
|
|
switch (vif->type) {
|
|
case NL80211_IFTYPE_UNSPECIFIED:
|
|
@@ -7106,6 +7116,10 @@ err_vdev_del:
|
|
debugfs_remove(arvif->mac_filter);
|
|
arvif->mac_filter = NULL;
|
|
|
|
+ /* Remove the wbm tx compl stats file */
|
|
+ debugfs_remove(arvif->wbm_tx_completion_stats);
|
|
+ arvif->wbm_tx_completion_stats = NULL;
|
|
+
|
|
unlock:
|
|
mutex_unlock(&ar->conf_mutex);
|
|
}
|