mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 19:31:55 +00:00
408 lines
12 KiB
Diff
408 lines
12 KiB
Diff
From d6d86c0c48c8d114e94c5b5f749c97d629d727ef Mon Sep 17 00:00:00 2001
|
|
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
|
Date: Mon, 4 Jan 2021 23:49:21 +0530
|
|
Subject: [PATCH 1/2] ath11k/mac80211: Add support to account Tx and Rx flow
|
|
packets
|
|
|
|
Added support to log the inflow and outflow of the Tx and Rx
|
|
packets in netif and host driver.
|
|
|
|
Command to dump the Tx pkts flow in driver:
|
|
cat
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/driver_tx_pkts_flow
|
|
|
|
Command to dump the Rx pkts flow in driver:
|
|
cat
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/driver_rx_pkts_flow
|
|
|
|
Commands to reset the Tx/Rx pkts flow in driver:
|
|
echo 1 >
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/reset_tx_stats
|
|
|
|
echo 1 >
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/reset_rx_stats
|
|
|
|
Command to dump the Tx pkts flow in mac80211:
|
|
cat
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/mac80211_tx_pkts_flow
|
|
|
|
Command to dump the Rx pkts flow in mac80211:
|
|
cat
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/mac80211_rx_pkts_flow
|
|
|
|
Commands to reset the Tx/Rx pkts flow in mac80211:
|
|
echo 1 >
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_tx_pkts_flow
|
|
|
|
echo 1 >
|
|
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/
|
|
XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_rx_pkts_flow
|
|
|
|
Sample output after running the Tx and Rx traffic.
|
|
|
|
root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\:
|
|
wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_tx_pkts_flow
|
|
Tx packets inflow from mac80211: 20
|
|
Tx packets outflow to HW: 20
|
|
|
|
root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\:
|
|
wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_tx_pkts_flow
|
|
Tx packets outflow from netif: 20
|
|
Tx packets inflow in mac80211: 20
|
|
|
|
root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\:
|
|
wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_rx_pkts_flow
|
|
Rx packets inflow from HW: 28
|
|
Rx packets outflow from driver: 28
|
|
|
|
root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\:
|
|
wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_rx_pkts_flow
|
|
Rx packets inflow in mac80211: 28
|
|
Rx packets inflow in netif: 26
|
|
Rx forwarded packets in bridge: 2
|
|
|
|
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 12 ++
|
|
drivers/net/wireless/ath/ath11k/debugfs.h | 2 +
|
|
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 145 +++++++++++++++++-
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 38 +++++
|
|
drivers/net/wireless/ath/ath11k/mac.c | 11 ++
|
|
5 files changed, 207 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -398,6 +398,16 @@ struct ath11k_per_ppdu_tx_stats {
|
|
u32 retry_bytes;
|
|
};
|
|
|
|
+struct ath11k_driver_tx_pkts_flow {
|
|
+ atomic_t pkts_in;
|
|
+ atomic_t pkts_out;
|
|
+};
|
|
+
|
|
+struct ath11k_driver_rx_pkts_flow {
|
|
+ atomic_t pkts_frm_hw;
|
|
+ atomic_t pkts_out;
|
|
+};
|
|
+
|
|
struct ath11k_sta {
|
|
struct ath11k_vif *arvif;
|
|
|
|
@@ -427,6 +437,8 @@ struct ath11k_sta {
|
|
#ifdef CPTCFG_ATH11K_NSS_SUPPORT
|
|
struct ath11k_nss_sta_stats *nss_stats;
|
|
#endif
|
|
+ struct ath11k_driver_tx_pkts_flow drv_tx_pkts;
|
|
+ struct ath11k_driver_rx_pkts_flow drv_rx_pkts;
|
|
u16 tcl_metadata;
|
|
/* Protected with ar->data_lock */
|
|
u32 peer_ps_state;
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
|
|
@@ -72,6 +72,8 @@ enum ath11k_dbg_htt_ext_stats_type {
|
|
#define TPC_STATS_TOT_COLUMN 100
|
|
#define ATH11K_TPC_STATS_BUF_SIZE (TPC_STATS_TOT_ROW * TPC_STATS_TOT_COLUMN)
|
|
|
|
+#define ATH11K_DRV_TX_STATS_SIZE 1024
|
|
+
|
|
enum ath11k_debug_tpc_stats_type {
|
|
ATH11K_DBG_TPC_STATS_SU,
|
|
ATH11K_DBG_TPC_STATS_SU_WITH_TXBF,
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
@@ -1087,6 +1087,8 @@ static ssize_t ath11k_dbg_sta_reset_rx_s
|
|
|
|
spin_lock_bh(&ar->ab->base_lock);
|
|
memset(arsta->rx_stats, 0, sizeof(*arsta->rx_stats));
|
|
+ atomic_set(&arsta->drv_rx_pkts.pkts_frm_hw, 0);
|
|
+ atomic_set(&arsta->drv_rx_pkts.pkts_out, 0);
|
|
spin_unlock_bh(&ar->ab->base_lock);
|
|
|
|
ret = count;
|
|
@@ -1196,6 +1198,139 @@ static const struct file_operations fops
|
|
.llseek = default_llseek,
|
|
};
|
|
|
|
+static ssize_t
|
|
+ath11k_dbg_sta_dump_driver_tx_pkts_flow(struct file *file,
|
|
+ const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ieee80211_sta *sta = file->private_data;
|
|
+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+ struct ath11k *ar = arsta->arvif->ar;
|
|
+ int len = 0, ret_val;
|
|
+ const int size = ATH11K_DRV_TX_STATS_SIZE;
|
|
+ char *buf;
|
|
+
|
|
+ if (!arsta->tx_stats)
|
|
+ return -ENOENT;
|
|
+
|
|
+ buf = kzalloc(ATH11K_DRV_TX_STATS_SIZE, GFP_KERNEL);
|
|
+ if (!buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+ len += scnprintf(buf + len, size - len,
|
|
+ "Tx packets inflow from mac80211: %u\n",
|
|
+ atomic_read(&arsta->drv_tx_pkts.pkts_in));
|
|
+ len += scnprintf(buf + len, size - len,
|
|
+ "Tx packets outflow to HW: %u\n",
|
|
+ atomic_read(&arsta->drv_tx_pkts.pkts_out));
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+
|
|
+ if (len > size)
|
|
+ len = size;
|
|
+
|
|
+ ret_val = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+ kfree(buf);
|
|
+
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+ return ret_val;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_driver_tx_pkts_flow = {
|
|
+ .read = ath11k_dbg_sta_dump_driver_tx_pkts_flow,
|
|
+ .open = simple_open,
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
+
|
|
+static ssize_t ath11k_dbg_sta_reset_tx_stats(struct file *file,
|
|
+ const char __user *buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ieee80211_sta *sta = file->private_data;
|
|
+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+ struct ath11k *ar = arsta->arvif->ar;
|
|
+ int ret, reset;
|
|
+
|
|
+ if (!arsta->tx_stats)
|
|
+ return -ENOENT;
|
|
+
|
|
+ ret = kstrtoint_from_user(buf, count, 0, &reset);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (!reset || reset > 1)
|
|
+ return -EINVAL;
|
|
+
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+ 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);
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+
|
|
+ ret = count;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_reset_tx_stats = {
|
|
+ .write = ath11k_dbg_sta_reset_tx_stats,
|
|
+ .open = simple_open,
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
+
|
|
+static ssize_t
|
|
+ath11k_dbg_sta_dump_driver_rx_pkts_flow(struct file *file,
|
|
+ char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ieee80211_sta *sta = file->private_data;
|
|
+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+ struct ath11k *ar = arsta->arvif->ar;
|
|
+ struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
|
|
+ int len = 0, ret_val = 0;
|
|
+ const int size = 1024;
|
|
+ char *buf;
|
|
+
|
|
+ if (!rx_stats)
|
|
+ return -ENOENT;
|
|
+
|
|
+ buf = kzalloc(size, GFP_KERNEL);
|
|
+ if (!buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+
|
|
+ len += scnprintf(buf + len, size - len,
|
|
+ "Rx packets inflow from HW: %u\n",
|
|
+ atomic_read(&arsta->drv_rx_pkts.pkts_frm_hw));
|
|
+ len += scnprintf(buf + len, size - len,
|
|
+ "Rx packets outflow from driver: %u\n",
|
|
+ atomic_read(&arsta->drv_rx_pkts.pkts_out));
|
|
+
|
|
+ len += scnprintf(buf + len, size - len, "\n");
|
|
+
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+
|
|
+ if (len > size)
|
|
+ len = size;
|
|
+
|
|
+ ret_val = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+ kfree(buf);
|
|
+
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+ return ret_val;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_driver_rx_pkts_flow = {
|
|
+ .read = ath11k_dbg_sta_dump_driver_rx_pkts_flow,
|
|
+ .open = simple_open,
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
+
|
|
void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
struct ieee80211_sta *sta, struct dentry *dir)
|
|
{
|
|
@@ -1211,14 +1346,21 @@ void ath11k_debugfs_sta_op_add(struct ie
|
|
debugfs_create_file("total_ps_duration", 0440, dir, sta,
|
|
&fops_total_ps_duration);
|
|
}
|
|
- if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))
|
|
+ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {
|
|
debugfs_create_file("tx_stats", 0400, dir, sta,
|
|
&fops_tx_stats);
|
|
+ debugfs_create_file("reset_tx_stats", 0600, dir, sta,
|
|
+ &fops_reset_tx_stats);
|
|
+ debugfs_create_file("driver_tx_pkts_flow", 0400, dir, sta,
|
|
+ &fops_driver_tx_pkts_flow);
|
|
+ }
|
|
if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) {
|
|
debugfs_create_file("rx_stats", 0400, dir, sta,
|
|
&fops_rx_stats);
|
|
debugfs_create_file("reset_rx_stats", 0600, dir, sta,
|
|
&fops_reset_rx_stats);
|
|
+ debugfs_create_file("driver_rx_pkts_flow", 0400, dir, sta,
|
|
+ &fops_driver_rx_pkts_flow);
|
|
}
|
|
|
|
debugfs_create_file("htt_peer_stats", 0400, dir, sta,
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -2692,6 +2692,7 @@ static void ath11k_dp_rx_deliver_msdu(st
|
|
struct ieee80211_rx_status *rx_status;
|
|
struct ieee80211_radiotap_he *he = NULL;
|
|
struct ieee80211_sta *pubsta = NULL;
|
|
+ struct ath11k_sta *arsta = NULL;
|
|
struct ath11k_peer *peer;
|
|
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
|
u8 decap = DP_RX_DECAP_TYPE_RAW;
|
|
@@ -2754,6 +2755,18 @@ static void ath11k_dp_rx_deliver_msdu(st
|
|
rx_status->flag |= RX_FLAG_8023;
|
|
|
|
ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
|
+
|
|
+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) {
|
|
+ if (!(status->flag & RX_FLAG_ONLY_MONITOR)) {
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+ if (peer && peer->sta)
|
|
+ arsta =
|
|
+ (struct ath11k_sta *)peer->sta->drv_priv;
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+ if (arsta)
|
|
+ atomic_inc(&arsta->drv_rx_pkts.pkts_out);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
|
@@ -2903,6 +2916,8 @@ int ath11k_dp_process_rx(struct ath11k_b
|
|
int total_msdu_reaped = 0;
|
|
struct hal_srng *srng;
|
|
struct sk_buff *msdu;
|
|
+ struct ath11k_peer *peer = NULL;
|
|
+ struct ath11k_sta *arsta = NULL;
|
|
int quota = budget;
|
|
bool done = false;
|
|
int buf_id, mac_id;
|
|
@@ -2974,6 +2989,19 @@ try_again:
|
|
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
|
desc.info0);
|
|
|
|
+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar) && rxcb->peer_id) {
|
|
+ rcu_read_lock();
|
|
+ spin_lock_bh(&ab->base_lock);
|
|
+ peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
|
|
+ if (peer && peer->sta)
|
|
+ arsta =
|
|
+ (struct ath11k_sta *)peer->sta->drv_priv;
|
|
+ spin_unlock_bh(&ab->base_lock);
|
|
+ if (arsta)
|
|
+ atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw);
|
|
+ rcu_read_unlock();
|
|
+ }
|
|
+
|
|
rxcb->mac_id = mac_id;
|
|
__skb_queue_tail(&msdu_list, msdu);
|
|
|
|
@@ -4458,7 +4486,10 @@ static int ath11k_dp_rx_h_null_q_desc(st
|
|
struct rx_attention *rx_attention;
|
|
u8 l3pad_bytes;
|
|
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
|
+ struct ath11k_peer *peer = NULL;
|
|
+ struct ath11k_sta *arsta = NULL;
|
|
u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;
|
|
+ u32 peer_id;
|
|
|
|
msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc);
|
|
|
|
@@ -4510,6 +4541,18 @@ static int ath11k_dp_rx_h_null_q_desc(st
|
|
* rx with mac80211. Need not worry about cleaning up amsdu_list.
|
|
*/
|
|
|
|
+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) {
|
|
+ peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, desc);
|
|
+ spin_lock_bh(&ar->ab->base_lock);
|
|
+ if (peer_id)
|
|
+ peer = ath11k_peer_find_by_id(ar->ab, rxcb->peer_id);
|
|
+ if (peer && peer->sta)
|
|
+ arsta = (struct ath11k_sta *)peer->sta->drv_priv;
|
|
+ spin_unlock_bh(&ar->ab->base_lock);
|
|
+ if (arsta)
|
|
+ atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw);
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -5590,6 +5590,8 @@ static void ath11k_mac_op_tx(struct ieee
|
|
struct ieee80211_key_conf *key = info->control.hw_key;
|
|
struct ath11k_mgmt_frame_stats *mgmt_stats = &arvif->mgmt_stats;
|
|
u32 info_flags = info->flags;
|
|
+ struct ieee80211_sta *sta = control->sta;
|
|
+ struct ath11k_sta *arsta = NULL;
|
|
bool is_prb_rsp;
|
|
u16 frm_type = 0;
|
|
int ret;
|
|
@@ -5653,6 +5655,15 @@ static void ath11k_mac_op_tx(struct ieee
|
|
ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
|
|
ieee80211_free_txskb(ar->hw, skb);
|
|
}
|
|
+
|
|
+ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar) && sta) {
|
|
+ arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+ if (arsta) {
|
|
+ atomic_inc(&arsta->drv_tx_pkts.pkts_in);
|
|
+ if (!ret)
|
|
+ atomic_inc(&arsta->drv_tx_pkts.pkts_out);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
void ath11k_mac_drain_tx(struct ath11k *ar)
|