blob: ac5bfb1b00cda9e259bee5122c79c385f5c4ee1c [file] [log] [blame]
developer0443cd32023-09-19 14:11:49 +08001From 999021989ad387b46c8ff4ffed43cc0017322c5e Mon Sep 17 00:00:00 2001
developer33554a22023-01-30 14:11:29 +08002From: Peter Chiu <chui-hao.chiu@mediatek.com>
3Date: Wed, 11 Jan 2023 10:56:27 +0800
developer0443cd32023-09-19 14:11:49 +08004Subject: [PATCH 2006/2011] wifi: mt76: add debugfs knob to show packet error
5 rate
developer33554a22023-01-30 14:11:29 +08006
developer2e350ba2023-06-26 15:03:29 +08007Get tx count and tx failed from mcu command
developer33554a22023-01-30 14:11:29 +08008---
developer2e350ba2023-06-26 15:03:29 +08009 mt76.h | 2 +
10 mt76_connac_mcu.h | 1 +
11 mt7915/mcu.c | 108 +++++++++++++++++++++++++++++++++++++++++++
12 mt7915/mcu.h | 21 ++++++++-
13 mt7915/mt7915.h | 1 +
14 mt7915/mtk_debugfs.c | 62 +++++++++++++++++++++++++
15 6 files changed, 194 insertions(+), 1 deletion(-)
developer33554a22023-01-30 14:11:29 +080016
17diff --git a/mt76.h b/mt76.h
developer0443cd32023-09-19 14:11:49 +080018index 968bf08..3032cdd 100644
developer33554a22023-01-30 14:11:29 +080019--- a/mt76.h
20+++ b/mt76.h
developer2e350ba2023-06-26 15:03:29 +080021@@ -297,8 +297,10 @@ struct mt76_sta_stats {
developer33554a22023-01-30 14:11:29 +080022 u64 tx_bytes;
23 /* WED TX */
24 u32 tx_packets; /* unit: MSDU */
25+ u32 tx_mpdu_cnt;
26 u32 tx_retries;
27 u32 tx_failed;
developer2e350ba2023-06-26 15:03:29 +080028+ u32 tx_failed_wm;
developer33554a22023-01-30 14:11:29 +080029 /* WED RX */
developer2e350ba2023-06-26 15:03:29 +080030 u64 rx_bytes;
31 u32 rx_packets;
developer33554a22023-01-30 14:11:29 +080032diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer0443cd32023-09-19 14:11:49 +080033index 9ad1883..2d6e610 100644
developer33554a22023-01-30 14:11:29 +080034--- a/mt76_connac_mcu.h
35+++ b/mt76_connac_mcu.h
developer0443cd32023-09-19 14:11:49 +080036@@ -1173,6 +1173,7 @@ enum {
developer33554a22023-01-30 14:11:29 +080037 MCU_EXT_CMD_EDCA_UPDATE = 0x27,
38 MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
39 MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
40+ MCU_EXT_CMD_GET_TX_STAT = 0x30,
41 MCU_EXT_CMD_WTBL_UPDATE = 0x32,
42 MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
43 MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
developer33554a22023-01-30 14:11:29 +080044diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer0443cd32023-09-19 14:11:49 +080045index b2b5c76..d4b0617 100644
developer33554a22023-01-30 14:11:29 +080046--- a/mt7915/mcu.c
47+++ b/mt7915/mcu.c
developer0443cd32023-09-19 14:11:49 +080048@@ -4233,6 +4233,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
developer2157bf82023-06-26 02:27:49 +080049 return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
developer33554a22023-01-30 14:11:29 +080050 }
51
52+static int mt7915_mcu_get_tx_stat_v1(struct mt7915_phy *phy,
53+ u16 wlan_idx)
54+{
55+#define to_wcid(hi, lo) (hi << 8 | lo)
56+ struct mt7915_dev *dev = phy->dev;
57+ struct mt76_phy *mphy = phy->mt76;
58+ struct mt7915_mcu_tx_stat_v1 *res;
59+ struct mt76_wcid *wcid;
60+ struct sk_buff *skb;
61+ struct {
62+ __le32 category;
63+ u8 wlan_idx_lo;
64+ u8 band;
65+ u8 wlan_idx_hi;
66+ u8 __rsv[5];
67+ } __packed req = {
68+ .category = cpu_to_le32(MCU_GET_TX_STAT_CNT),
69+ .band = mphy->band_idx,
70+ .wlan_idx_lo = to_wcid_lo(wlan_idx),
71+ .wlan_idx_hi = to_wcid_hi(wlan_idx),
72+ };
73+ int ret;
74+
75+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
76+ &req, sizeof(req), true, &skb);
77+ if (ret)
78+ return ret;
79+
80+ res = (struct mt7915_mcu_tx_stat_v1 *)skb->data;
81+
82+ if (to_wcid(res->wlan_idx_hi, res->wlan_idx_lo) != wlan_idx) {
83+ ret = -EINVAL;
84+ goto out;
85+ }
86+
87+ rcu_read_lock();
88+
89+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
90+ if (wcid) {
91+ wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
developer2e350ba2023-06-26 15:03:29 +080092+ wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
developer33554a22023-01-30 14:11:29 +080093+ } else {
94+ ret = -EINVAL;
95+ }
96+
97+ rcu_read_unlock();
98+out:
99+ dev_kfree_skb(skb);
100+
101+ return ret;
102+}
103+
104+static int mt7915_mcu_get_tx_stat_v2(struct mt7915_phy *phy,
105+ u16 wlan_idx)
106+{
107+ struct mt7915_dev *dev = phy->dev;
108+ struct mt76_phy *mphy = phy->mt76;
109+ struct mt7915_mcu_tx_stat_v2 *res;
110+ struct mt76_wcid *wcid;
111+ struct sk_buff *skb;
112+ struct {
113+ u8 category;
114+ u8 band;
115+ __le16 wcid;
116+ } __packed req = {
117+ .category = MCU_GET_TX_STAT_CNT,
118+ .band = mphy->band_idx,
119+ .wcid = cpu_to_le16(wlan_idx),
120+ };
121+ int ret;
122+
123+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
124+ &req, sizeof(req), true, &skb);
125+ if (ret)
126+ return ret;
127+
128+ res = (struct mt7915_mcu_tx_stat_v2 *)skb->data;
129+
130+ if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
131+ ret = -EINVAL;
132+ goto out;
133+ }
134+
135+ rcu_read_lock();
136+
137+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
138+ if (wcid) {
139+ wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
developer2e350ba2023-06-26 15:03:29 +0800140+ wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
developer33554a22023-01-30 14:11:29 +0800141+ } else {
142+ ret = -EINVAL;
143+ }
144+
145+ rcu_read_unlock();
146+out:
147+ dev_kfree_skb(skb);
148+
149+ return ret;
150+}
151+
152+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx)
153+{
154+ if (is_mt7915(&phy->dev->mt76))
155+ return mt7915_mcu_get_tx_stat_v1(phy, wlan_idx);
156+
157+ return mt7915_mcu_get_tx_stat_v2(phy, wlan_idx);
158+}
159+
160 int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
161 struct cfg80211_he_bss_color *he_bss_color)
162 {
163diff --git a/mt7915/mcu.h b/mt7915/mcu.h
developerd38f89c2023-09-06 09:56:19 +0800164index 825bb7d..12c98c5 100644
developer33554a22023-01-30 14:11:29 +0800165--- a/mt7915/mcu.h
166+++ b/mt7915/mcu.h
developer8f0d89b2023-07-28 07:16:44 +0800167@@ -791,7 +791,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
developer5bea7322023-04-13 18:50:55 +0800168 }
169
170 enum {
171- MCU_GET_TX_RATE = 4
172+ MCU_GET_TX_RATE = 4,
173+ MCU_GET_TX_STAT_CNT = 8
174 };
175
176 #ifdef CONFIG_MTK_VENDOR
developer8f0d89b2023-07-28 07:16:44 +0800177@@ -1070,6 +1071,24 @@ struct mt7915_muru {
developer33554a22023-01-30 14:11:29 +0800178 /* DL&UL User config */
179 #define MURU_USER_CNT BIT(4)
180
181+struct mt7915_mcu_tx_stat_v1 {
182+ u8 wlan_idx_lo;
183+ u8 band_idx;
184+ u8 wlan_idx_hi;
185+ u8 __rsv1[29];
186+ __le32 tx_cnt;
187+ __le32 tx_failed;
188+ u8 __rsv2[26];
189+};
190+
191+struct mt7915_mcu_tx_stat_v2 {
192+ u8 __rsv1[4];
193+ __le16 wlan_idx;
194+ u8 __rsv2[2];
195+ __le32 tx_cnt;
196+ __le32 tx_failed;
197+};
198+
developer33554a22023-01-30 14:11:29 +0800199 enum {
200 CAPI_SU,
201 CAPI_MU,
202diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer0443cd32023-09-19 14:11:49 +0800203index c1f3a0a..d47abcf 100644
developer33554a22023-01-30 14:11:29 +0800204--- a/mt7915/mt7915.h
205+++ b/mt7915/mt7915.h
developer0443cd32023-09-19 14:11:49 +0800206@@ -677,6 +677,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
developer33554a22023-01-30 14:11:29 +0800207 int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
208 struct cfg80211_chan_def *chandef);
developer2157bf82023-06-26 02:27:49 +0800209 int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
210+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx);
developer33554a22023-01-30 14:11:29 +0800211 int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
developer2157bf82023-06-26 02:27:49 +0800212 int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
213 int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
developer2e350ba2023-06-26 15:03:29 +0800214diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
developerd38f89c2023-09-06 09:56:19 +0800215index 928bb50..4defc17 100644
developer2e350ba2023-06-26 15:03:29 +0800216--- a/mt7915/mtk_debugfs.c
217+++ b/mt7915/mtk_debugfs.c
developerd38f89c2023-09-06 09:56:19 +0800218@@ -3795,6 +3795,66 @@ mt7915_sr_enable_set(void *data, u64 val)
219 DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, NULL,
220 mt7915_sr_enable_set, "%llx\n");
developer2e350ba2023-06-26 15:03:29 +0800221
222+static int mt7915_reset_counter(void *data, u64 val)
223+{
224+ struct mt7915_phy *phy = data;
225+ struct mt7915_dev *dev = phy->dev;
226+ struct mt76_wcid *wcid;
227+
228+ /* Clear the firmware counters */
229+ mt7915_mcu_wed_wa_tx_stats(dev, dev->wlan_idx);
230+ mt7915_get_tx_stat(phy, dev->wlan_idx);
231+
232+ rcu_read_lock();
233+ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
234+ if (!wcid)
235+ return -EINVAL;
236+
237+ memset(&wcid->stats, 0, sizeof(struct mt76_sta_stats));
238+
239+ rcu_read_unlock();
240+
241+ return 0;
242+}
243+
244+DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_counter, NULL,
245+ mt7915_reset_counter, "%lld\n");
246+
247+static int
248+mt7915_per_read(struct seq_file *s, void *data)
249+{
250+ struct mt7915_dev *dev = dev_get_drvdata(s->private);
251+ struct mt76_sta_stats *stats;
252+ struct mt76_wcid *wcid;
253+ int ret;
254+ u8 phy_idx;
255+
256+ if (!dev->mt76.wcid[dev->wlan_idx])
257+ return -EINVAL;
258+
259+ phy_idx = dev->mt76.wcid[dev->wlan_idx]->phy_idx;
260+
261+ ret = mt7915_get_tx_stat(dev->mt76.phys[phy_idx]->priv, dev->wlan_idx);
262+ if (ret)
263+ return ret;
264+
265+ rcu_read_lock();
266+ wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
267+ if (!wcid)
268+ return -EINVAL;
269+
270+ stats = &wcid->stats;
271+
272+ seq_printf(s, "sta %d, tx_mpdu_cnt = %u, tx_failed = %u, PER = %u.%u%%\n", dev->wlan_idx,
273+ stats->tx_mpdu_cnt, stats->tx_failed_wm,
274+ stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt / 10 : 0,
275+ stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt % 10 : 0);
276+
277+ rcu_read_unlock();
278+
279+ return 0;
280+}
281+
282 int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
283 {
284 struct mt7915_dev *dev = phy->dev;
developerd38f89c2023-09-06 09:56:19 +0800285@@ -3886,6 +3946,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
developer2e350ba2023-06-26 15:03:29 +0800286 debugfs_create_file("sw_aci", 0600, dir, dev,
287 &fops_sw_aci);
developerd38f89c2023-09-06 09:56:19 +0800288 debugfs_create_file("sr_enable", 0200, dir, phy, &fops_sr_enable);
developer2e350ba2023-06-26 15:03:29 +0800289+ debugfs_create_file("reset_counter", 0200, dir, dev, &fops_reset_counter);
290+ debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
291 return 0;
292 }
293 #endif
developer33554a22023-01-30 14:11:29 +0800294--
developerd38f89c2023-09-06 09:56:19 +08002952.18.0
developer33554a22023-01-30 14:11:29 +0800296