blob: cdba8999e75c60e816acbc861d35a491738566d9 [file] [log] [blame]
developer67bb1212024-02-04 16:58:38 +08001From f8bfd93b55c37abf0d210bbeab633a6a9877a7a6 Mon Sep 17 00:00:00 2001
developerc2cfe0f2023-09-22 04:11:09 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Mon, 10 Jul 2023 11:47:29 +0800
developer07b5baf2024-01-10 04:38:47 +08004Subject: [PATCH 1020/1044] mtk: wifi: mt76: mt7996: add support spatial reuse
developer5f4e6c32023-12-20 06:12:53 +08005 debug commands
developerc2cfe0f2023-09-22 04:11:09 +08006
7This commit adds the following debug commands in debugfs:
81. sr_enable: enable/disable spatial reuse feature. Default is on.
92. sr_enhanced_enable: enable/disable enhanced spatial reuse feature.
10Default is on. This feature is mtk proprietary feature.
113. sr_stats: Check the Spatial reuse tx statistics.
124. sr_scene_cond: Check the result of mtk scene detection algorithm. Mtk
13scene detection algorithm in firmware may decide whether current
14environment can SR Tx or not.
15
16To learn more details of these commands, please check:
17https://wiki.mediatek.inc/display/APKB/mt76+Phy+feature+debug+Cheetsheet#mt76PhyfeaturedebugCheetsheet-SpatialReuse
developer5f4e6c32023-12-20 06:12:53 +080018
developerc2cfe0f2023-09-22 04:11:09 +080019---
20 mt76_connac_mcu.h | 1 +
21 mt7996/main.c | 6 +++
developer5f4e6c32023-12-20 06:12:53 +080022 mt7996/mcu.c | 8 ++++
developerc2cfe0f2023-09-22 04:11:09 +080023 mt7996/mt7996.h | 6 +++
24 mt7996/mtk_debugfs.c | 82 ++++++++++++++++++++++++++++++++
25 mt7996/mtk_mcu.c | 111 +++++++++++++++++++++++++++++++++++++++++++
26 mt7996/mtk_mcu.h | 56 ++++++++++++++++++++++
developer5f4e6c32023-12-20 06:12:53 +080027 7 files changed, 270 insertions(+)
developerc2cfe0f2023-09-22 04:11:09 +080028
29diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer67bb1212024-02-04 16:58:38 +080030index 062268d6..9edb580c 100644
developerc2cfe0f2023-09-22 04:11:09 +080031--- a/mt76_connac_mcu.h
32+++ b/mt76_connac_mcu.h
developer67bb1212024-02-04 16:58:38 +080033@@ -1040,6 +1040,7 @@ enum {
developerc2cfe0f2023-09-22 04:11:09 +080034 MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
35 MCU_UNI_EVENT_SCAN_DONE = 0x0e,
36 MCU_UNI_EVENT_RDD_REPORT = 0x11,
37+ MCU_UNI_EVENT_SR = 0x25,
38 MCU_UNI_EVENT_ROC = 0x27,
39 MCU_UNI_EVENT_TX_DONE = 0x2d,
40 MCU_UNI_EVENT_BF = 0x33,
41diff --git a/mt7996/main.c b/mt7996/main.c
developer67bb1212024-02-04 16:58:38 +080042index 478ca7ce..9ca37e1e 100644
developerc2cfe0f2023-09-22 04:11:09 +080043--- a/mt7996/main.c
44+++ b/mt7996/main.c
45@@ -6,6 +6,9 @@
46 #include "mt7996.h"
47 #include "mcu.h"
48 #include "mac.h"
49+#ifdef CONFIG_MTK_DEBUG
50+#include "mtk_mcu.h"
51+#endif
52
53 static bool mt7996_dev_running(struct mt7996_dev *dev)
54 {
55@@ -78,6 +81,9 @@ int mt7996_run(struct ieee80211_hw *hw)
56 goto out;
57
58 #ifdef CONFIG_MTK_DEBUG
59+ phy->sr_enable = true;
60+ phy->enhanced_sr_enable = true;
61+
62 ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
63 !dev->dbg.sku_disable);
64 #else
65diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer67bb1212024-02-04 16:58:38 +080066index 60b1b62c..03bab7c3 100644
developerc2cfe0f2023-09-22 04:11:09 +080067--- a/mt7996/mcu.c
68+++ b/mt7996/mcu.c
developer5f4e6c32023-12-20 06:12:53 +080069@@ -712,6 +712,14 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
70 case MCU_UNI_EVENT_WED_RRO:
71 mt7996_mcu_wed_rro_event(dev, skb);
developerc2cfe0f2023-09-22 04:11:09 +080072 break;
73+#ifdef CONFIG_MTK_DEBUG
74+ case MCU_UNI_EVENT_SR:
75+ mt7996_mcu_rx_sr_event(dev, skb);
76+ break;
77+#endif
developer5f4e6c32023-12-20 06:12:53 +080078+ case MCU_UNI_EVENT_THERMAL:
79+ mt7996_mcu_rx_thermal_notify(dev, skb);
80+ break;
81 #ifdef CONFIG_NL80211_TESTMODE
82 case MCU_UNI_EVENT_TESTMODE_CTRL:
83 mt7996_tm_rf_test_event(dev, skb);
developerc2cfe0f2023-09-22 04:11:09 +080084diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer07b5baf2024-01-10 04:38:47 +080085index cfa50bfe..adb0cdd1 100644
developerc2cfe0f2023-09-22 04:11:09 +080086--- a/mt7996/mt7996.h
87+++ b/mt7996/mt7996.h
developer07b5baf2024-01-10 04:38:47 +080088@@ -352,6 +352,10 @@ struct mt7996_phy {
developerc2cfe0f2023-09-22 04:11:09 +080089 spinlock_t amnt_lock;
90 struct mt7996_air_monitor_ctrl amnt_ctrl;
91 #endif
92+#ifdef CONFIG_MTK_DEBUG
93+ bool sr_enable:1;
94+ bool enhanced_sr_enable:1;
95+#endif
96 };
97
98 struct mt7996_dev {
developer07b5baf2024-01-10 04:38:47 +080099@@ -800,6 +804,8 @@ enum edcca_bw_id {
developerc2cfe0f2023-09-22 04:11:09 +0800100 #ifdef CONFIG_MTK_DEBUG
101 int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
developer5f4e6c32023-12-20 06:12:53 +0800102 int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
developerc2cfe0f2023-09-22 04:11:09 +0800103+int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
104+void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
105 #endif
106
developer7e2761e2023-10-12 08:11:13 +0800107 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
developerc2cfe0f2023-09-22 04:11:09 +0800108diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
developer07b5baf2024-01-10 04:38:47 +0800109index 669eba9e..d1ca9ce7 100644
developerc2cfe0f2023-09-22 04:11:09 +0800110--- a/mt7996/mtk_debugfs.c
111+++ b/mt7996/mtk_debugfs.c
developer07b5baf2024-01-10 04:38:47 +0800112@@ -2777,6 +2777,83 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
developerc2cfe0f2023-09-22 04:11:09 +0800113 return 0;
114 }
115
116+static int
117+mt7996_sr_enable_get(void *data, u64 *val)
118+{
119+ struct mt7996_phy *phy = data;
120+
121+ *val = phy->sr_enable;
122+
123+ return 0;
124+}
125+
126+static int
127+mt7996_sr_enable_set(void *data, u64 val)
128+{
129+ struct mt7996_phy *phy = data;
130+ int ret;
131+
132+ if (!!val == phy->sr_enable)
133+ return 0;
134+
135+ ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, val, true);
136+ if (ret)
137+ return ret;
138+
139+ return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_CFG_SR_ENABLE, 0, false);
140+}
141+DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enable, mt7996_sr_enable_get,
142+ mt7996_sr_enable_set, "%lld\n");
143+static int
144+mt7996_sr_enhanced_enable_get(void *data, u64 *val)
145+{
146+ struct mt7996_phy *phy = data;
147+
148+ *val = phy->enhanced_sr_enable;
149+
150+ return 0;
151+}
152+
153+static int
154+mt7996_sr_enhanced_enable_set(void *data, u64 val)
155+{
156+ struct mt7996_phy *phy = data;
157+ int ret;
158+
159+ if (!!val == phy->enhanced_sr_enable)
160+ return 0;
161+
162+ ret = mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, val, true);
163+ if (ret)
164+ return ret;
165+
166+ return mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_ENHANCE_SR_ENABLE, 0, false);
167+}
168+DEFINE_DEBUGFS_ATTRIBUTE(fops_sr_enhanced_enable, mt7996_sr_enhanced_enable_get,
169+ mt7996_sr_enhanced_enable_set, "%lld\n");
170+
171+static int
172+mt7996_sr_stats_show(struct seq_file *file, void *data)
173+{
174+ struct mt7996_phy *phy = file->private;
175+
176+ mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_HW_IND, 0, false);
177+
178+ return 0;
179+}
180+DEFINE_SHOW_ATTRIBUTE(mt7996_sr_stats);
181+
182+static int
183+mt7996_sr_scene_cond_show(struct seq_file *file, void *data)
184+{
185+ struct mt7996_phy *phy = file->private;
186+
187+ mt7996_mcu_set_sr_enable(phy, UNI_CMD_SR_SW_SD, 0, false);
188+
189+ return 0;
190+}
191+DEFINE_SHOW_ATTRIBUTE(mt7996_sr_scene_cond);
192+
193 int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
194 {
195 struct mt7996_dev *dev = phy->dev;
developer07b5baf2024-01-10 04:38:47 +0800196@@ -2856,6 +2933,11 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
developerc2cfe0f2023-09-22 04:11:09 +0800197 debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
developer5f4e6c32023-12-20 06:12:53 +0800198 debugfs_create_file("scs_enable", 0200, dir, phy, &fops_scs_enable);
developerc2cfe0f2023-09-22 04:11:09 +0800199
200+ debugfs_create_file("sr_enable", 0600, dir, phy, &fops_sr_enable);
201+ debugfs_create_file("sr_enhanced_enable", 0600, dir, phy, &fops_sr_enhanced_enable);
202+ debugfs_create_file("sr_stats", 0400, dir, phy, &mt7996_sr_stats_fops);
203+ debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7996_sr_scene_cond_fops);
204+
205 return 0;
206 }
207
208diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
developer5f4e6c32023-12-20 06:12:53 +0800209index 5c54d02c..dbdf8d80 100644
developerc2cfe0f2023-09-22 04:11:09 +0800210--- a/mt7996/mtk_mcu.c
211+++ b/mt7996/mtk_mcu.c
developer5f4e6c32023-12-20 06:12:53 +0800212@@ -146,4 +146,115 @@ int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
developerc2cfe0f2023-09-22 04:11:09 +0800213 return 0;
214 }
215
216+int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set)
217+{
218+ struct {
219+ u8 band_idx;
220+ u8 _rsv[3];
221+
222+ __le16 tag;
223+ __le16 len;
224+
225+ __le32 val;
226+
227+ } __packed req = {
228+ .band_idx = phy->mt76->band_idx,
229+
230+ .tag = cpu_to_le16(action),
231+ .len = cpu_to_le16(sizeof(req) - 4),
232+
233+ .val = cpu_to_le32((u32) val),
234+ };
235+
236+ if (set)
237+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SR), &req,
238+ sizeof(req), false);
239+ else
240+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD_QUERY(SR), &req,
241+ sizeof(req), false);
242+}
243+
244+void mt7996_mcu_rx_sr_swsd(struct mt7996_dev *dev, struct sk_buff *skb)
245+{
246+#define SR_SCENE_DETECTION_TIMER_PERIOD_MS 500
247+ struct mt7996_mcu_sr_swsd_event *event;
248+ static const char * const rules[] = {"1 - NO CONNECTED", "2 - NO CONGESTION",
249+ "3 - NO INTERFERENCE", "4 - SR ON"};
250+ u8 idx;
251+
252+ event = (struct mt7996_mcu_sr_swsd_event *)skb->data;
253+ idx = event->basic.band_idx;
254+
255+ dev_info(dev->mt76.dev, "Band index = %u\n", le16_to_cpu(event->basic.band_idx));
256+ dev_info(dev->mt76.dev, "Hit Rule = %s\n", rules[event->tlv[idx].rule]);
257+ dev_info(dev->mt76.dev, "Timer Period = %d(us)\n"
258+ "Congestion Ratio = %d.%1d%%\n",
259+ SR_SCENE_DETECTION_TIMER_PERIOD_MS * 1000,
260+ le32_to_cpu(event->tlv[idx].total_airtime_ratio) / 10,
261+ le32_to_cpu(event->tlv[idx].total_airtime_ratio) % 10);
262+ dev_info(dev->mt76.dev,
263+ "Total Airtime = %d(us)\n"
264+ "ChBusy = %d\n"
265+ "SrTx = %d\n"
266+ "OBSS = %d\n"
267+ "MyTx = %d\n"
268+ "MyRx = %d\n"
269+ "Interference Ratio = %d.%1d%%\n",
270+ le32_to_cpu(event->tlv[idx].total_airtime),
271+ le32_to_cpu(event->tlv[idx].channel_busy_time),
272+ le32_to_cpu(event->tlv[idx].sr_tx_airtime),
273+ le32_to_cpu(event->tlv[idx].obss_airtime),
274+ le32_to_cpu(event->tlv[idx].my_tx_airtime),
275+ le32_to_cpu(event->tlv[idx].my_rx_airtime),
276+ le32_to_cpu(event->tlv[idx].obss_airtime_ratio) / 10,
277+ le32_to_cpu(event->tlv[idx].obss_airtime_ratio) % 10);
278+}
279+
280+void mt7996_mcu_rx_sr_hw_indicator(struct mt7996_dev *dev, struct sk_buff *skb)
281+{
282+ struct mt7996_mcu_sr_hw_ind_event *event;
283+
284+ event = (struct mt7996_mcu_sr_hw_ind_event *)skb->data;
285+
286+ dev_info(dev->mt76.dev, "Inter PPDU Count = %u\n",
287+ le16_to_cpu(event->inter_bss_ppdu_cnt));
288+ dev_info(dev->mt76.dev, "SR Valid Count = %u\n",
289+ le16_to_cpu(event->non_srg_valid_cnt));
290+ dev_info(dev->mt76.dev, "SR Tx Count = %u\n",
291+ le32_to_cpu(event->sr_ampdu_mpdu_cnt));
292+ dev_info(dev->mt76.dev, "SR Tx Acked Count = %u\n",
293+ le32_to_cpu(event->sr_ampdu_mpdu_acked_cnt));
294+}
295+
296+void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
297+{
298+ struct mt76_phy *mphy = &dev->mt76.phy;
299+ struct mt7996_phy *phy;
300+ struct mt7996_mcu_sr_common_event *event;
301+
302+ event = (struct mt7996_mcu_sr_common_event *)skb->data;
303+ mphy = dev->mt76.phys[event->basic.band_idx];
304+ if (!mphy)
305+ return;
306+
307+ phy = (struct mt7996_phy *)mphy->priv;
308+
309+ switch (le16_to_cpu(event->basic.tag)) {
310+ case UNI_EVENT_SR_CFG_SR_ENABLE:
311+ phy->sr_enable = le32_to_cpu(event->value) ? true : false;
312+ break;
313+ case UNI_EVENT_SR_HW_ESR_ENABLE:
314+ phy->enhanced_sr_enable = le32_to_cpu(event->value) ? true : false;
315+ break;
316+ case UNI_EVENT_SR_SW_SD:
317+ mt7996_mcu_rx_sr_swsd(dev, skb);
318+ break;
319+ case UNI_EVENT_SR_HW_IND:
320+ mt7996_mcu_rx_sr_hw_indicator(dev, skb);
321+ break;
322+ default:
323+ dev_info(dev->mt76.dev, "Unknown SR event tag %d\n",
324+ le16_to_cpu(event->basic.tag));
325+ }
326+}
327 #endif
328diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
developer07b5baf2024-01-10 04:38:47 +0800329index 36a58ad6..098e63ae 100644
developerc2cfe0f2023-09-22 04:11:09 +0800330--- a/mt7996/mtk_mcu.h
331+++ b/mt7996/mtk_mcu.h
developer07b5baf2024-01-10 04:38:47 +0800332@@ -121,6 +121,62 @@ enum {
developerc2cfe0f2023-09-22 04:11:09 +0800333 EDCCA_JAPAN = 3
334 };
335
336+enum {
337+ UNI_EVENT_SR_CFG_SR_ENABLE = 0x1,
338+ UNI_EVENT_SR_SW_SD = 0x83,
339+ UNI_EVENT_SR_HW_IND = 0xC9,
340+ UNI_EVENT_SR_HW_ESR_ENABLE = 0xD8,
341+};
342+enum {
343+ UNI_CMD_SR_CFG_SR_ENABLE = 0x1,
344+ UNI_CMD_SR_SW_SD = 0x84,
345+ UNI_CMD_SR_HW_IND = 0xCB,
346+ UNI_CMD_SR_HW_ENHANCE_SR_ENABLE = 0xDA,
347+};
348+
349+struct mt7996_mcu_sr_basic_event {
350+ struct mt7996_mcu_rxd rxd;
351+
352+ u8 band_idx;
353+ u8 _rsv[3];
354+
355+ __le16 tag;
356+ __le16 len;
357+};
358+
359+struct sr_sd_tlv {
360+ u8 _rsv[16];
361+ __le32 sr_tx_airtime;
362+ __le32 obss_airtime;
363+ __le32 my_tx_airtime;
364+ __le32 my_rx_airtime;
365+ __le32 channel_busy_time;
366+ __le32 total_airtime;
367+ __le32 total_airtime_ratio;
368+ __le32 obss_airtime_ratio;
369+ u8 rule;
370+ u8 _rsv2[59];
371+} __packed;
372+
373+struct mt7996_mcu_sr_swsd_event {
374+ struct mt7996_mcu_sr_basic_event basic;
375+ struct sr_sd_tlv tlv[3];
376+} __packed;
377+
378+struct mt7996_mcu_sr_common_event {
379+ struct mt7996_mcu_sr_basic_event basic;
380+ __le32 value;
381+};
382+
383+struct mt7996_mcu_sr_hw_ind_event {
384+ struct mt7996_mcu_sr_basic_event basic;
385+ __le16 non_srg_valid_cnt;
386+ u8 _rsv[4];
387+ __le16 inter_bss_ppdu_cnt;
388+ u8 _rsv2[4];
389+ __le32 sr_ampdu_mpdu_cnt;
390+ __le32 sr_ampdu_mpdu_acked_cnt;
391+};
392 #endif
393
394 #endif
395--
developer7e2761e2023-10-12 08:11:13 +08003962.18.0
developerc2cfe0f2023-09-22 04:11:09 +0800397