mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2026-01-08 16:41:41 +00:00
297 lines
7.8 KiB
Diff
297 lines
7.8 KiB
Diff
From 94195c0022e50d9a3e28dc184bbaaa4505648611 Mon Sep 17 00:00:00 2001
|
|
From: Peter Chiu <chui-hao.chiu@mediatek.com>
|
|
Date: Wed, 11 Jan 2023 10:56:27 +0800
|
|
Subject: [PATCH 2006/2014] wifi: mt76: add debugfs knob to show packet error
|
|
rate
|
|
|
|
Get tx count and tx failed from mcu command
|
|
---
|
|
mt76.h | 2 +
|
|
mt76_connac_mcu.h | 1 +
|
|
mt7915/mcu.c | 108 +++++++++++++++++++++++++++++++++++++++++++
|
|
mt7915/mcu.h | 21 ++++++++-
|
|
mt7915/mt7915.h | 1 +
|
|
mt7915/mtk_debugfs.c | 62 +++++++++++++++++++++++++
|
|
6 files changed, 194 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/mt76.h b/mt76.h
|
|
index 2e7585a..29e0b19 100644
|
|
--- a/mt76.h
|
|
+++ b/mt76.h
|
|
@@ -321,8 +321,10 @@ struct mt76_sta_stats {
|
|
u64 last_tx_bytes;
|
|
/* WED TX */
|
|
u32 tx_packets; /* unit: MSDU */
|
|
+ u32 tx_mpdu_cnt;
|
|
u32 tx_retries;
|
|
u32 tx_failed;
|
|
+ u32 tx_failed_wm;
|
|
/* WED RX */
|
|
u64 rx_bytes;
|
|
u32 rx_packets;
|
|
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
|
|
index 03d6a2b..b0d3fe8 100644
|
|
--- a/mt76_connac_mcu.h
|
|
+++ b/mt76_connac_mcu.h
|
|
@@ -1207,6 +1207,7 @@ enum {
|
|
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
|
|
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
|
|
MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
|
|
+ MCU_EXT_CMD_GET_TX_STAT = 0x30,
|
|
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
|
|
MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
|
|
MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
|
|
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
|
|
index a153585..c75db44 100644
|
|
--- a/mt7915/mcu.c
|
|
+++ b/mt7915/mcu.c
|
|
@@ -4565,6 +4565,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
|
|
return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
|
|
}
|
|
|
|
+static int mt7915_mcu_get_tx_stat_v1(struct mt7915_phy *phy,
|
|
+ u16 wlan_idx)
|
|
+{
|
|
+#define to_wcid(hi, lo) (hi << 8 | lo)
|
|
+ struct mt7915_dev *dev = phy->dev;
|
|
+ struct mt76_phy *mphy = phy->mt76;
|
|
+ struct mt7915_mcu_tx_stat_v1 *res;
|
|
+ struct mt76_wcid *wcid;
|
|
+ struct sk_buff *skb;
|
|
+ struct {
|
|
+ __le32 category;
|
|
+ u8 wlan_idx_lo;
|
|
+ u8 band;
|
|
+ u8 wlan_idx_hi;
|
|
+ u8 __rsv[5];
|
|
+ } __packed req = {
|
|
+ .category = cpu_to_le32(MCU_GET_TX_STAT_CNT),
|
|
+ .band = mphy->band_idx,
|
|
+ .wlan_idx_lo = to_wcid_lo(wlan_idx),
|
|
+ .wlan_idx_hi = to_wcid_hi(wlan_idx),
|
|
+ };
|
|
+ int ret;
|
|
+
|
|
+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
|
|
+ &req, sizeof(req), true, &skb);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ res = (struct mt7915_mcu_tx_stat_v1 *)skb->data;
|
|
+
|
|
+ if (to_wcid(res->wlan_idx_hi, res->wlan_idx_lo) != wlan_idx) {
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rcu_read_lock();
|
|
+
|
|
+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
|
|
+ if (wcid) {
|
|
+ wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
|
|
+ wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
|
|
+ } else {
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
+ rcu_read_unlock();
|
|
+out:
|
|
+ dev_kfree_skb(skb);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int mt7915_mcu_get_tx_stat_v2(struct mt7915_phy *phy,
|
|
+ u16 wlan_idx)
|
|
+{
|
|
+ struct mt7915_dev *dev = phy->dev;
|
|
+ struct mt76_phy *mphy = phy->mt76;
|
|
+ struct mt7915_mcu_tx_stat_v2 *res;
|
|
+ struct mt76_wcid *wcid;
|
|
+ struct sk_buff *skb;
|
|
+ struct {
|
|
+ u8 category;
|
|
+ u8 band;
|
|
+ __le16 wcid;
|
|
+ } __packed req = {
|
|
+ .category = MCU_GET_TX_STAT_CNT,
|
|
+ .band = mphy->band_idx,
|
|
+ .wcid = cpu_to_le16(wlan_idx),
|
|
+ };
|
|
+ int ret;
|
|
+
|
|
+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
|
|
+ &req, sizeof(req), true, &skb);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ res = (struct mt7915_mcu_tx_stat_v2 *)skb->data;
|
|
+
|
|
+ if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
|
|
+ ret = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rcu_read_lock();
|
|
+
|
|
+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
|
|
+ if (wcid) {
|
|
+ wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
|
|
+ wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
|
|
+ } else {
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
+ rcu_read_unlock();
|
|
+out:
|
|
+ dev_kfree_skb(skb);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx)
|
|
+{
|
|
+ if (is_mt7915(&phy->dev->mt76))
|
|
+ return mt7915_mcu_get_tx_stat_v1(phy, wlan_idx);
|
|
+
|
|
+ return mt7915_mcu_get_tx_stat_v2(phy, wlan_idx);
|
|
+}
|
|
+
|
|
int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
|
struct cfg80211_he_bss_color *he_bss_color)
|
|
{
|
|
diff --git a/mt7915/mcu.h b/mt7915/mcu.h
|
|
index 52baaa7..ec7ad7d 100644
|
|
--- a/mt7915/mcu.h
|
|
+++ b/mt7915/mcu.h
|
|
@@ -854,7 +854,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
|
|
}
|
|
|
|
enum {
|
|
- MCU_GET_TX_RATE = 4
|
|
+ MCU_GET_TX_RATE = 4,
|
|
+ MCU_GET_TX_STAT_CNT = 8
|
|
};
|
|
|
|
#ifdef CONFIG_MTK_VENDOR
|
|
@@ -1130,6 +1131,24 @@ struct mt7915_muru {
|
|
/* DL&UL User config */
|
|
#define MURU_USER_CNT BIT(4)
|
|
|
|
+struct mt7915_mcu_tx_stat_v1 {
|
|
+ u8 wlan_idx_lo;
|
|
+ u8 band_idx;
|
|
+ u8 wlan_idx_hi;
|
|
+ u8 __rsv1[29];
|
|
+ __le32 tx_cnt;
|
|
+ __le32 tx_failed;
|
|
+ u8 __rsv2[26];
|
|
+};
|
|
+
|
|
+struct mt7915_mcu_tx_stat_v2 {
|
|
+ u8 __rsv1[4];
|
|
+ __le16 wlan_idx;
|
|
+ u8 __rsv2[2];
|
|
+ __le32 tx_cnt;
|
|
+ __le32 tx_failed;
|
|
+};
|
|
+
|
|
enum {
|
|
CAPI_SU,
|
|
CAPI_MU,
|
|
diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
|
|
index e41c7ad..38d39c8 100644
|
|
--- a/mt7915/mt7915.h
|
|
+++ b/mt7915/mt7915.h
|
|
@@ -753,6 +753,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
|
|
int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
|
|
struct cfg80211_chan_def *chandef);
|
|
int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
|
|
+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx);
|
|
int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
|
|
int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
|
|
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
|
|
diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
|
|
index ead8970..a80ddeb 100644
|
|
--- a/mt7915/mtk_debugfs.c
|
|
+++ b/mt7915/mtk_debugfs.c
|
|
@@ -4027,6 +4027,66 @@ mt7915_sr_scene_cond_show(struct seq_file *file, void *data)
|
|
|
|
DEFINE_SHOW_ATTRIBUTE(mt7915_sr_scene_cond);
|
|
|
|
+static int mt7915_reset_counter(void *data, u64 val)
|
|
+{
|
|
+ struct mt7915_phy *phy = data;
|
|
+ struct mt7915_dev *dev = phy->dev;
|
|
+ struct mt76_wcid *wcid;
|
|
+
|
|
+ /* Clear the firmware counters */
|
|
+ mt7915_mcu_wed_wa_tx_stats(dev, dev->wlan_idx);
|
|
+ mt7915_get_tx_stat(phy, dev->wlan_idx);
|
|
+
|
|
+ rcu_read_lock();
|
|
+ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
|
|
+ if (!wcid)
|
|
+ return -EINVAL;
|
|
+
|
|
+ memset(&wcid->stats, 0, sizeof(struct mt76_sta_stats));
|
|
+
|
|
+ rcu_read_unlock();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_counter, NULL,
|
|
+ mt7915_reset_counter, "%lld\n");
|
|
+
|
|
+static int
|
|
+mt7915_per_read(struct seq_file *s, void *data)
|
|
+{
|
|
+ struct mt7915_dev *dev = dev_get_drvdata(s->private);
|
|
+ struct mt76_sta_stats *stats;
|
|
+ struct mt76_wcid *wcid;
|
|
+ int ret;
|
|
+ u8 phy_idx;
|
|
+
|
|
+ if (!dev->mt76.wcid[dev->wlan_idx])
|
|
+ return -EINVAL;
|
|
+
|
|
+ phy_idx = dev->mt76.wcid[dev->wlan_idx]->phy_idx;
|
|
+
|
|
+ ret = mt7915_get_tx_stat(dev->mt76.phys[phy_idx]->priv, dev->wlan_idx);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ rcu_read_lock();
|
|
+ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
|
|
+ if (!wcid)
|
|
+ return -EINVAL;
|
|
+
|
|
+ stats = &wcid->stats;
|
|
+
|
|
+ seq_printf(s, "sta %d, tx_mpdu_cnt = %u, tx_failed = %u, PER = %u.%u%%\n", dev->wlan_idx,
|
|
+ stats->tx_mpdu_cnt, stats->tx_failed_wm,
|
|
+ stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt / 10 : 0,
|
|
+ stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt % 10 : 0);
|
|
+
|
|
+ rcu_read_unlock();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
|
|
{
|
|
struct mt7915_dev *dev = phy->dev;
|
|
@@ -4124,6 +4184,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
|
|
debugfs_create_file("thermal_recal", 0200, dir, dev, &fops_thermal_recal);
|
|
debugfs_create_file("sr_stats", 0400, dir, phy, &mt7915_sr_stats_fops);
|
|
debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7915_sr_scene_cond_fops);
|
|
+ debugfs_create_file("reset_counter", 0200, dir, phy, &fops_reset_counter);
|
|
+ debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
|
|
|
|
return 0;
|
|
}
|
|
--
|
|
2.18.0
|
|
|