blob: 78ae8ad862f3b06246987e10b349dc4e42494c1f [file] [log] [blame]
developer7e2761e2023-10-12 08:11:13 +08001From b02a81b168e9c42350c1f6a9b7e38c60c76cc692 Mon Sep 17 00:00:00 2001
developer064da3c2023-06-13 15:57:26 +08002From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Mon, 8 May 2023 09:03:50 +0800
developer7e2761e2023-10-12 08:11:13 +08004Subject: [PATCH 38/98] wifi: mt76: mt7996: enable SCS feature for mt7996
developer064da3c2023-06-13 15:57:26 +08005 driver
6
7Enable Smart Carrier Sense algorithn by default to improve performance
8in a noisy environment.
9
10Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
11---
12 mt76_connac_mcu.h | 1 +
13 mt7996/init.c | 1 +
14 mt7996/main.c | 7 +++
15 mt7996/mcu.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
16 mt7996/mcu.h | 6 +++
developer7e2761e2023-10-12 08:11:13 +080017 mt7996/mt7996.h | 15 ++++++
18 6 files changed, 153 insertions(+)
developer064da3c2023-06-13 15:57:26 +080019
20diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer7e2761e2023-10-12 08:11:13 +080021index 4d054bd..fae76c9 100644
developer064da3c2023-06-13 15:57:26 +080022--- a/mt76_connac_mcu.h
23+++ b/mt76_connac_mcu.h
developer7e2761e2023-10-12 08:11:13 +080024@@ -1232,6 +1232,7 @@ enum {
developerc2cfe0f2023-09-22 04:11:09 +080025 MCU_UNI_CMD_GET_STAT_INFO = 0x23,
developer064da3c2023-06-13 15:57:26 +080026 MCU_UNI_CMD_SNIFFER = 0x24,
27 MCU_UNI_CMD_SR = 0x25,
28+ MCU_UNI_CMD_SCS = 0x26,
29 MCU_UNI_CMD_ROC = 0x27,
developerc2cfe0f2023-09-22 04:11:09 +080030 MCU_UNI_CMD_SET_DBDC_PARMS = 0x28,
developer064da3c2023-06-13 15:57:26 +080031 MCU_UNI_CMD_TXPOWER = 0x2b,
developer064da3c2023-06-13 15:57:26 +080032diff --git a/mt7996/init.c b/mt7996/init.c
developer7e2761e2023-10-12 08:11:13 +080033index fed74d0..f393e04 100644
developer064da3c2023-06-13 15:57:26 +080034--- a/mt7996/init.c
35+++ b/mt7996/init.c
developer7e2761e2023-10-12 08:11:13 +080036@@ -1211,6 +1211,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
developer064da3c2023-06-13 15:57:26 +080037 dev->mt76.phy.priv = &dev->phy;
38 INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
39 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
40+ INIT_DELAYED_WORK(&dev->scs_work, mt7996_mcu_scs_sta_poll);
41 INIT_LIST_HEAD(&dev->sta_rc_list);
developer064da3c2023-06-13 15:57:26 +080042 INIT_LIST_HEAD(&dev->twt_list);
developerc2cfe0f2023-09-22 04:11:09 +080043
developer064da3c2023-06-13 15:57:26 +080044diff --git a/mt7996/main.c b/mt7996/main.c
developer7e2761e2023-10-12 08:11:13 +080045index 226235c..6fa4a65 100644
developer064da3c2023-06-13 15:57:26 +080046--- a/mt7996/main.c
47+++ b/mt7996/main.c
48@@ -73,11 +73,17 @@ int mt7996_run(struct ieee80211_hw *hw)
49 if (ret)
50 goto out;
51
52+ ret = mt7996_mcu_set_scs(phy, SCS_ENABLE);
53+ if (ret)
54+ goto out;
55+
56 set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
57
58 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
59 MT7996_WATCHDOG_TIME);
60
61+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
62+
63 if (!running)
64 mt7996_mac_reset_counters(phy);
65
66@@ -105,6 +111,7 @@ static void mt7996_stop(struct ieee80211_hw *hw)
67 struct mt7996_phy *phy = mt7996_hw_phy(hw);
68
69 cancel_delayed_work_sync(&phy->mt76->mac_work);
70+ cancel_delayed_work_sync(&dev->scs_work);
71
72 mutex_lock(&dev->mt76.mutex);
73
74diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer7e2761e2023-10-12 08:11:13 +080075index 141b838..6cedc39 100644
developer064da3c2023-06-13 15:57:26 +080076--- a/mt7996/mcu.c
77+++ b/mt7996/mcu.c
developer7e2761e2023-10-12 08:11:13 +080078@@ -4346,3 +4346,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
developer064da3c2023-06-13 15:57:26 +080079 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TXPOWER),
80 &req, sizeof(req), false);
81 }
82+
83+int mt7996_mcu_set_scs_stats(struct mt7996_phy *phy)
84+{
85+ struct mt7996_scs_ctrl ctrl = phy->scs_ctrl;
86+ struct {
87+ u8 band_idx;
88+ u8 _rsv[3];
89+
90+ __le16 tag;
91+ __le16 len;
92+
93+ u8 _rsv2[6];
94+ s8 min_rssi;
95+ u8 _rsv3;
96+ } __packed req = {
97+ .band_idx = phy->mt76->band_idx,
98+ .tag = cpu_to_le16(UNI_CMD_SCS_SEND_DATA),
99+ .len = cpu_to_le16(sizeof(req) - 4),
100+
101+ .min_rssi = ctrl.sta_min_rssi,
102+ };
103+
104+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
105+ &req, sizeof(req), false);
106+}
107+
108+void mt7996_sta_rssi_work(void *data, struct ieee80211_sta *sta)
109+{
110+ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
111+ struct mt7996_dev *dev = (struct mt7996_dev *)data;
112+ struct mt7996_phy *poll_phy;
113+ u8 band_idx = msta->wcid.phy_idx;
114+
115+ switch (band_idx) {
116+ case MT_BAND0:
117+ poll_phy = dev->mphy.priv;
118+ break;
119+ case MT_BAND1:
120+ poll_phy = mt7996_phy2(dev);
121+ break;
122+ case MT_BAND2:
123+ poll_phy = mt7996_phy3(dev);
124+ break;
125+ default:
126+ poll_phy = NULL;
127+ break;
128+ }
129+
130+ if (!poll_phy->scs_ctrl.scs_enable)
131+ return;
132+
133+ if (poll_phy->scs_ctrl.sta_min_rssi > msta->ack_signal)
134+ poll_phy->scs_ctrl.sta_min_rssi = msta->ack_signal;
135+}
136+
137+void mt7996_mcu_scs_sta_poll(struct work_struct *work)
138+{
139+ struct mt7996_dev *dev = container_of(work, struct mt7996_dev,
140+ scs_work.work);
141+ bool scs_enable_flag = false;
142+ u8 i;
143+
144+ ieee80211_iterate_stations_atomic(dev->mphy.hw, mt7996_sta_rssi_work, dev);
145+
146+ for (i = 0; i < __MT_MAX_BAND; i++) {
147+ struct mt7996_phy *phy;
148+
149+ switch (i) {
150+ case MT_BAND0:
151+ phy = dev->mphy.priv;
152+ break;
153+ case MT_BAND1:
154+ phy = mt7996_phy2(dev);
155+ break;
156+ case MT_BAND2:
157+ phy = mt7996_phy3(dev);
158+ break;
159+ default:
160+ phy = NULL;
161+ break;
162+ }
163+
164+ if (phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state) &&
165+ phy->scs_ctrl.scs_enable) {
166+ scs_enable_flag = true;
167+ if (mt7996_mcu_set_scs_stats(phy))
168+ dev_err(dev->mt76.dev, "Failed to send scs mcu cmd\n");
169+ phy->scs_ctrl.sta_min_rssi = 0;
170+ }
171+ }
172+
173+ if (scs_enable_flag)
174+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
175+}
176+
177+
178+int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
179+{
180+ struct mt7996_dev *dev = phy->dev;
181+ struct {
182+ u8 band_idx;
183+ u8 _rsv[3];
184+
185+ __le16 tag;
186+ __le16 len;
187+
188+ u8 scs_enable;
189+ u8 _rsv2[3];
190+ } __packed req = {
191+ .band_idx = phy->mt76->band_idx,
192+ .tag = cpu_to_le16(UNI_CMD_SCS_ENABLE),
193+ .len = cpu_to_le16(sizeof(req) - 4),
194+ .scs_enable = enable,
195+ };
196+
197+ phy->scs_ctrl.scs_enable = enable;
198+
199+ if (enable == SCS_ENABLE)
200+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
201+
202+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
203+ &req, sizeof(req), false);
204+}
205diff --git a/mt7996/mcu.h b/mt7996/mcu.h
developer7e2761e2023-10-12 08:11:13 +0800206index 16ffc3d..ff9cc9c 100644
developer064da3c2023-06-13 15:57:26 +0800207--- a/mt7996/mcu.h
208+++ b/mt7996/mcu.h
developerc2cfe0f2023-09-22 04:11:09 +0800209@@ -875,6 +875,12 @@ enum {
developer7e2761e2023-10-12 08:11:13 +0800210 UNI_CMD_PP_EN_CTRL,
developer064da3c2023-06-13 15:57:26 +0800211 };
212
213+enum {
214+ UNI_CMD_SCS_SEND_DATA,
215+ UNI_CMD_SCS_SET_PD_THR_RANGE = 2,
216+ UNI_CMD_SCS_ENABLE,
217+};
218+
219 #define MT7996_PATCH_SEC GENMASK(31, 24)
220 #define MT7996_PATCH_SCRAMBLE_KEY GENMASK(15, 8)
221 #define MT7996_PATCH_AES_KEY GENMASK(7, 0)
222diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer7e2761e2023-10-12 08:11:13 +0800223index efdcff7..eb48dbd 100644
developer064da3c2023-06-13 15:57:26 +0800224--- a/mt7996/mt7996.h
225+++ b/mt7996/mt7996.h
developer7e2761e2023-10-12 08:11:13 +0800226@@ -193,6 +193,16 @@ struct mt7996_hif {
developer064da3c2023-06-13 15:57:26 +0800227 int irq;
228 };
229
developer064da3c2023-06-13 15:57:26 +0800230+struct mt7996_scs_ctrl {
231+ u8 scs_enable;
232+ s8 sta_min_rssi;
233+};
234+
235+enum {
236+ SCS_DISABLE = 0,
237+ SCS_ENABLE,
238+};
239+
developer7e2761e2023-10-12 08:11:13 +0800240 struct mt7996_wed_rro_addr {
241 u32 head_low;
242 u32 head_high : 4;
243@@ -235,6 +245,8 @@ struct mt7996_phy {
developer064da3c2023-06-13 15:57:26 +0800244
245 bool has_aux_rx;
246
247+ struct mt7996_scs_ctrl scs_ctrl;
248+
249 #ifdef CONFIG_NL80211_TESTMODE
250 struct {
251 u32 *reg_backup;
developer7e2761e2023-10-12 08:11:13 +0800252@@ -280,6 +292,7 @@ struct mt7996_dev {
developer064da3c2023-06-13 15:57:26 +0800253 struct work_struct rc_work;
254 struct work_struct dump_work;
255 struct work_struct reset_work;
256+ struct delayed_work scs_work;
257 wait_queue_head_t reset_wait;
258 struct {
259 u32 state;
developer7e2761e2023-10-12 08:11:13 +0800260@@ -555,6 +568,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
developer064da3c2023-06-13 15:57:26 +0800261 void mt7996_mcu_exit(struct mt7996_dev *dev);
developer7e2761e2023-10-12 08:11:13 +0800262 int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
developer064da3c2023-06-13 15:57:26 +0800263 int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
264+int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
265+void mt7996_mcu_scs_sta_poll(struct work_struct *work);
266
267 static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
268 {
269--
developer7e2761e2023-10-12 08:11:13 +08002702.18.0
developer064da3c2023-06-13 15:57:26 +0800271