blob: 71a05fbba352b575359d6c83f5c0f1d3a1a2b044 [file] [log] [blame]
developerc2cfe0f2023-09-22 04:11:09 +08001From d7700431ea080cc79002cad62384ea66054f9905 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
developerc2cfe0f2023-09-22 04:11:09 +08004Subject: [PATCH 1005/1024] 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 +++
17 mt7996/mt7996.h | 16 ++++++
18 6 files changed, 154 insertions(+)
19
20diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developerc2cfe0f2023-09-22 04:11:09 +080021index 7e859da65..25b467e5d 100644
developer064da3c2023-06-13 15:57:26 +080022--- a/mt76_connac_mcu.h
23+++ b/mt76_connac_mcu.h
developerc2cfe0f2023-09-22 04:11:09 +080024@@ -1230,6 +1230,7 @@ enum {
25 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
developerc2cfe0f2023-09-22 04:11:09 +080033index aebdc0df8..f76fe6ea7 100644
developer064da3c2023-06-13 15:57:26 +080034--- a/mt7996/init.c
35+++ b/mt7996/init.c
developerc2cfe0f2023-09-22 04:11:09 +080036@@ -1070,6 +1070,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
developerc2cfe0f2023-09-22 04:11:09 +080045index 3336602f1..ab5693e4f 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
developerc2cfe0f2023-09-22 04:11:09 +080075index 837cf1b30..db3cab39c 100644
developer064da3c2023-06-13 15:57:26 +080076--- a/mt7996/mcu.c
77+++ b/mt7996/mcu.c
developerc2cfe0f2023-09-22 04:11:09 +080078@@ -4354,3 +4354,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
developerc2cfe0f2023-09-22 04:11:09 +0800206index 86701c3f6..3b2536601 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 {
developer064da3c2023-06-13 15:57:26 +0800210 MT7996_SEC_MODE_MAX,
211 };
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
developerc2cfe0f2023-09-22 04:11:09 +0800223index d65adac41..7b7dc9b33 100644
developer064da3c2023-06-13 15:57:26 +0800224--- a/mt7996/mt7996.h
225+++ b/mt7996/mt7996.h
developerc2cfe0f2023-09-22 04:11:09 +0800226@@ -165,6 +165,17 @@ struct mt7996_hif {
developer064da3c2023-06-13 15:57:26 +0800227 int irq;
228 };
229
230+
231+struct mt7996_scs_ctrl {
232+ u8 scs_enable;
233+ s8 sta_min_rssi;
234+};
235+
236+enum {
237+ SCS_DISABLE = 0,
238+ SCS_ENABLE,
239+};
240+
241 struct mt7996_phy {
242 struct mt76_phy *mt76;
243 struct mt7996_dev *dev;
developerc2cfe0f2023-09-22 04:11:09 +0800244@@ -198,6 +209,8 @@ struct mt7996_phy {
developer064da3c2023-06-13 15:57:26 +0800245
246 bool has_aux_rx;
247
248+ struct mt7996_scs_ctrl scs_ctrl;
249+
250 #ifdef CONFIG_NL80211_TESTMODE
251 struct {
252 u32 *reg_backup;
developerc2cfe0f2023-09-22 04:11:09 +0800253@@ -243,6 +256,7 @@ struct mt7996_dev {
developer064da3c2023-06-13 15:57:26 +0800254 struct work_struct rc_work;
255 struct work_struct dump_work;
256 struct work_struct reset_work;
257+ struct delayed_work scs_work;
258 wait_queue_head_t reset_wait;
259 struct {
260 u32 state;
developerc2cfe0f2023-09-22 04:11:09 +0800261@@ -497,6 +511,8 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
developer064da3c2023-06-13 15:57:26 +0800262 void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
263 void mt7996_mcu_exit(struct mt7996_dev *dev);
264 int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
265+int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
266+void mt7996_mcu_scs_sta_poll(struct work_struct *work);
267
268 static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
269 {
270--
developerc2cfe0f2023-09-22 04:11:09 +08002712.39.2
developer064da3c2023-06-13 15:57:26 +0800272