blob: 7024d1f5da3ee8c8ae17cf97b52336b4fe7fb650 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 230a5ba21216bb292f2fb1b0cf2236e2e14de2ca Mon Sep 17 00:00:00 2001
developer73e5a572022-04-19 10:21:20 +08002From: MeiChia Chiu <meichia.chiu@mediatek.com>
developer6caa5e22022-06-16 13:33:13 +08003Date: Mon, 6 Jun 2022 20:15:51 +0800
developer05f3b2b2024-08-19 19:17:34 +08004Subject: [PATCH 1004/1052] wifi: mt76: mt7915: certification patches
developer73e5a572022-04-19 10:21:20 +08005
developer73e5a572022-04-19 10:21:20 +08006---
developerf7a3ca32022-09-01 14:44:55 +08007 mt76_connac_mcu.h | 1 +
8 mt7915/mac.c | 23 +++
developerbb6ddff2023-03-08 17:22:32 +08009 mt7915/main.c | 13 +-
developerf7a3ca32022-09-01 14:44:55 +080010 mt7915/mcu.c | 466 +++++++++++++++++++++++++++++++++++++++++++
11 mt7915/mcu.h | 207 ++++++++++++++++++-
12 mt7915/mt7915.h | 13 ++
developerbb6ddff2023-03-08 17:22:32 +080013 mt7915/mtk_debugfs.c | 7 +-
developer70180b02023-11-14 17:01:47 +080014 mt7915/vendor.c | 188 +++++++++++++++++
developerf7a3ca32022-09-01 14:44:55 +080015 mt7915/vendor.h | 42 ++++
developer70180b02023-11-14 17:01:47 +080016 9 files changed, 955 insertions(+), 5 deletions(-)
developer73e5a572022-04-19 10:21:20 +080017
18diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developer05f3b2b2024-08-19 19:17:34 +080019index cd6db774..bd28cc50 100644
developer73e5a572022-04-19 10:21:20 +080020--- a/mt76_connac_mcu.h
21+++ b/mt76_connac_mcu.h
developer05f3b2b2024-08-19 19:17:34 +080022@@ -1248,6 +1248,7 @@ enum {
developer73e5a572022-04-19 10:21:20 +080023 /* for vendor csi and air monitor */
24 MCU_EXT_CMD_SMESH_CTRL = 0xae,
developerdad89a32024-04-29 14:17:17 +080025 MCU_EXT_CMD_SET_QOS_MAP = 0xb4,
developer73e5a572022-04-19 10:21:20 +080026+ MCU_EXT_CMD_CERT_CFG = 0xb7,
27 MCU_EXT_CMD_CSI_CTRL = 0xc2,
28 };
29
developer73e5a572022-04-19 10:21:20 +080030diff --git a/mt7915/mac.c b/mt7915/mac.c
developer05f3b2b2024-08-19 19:17:34 +080031index 778f04f7..2fd1d1fb 100644
developer73e5a572022-04-19 10:21:20 +080032--- a/mt7915/mac.c
33+++ b/mt7915/mac.c
developer047bc182022-11-16 12:20:48 +080034@@ -8,6 +8,7 @@
developer73e5a572022-04-19 10:21:20 +080035 #include "../dma.h"
36 #include "mac.h"
37 #include "mcu.h"
38+#include "vendor.h"
39
developer047bc182022-11-16 12:20:48 +080040 #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2)
developer73e5a572022-04-19 10:21:20 +080041
developera20cdc22024-05-31 18:57:31 +080042@@ -1961,6 +1962,21 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
developer8effbd32023-04-17 15:57:28 +080043 spin_unlock_bh(&phy->stats_lock);
developer73e5a572022-04-19 10:21:20 +080044 }
45
46+#ifdef CONFIG_MTK_VENDOR
47+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta)
48+{
49+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
50+ struct mt7915_dev *dev = msta->vif->phy->dev;
51+ u32 *changed = data;
52+
developer47efbdb2023-06-29 20:33:22 +080053+ spin_lock_bh(&dev->mt76.sta_poll_lock);
developer73e5a572022-04-19 10:21:20 +080054+ msta->changed |= *changed;
55+ if (list_empty(&msta->rc_list))
56+ list_add_tail(&msta->rc_list, &dev->sta_rc_list);
developer47efbdb2023-06-29 20:33:22 +080057+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
developer73e5a572022-04-19 10:21:20 +080058+}
59+#endif
60+
61 void mt7915_mac_sta_rc_work(struct work_struct *work)
62 {
63 struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
developera20cdc22024-05-31 18:57:31 +080064@@ -1983,6 +1999,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
developer73e5a572022-04-19 10:21:20 +080065 sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
66 vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
67
68+#ifdef CONFIG_MTK_VENDOR
69+ if (changed & CAPI_RFEATURE_CHANGED) {
70+ mt7915_mcu_set_rfeature_starec(&changed, dev, vif, sta);
developer47efbdb2023-06-29 20:33:22 +080071+ spin_lock_bh(&dev->mt76.sta_poll_lock);
developer73e5a572022-04-19 10:21:20 +080072+ continue;
73+ }
74+#endif
75 if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED |
76 IEEE80211_RC_NSS_CHANGED |
77 IEEE80211_RC_BW_CHANGED))
78diff --git a/mt7915/main.c b/mt7915/main.c
developer05f3b2b2024-08-19 19:17:34 +080079index aca3e9c0..09e1a83b 100644
developer73e5a572022-04-19 10:21:20 +080080--- a/mt7915/main.c
81+++ b/mt7915/main.c
developerdad89a32024-04-29 14:17:17 +080082@@ -771,6 +771,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
developer73e5a572022-04-19 10:21:20 +080083 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
84 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
85 bool ext_phy = mvif->phy != &dev->phy;
86+#ifdef CONFIG_MTK_VENDOR
developer4d581862023-02-13 16:01:56 +080087+ struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
developer73e5a572022-04-19 10:21:20 +080088+#endif
89 int ret, idx;
developera46f6132024-03-26 14:09:54 +080090 u32 addr;
developer73e5a572022-04-19 10:21:20 +080091
developerdad89a32024-04-29 14:17:17 +080092@@ -803,7 +806,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
developer73e5a572022-04-19 10:21:20 +080093 #ifdef CONFIG_MTK_VENDOR
94 mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
95 #endif
96- return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
97+ ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
98+ if (ret)
99+ return ret;
100+
101+#ifdef CONFIG_MTK_VENDOR
developer4d581862023-02-13 16:01:56 +0800102+ if (phy->muru_onoff & MUMIMO_DL_CERT)
developer73e5a572022-04-19 10:21:20 +0800103+ mt7915_mcu_set_mimo(phy, 0);
developer73e5a572022-04-19 10:21:20 +0800104+#endif
105+ return 0;
106 }
107
108 void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
109diff --git a/mt7915/mcu.c b/mt7915/mcu.c
developer05f3b2b2024-08-19 19:17:34 +0800110index 6867635f..c819a3be 100644
developer73e5a572022-04-19 10:21:20 +0800111--- a/mt7915/mcu.c
112+++ b/mt7915/mcu.c
developera46f6132024-03-26 14:09:54 +0800113@@ -4402,6 +4402,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
developer73e5a572022-04-19 10:21:20 +0800114
115 return 0;
116 }
117+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
118+{
119+ u8 mode, val;
120+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
developer4d581862023-02-13 16:01:56 +0800121+ struct mt7915_phy *phy = mvif->phy;
developer73e5a572022-04-19 10:21:20 +0800122+
123+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
124+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
125+
126+ switch (mode) {
127+ case RATE_PARAM_FIXED_OFDMA:
128+ if (val == 3) /* DL 20 and 80 */
developer4d581862023-02-13 16:01:56 +0800129+ phy->muru_onoff = OFDMA_DL; /* Enable OFDMA DL only */
developer73e5a572022-04-19 10:21:20 +0800130+ else
developer4d581862023-02-13 16:01:56 +0800131+ phy->muru_onoff = val;
developer73e5a572022-04-19 10:21:20 +0800132+ break;
133+ case RATE_PARAM_FIXED_MIMO:
134+ if (val == 0)
developer4d581862023-02-13 16:01:56 +0800135+ phy->muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
developer73e5a572022-04-19 10:21:20 +0800136+ break;
137+ }
138+}
139+
140+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
141+ struct ieee80211_vif *vif, struct ieee80211_sta *sta)
142+{
143+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
144+ struct mt7915_vif *mvif = msta->vif;
145+ struct sta_rec_ra_fixed *ra;
146+ struct sk_buff *skb;
147+ struct tlv *tlv;
148+ u8 mode, val;
149+ int len = sizeof(struct sta_req_hdr) + sizeof(*ra);
150+
151+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
152+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
153+
154+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &msta->wcid, len);
155+ if (IS_ERR(skb))
156+ return;
157+
158+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
159+ ra = (struct sta_rec_ra_fixed *)tlv;
160+
161+ switch (mode) {
162+ case RATE_PARAM_FIXED_GI:
163+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_GI);
164+ ra->phy.sgi = val * 85;
165+ break;
166+ case RATE_PARAM_FIXED_HE_LTF:
167+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_HE_LTF);
168+ ra->phy.he_ltf = val * 85;
169+ break;
170+ case RATE_PARAM_FIXED_MCS:
171+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_MCS);
172+ ra->phy.mcs = val;
173+ break;
174+ }
175+
176+ mt76_mcu_skb_send_msg(&dev->mt76, skb,
177+ MCU_EXT_CMD(STA_REC_UPDATE), true);
178+}
179+
180+int mt7915_mcu_set_mu_prot_frame_th(struct mt7915_phy *phy, u32 val)
181+{
182+ struct mt7915_dev *dev = phy->dev;
183+ struct {
184+ __le32 cmd;
185+ __le32 threshold;
186+ } __packed req = {
187+ .cmd = cpu_to_le32(MURU_SET_PROT_FRAME_THR),
188+ .threshold = val,
189+ };
190+
191+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
192+ sizeof(req), false);
193+}
194+
195+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val)
196+{
197+ struct mt7915_dev *dev = phy->dev;
198+ struct {
199+ __le32 cmd;
200+ u8 override;
201+ } __packed req = {
202+ .cmd = cpu_to_le32(MURU_SET_CERT_MU_EDCA_OVERRIDE),
203+ .override = val,
204+ };
205+
206+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
207+ sizeof(req), false);
208+}
209+
210+int mt7915_mcu_set_muru_cfg(struct mt7915_phy *phy, struct mt7915_muru *muru)
211+{
212+ struct mt7915_dev *dev = phy->dev;
213+ struct {
214+ __le32 cmd;
215+ struct mt7915_muru muru;
216+ } __packed req = {
217+ .cmd = cpu_to_le32(MURU_SET_MANUAL_CFG),
218+ };
219+
220+ memcpy(&req.muru, muru, sizeof(struct mt7915_muru));
221+
222+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
223+ sizeof(req), false);
224+}
225+
226+int mt7915_set_muru_cfg(struct mt7915_phy *phy, u8 action, u8 val)
227+{
228+ struct mt7915_muru muru;
229+ struct mt7915_muru_dl *dl = &muru.dl;
230+ struct mt7915_muru_ul *ul = &muru.ul;
231+ struct mt7915_muru_comm *comm = &muru.comm;
232+
233+ memset(&muru, 0, sizeof(muru));
234+
235+ switch (action) {
236+ case MURU_DL_USER_CNT:
237+ dl->user_num = val;
238+ comm->ppdu_format |= MURU_PPDU_HE_MU;
239+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_DL;
240+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
241+ muru.cfg_dl = cpu_to_le32(MURU_USER_CNT);
242+ return mt7915_mcu_set_muru_cfg(phy, &muru);
243+ case MURU_UL_USER_CNT:
244+ ul->user_num = val;
245+ comm->ppdu_format |= MURU_PPDU_HE_TRIG;
246+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_UL;
247+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
248+ muru.cfg_ul = cpu_to_le32(MURU_USER_CNT);
249+ return mt7915_mcu_set_muru_cfg(phy, &muru);
250+ default:
251+ return 0;
252+ }
253+}
254+
255+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type)
256+{
257+ struct mt7915_dev *dev = phy->dev;
258+ struct {
259+ __le32 cmd;
260+ u8 enable_su;
261+ } __packed ppdu_type_req = {
262+ .cmd = cpu_to_le32(MURU_SET_SUTX),
263+ };
264+
265+ switch(ppdu_type) {
266+ case CAPI_SU:
267+ ppdu_type_req.enable_su = 1;
268+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
269+ &ppdu_type_req, sizeof(ppdu_type_req), false);
270+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, 0);
271+ break;
272+ case CAPI_MU:
273+ ppdu_type_req.enable_su = 0;
274+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
275+ &ppdu_type_req, sizeof(ppdu_type_req), false);
276+ break;
277+ default:
278+ break;
279+ }
280+}
281+
282+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt)
283+{
284+ struct mt7915_dev *dev = phy->dev;
285+ struct {
286+ __le32 cmd;
287+ u8 enable_su;
288+ } __packed nusers_ofdma_req = {
289+ .cmd = cpu_to_le32(MURU_SET_SUTX),
290+ .enable_su = 0,
291+ };
292+
293+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
294+ &nusers_ofdma_req, sizeof(nusers_ofdma_req), false);
295+
296+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
297+ mt7915_mcu_set_mu_prot_frame_th(phy, 9999);
298+ switch(type) {
299+ case MURU_UL_USER_CNT:
300+ mt7915_set_muru_cfg(phy, MURU_UL_USER_CNT, ofdma_user_cnt);
301+ break;
302+ case MURU_DL_USER_CNT:
303+ default:
304+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, ofdma_user_cnt);
305+ break;
306+ }
307+}
308+
309+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction)
310+{
311+#define MUMIMO_SET_FIXED_RATE 10
312+#define MUMIMO_SET_FIXED_GRP_RATE 11
313+#define MUMIMO_SET_FORCE_MU 12
314+ struct mt7915_dev *dev = phy->dev;
315+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
316+ struct {
317+ __le32 cmd;
318+ __le16 sub_cmd;
319+ __le16 disable_ra;
320+ } __packed fixed_rate_req = {
321+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
322+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FIXED_RATE),
323+ .disable_ra = cpu_to_le16(1),
324+ };
325+ struct {
326+ __le32 cmd;
327+ __le32 sub_cmd;
328+ struct {
329+ u8 user_cnt:2;
330+ u8 rsv:2;
331+ u8 ns0:1;
332+ u8 ns1:1;
333+ u8 ns2:1;
334+ u8 ns3:1;
335+
336+ __le16 wlan_id_user0;
337+ __le16 wlan_id_user1;
338+ __le16 wlan_id_user2;
339+ __le16 wlan_id_user3;
340+
341+ u8 dl_mcs_user0:4;
342+ u8 dl_mcs_user1:4;
343+ u8 dl_mcs_user2:4;
344+ u8 dl_mcs_user3:4;
345+
346+ u8 ul_mcs_user0:4;
347+ u8 ul_mcs_user1:4;
348+ u8 ul_mcs_user2:4;
349+ u8 ul_mcs_user3:4;
350+
351+ u8 ru_alloc;
352+ u8 cap;
353+ u8 gi;
354+ u8 dl_ul;
355+ } grp_rate_conf;
356+ } fixed_grp_rate_req = {
357+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
358+ .sub_cmd = cpu_to_le32(MUMIMO_SET_FIXED_GRP_RATE),
359+ .grp_rate_conf = {
360+ .user_cnt = 1,
361+ .ru_alloc = 134,
362+ .gi = 0,
363+ .cap = 1,
364+ .dl_ul = 0,
365+ .wlan_id_user0 = cpu_to_le16(1),
developer15c355d2023-03-21 17:28:34 +0800366+ .dl_mcs_user0 = 4,
developer73e5a572022-04-19 10:21:20 +0800367+ .wlan_id_user1 = cpu_to_le16(2),
developer15c355d2023-03-21 17:28:34 +0800368+ .dl_mcs_user1 = 4,
developer73e5a572022-04-19 10:21:20 +0800369+ },
370+ };
371+ struct {
372+ __le32 cmd;
373+ __le16 sub_cmd;
374+ bool force_mu;
375+ } __packed force_mu_req = {
376+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
377+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FORCE_MU),
378+ .force_mu = true,
379+ };
380+
381+ switch (chandef->width) {
382+ case NL80211_CHAN_WIDTH_20_NOHT:
383+ case NL80211_CHAN_WIDTH_20:
384+ fixed_grp_rate_req.grp_rate_conf.ru_alloc = 122;
385+ break;
386+ case NL80211_CHAN_WIDTH_80:
387+ default:
388+ break;
389+ }
390+
391+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
392+
393+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
394+ &fixed_rate_req, sizeof(fixed_rate_req), false);
395+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
396+ &fixed_grp_rate_req, sizeof(fixed_grp_rate_req), false);
397+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
398+ &force_mu_req, sizeof(force_mu_req), false);
399+}
400+
401+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
402+{
403+ struct mt7915_dev *dev = phy->dev;
404+ struct {
405+ __le32 cmd;
406+ u8 enable;
407+ } __packed req = {
408+ .cmd = cpu_to_le32(MURU_SET_20M_DYN_ALGO),
409+ .enable = enable,
410+ };
411+
412+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
413+ &req, sizeof(req), false);
414+}
415+
416+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type)
417+{
418+#define CFGINFO_CERT_CFG 4
419+ struct mt7915_dev *dev = phy->dev;
420+ struct {
421+ struct basic_info{
422+ u8 dbdc_idx;
423+ u8 rsv[3];
424+ __le32 tlv_num;
425+ u8 tlv_buf[0];
426+ } hdr;
427+ struct cert_cfg{
428+ __le16 tag;
429+ __le16 length;
430+ u8 cert_program;
431+ u8 rsv[3];
432+ } tlv;
433+ } req = {
434+ .hdr = {
435+ .dbdc_idx = phy != &dev->phy,
436+ .tlv_num = cpu_to_le32(1),
437+ },
438+ .tlv = {
439+ .tag = cpu_to_le16(CFGINFO_CERT_CFG),
440+ .length = cpu_to_le16(sizeof(struct cert_cfg)),
441+ .cert_program = type, /* 1: CAPI Enable */
442+ }
443+ };
444+
445+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CERT_CFG),
446+ &req, sizeof(req), false);
447+}
448+
449+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val)
450+{
451+#define BF_CMD_CFG_PHY 36
452+#define BF_PHY_SMTH_INTL_BYPASS 0
453+ struct mt7915_dev *dev = phy->dev;
454+ struct {
455+ u8 cmd_category_id;
456+ u8 action;
457+ u8 band_idx;
458+ u8 smthintbypass;
459+ u8 rsv[12];
460+ } req = {
461+ .cmd_category_id = BF_CMD_CFG_PHY,
462+ .action = BF_PHY_SMTH_INTL_BYPASS,
463+ .band_idx = phy != &dev->phy,
464+ .smthintbypass = val,
465+ };
466+
467+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
468+ &req, sizeof(req), false);
469+}
470+
471+int mt7915_mcu_set_bsrp_ctrl(struct mt7915_phy *phy, u16 interval,
472+ u16 ru_alloc, u32 ppdu_dur, u8 trig_flow, u8 ext_cmd)
473+{
474+ struct mt7915_dev *dev = phy->dev;
475+ struct {
476+ __le32 cmd;
477+ __le16 bsrp_interval;
478+ __le16 bsrp_ru_alloc;
479+ __le32 ppdu_duration;
480+ u8 trigger_flow;
481+ u8 ext_cmd_bsrp;
482+ } __packed req = {
483+ .cmd = cpu_to_le32(MURU_SET_BSRP_CTRL),
484+ .bsrp_interval = cpu_to_le16(interval),
485+ .bsrp_ru_alloc = cpu_to_le16(ru_alloc),
486+ .ppdu_duration = cpu_to_le32(ppdu_dur),
487+ .trigger_flow = trig_flow,
488+ .ext_cmd_bsrp = ext_cmd,
489+ };
490+
491+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
492+ sizeof(req), false);
493+}
494+
495+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num)
496+{
497+ struct mt7915_dev *dev = phy->dev;
498+ struct {
499+ __le32 cmd;
500+ u8 ack_policy;
501+ } __packed req = {
502+ .cmd = cpu_to_le32(MURU_SET_MU_DL_ACK_POLICY),
503+ .ack_policy = policy_num,
504+ };
505+
506+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
507+ sizeof(req), false);
508+}
509+
510+int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
511+ u8 v1, u8 v2, u8 v3)
512+{
513+ struct mt7915_dev *dev = phy->dev;
514+ struct {
515+ u8 cmd_category_id;
516+ u8 action;
517+ u8 read_clear;
518+ u8 vht_opt;
519+ u8 he_opt;
520+ u8 glo_opt;
521+ __le16 wlan_idx;
522+ u8 sound_interval;
523+ u8 sound_stop;
524+ u8 max_sound_sta;
525+ u8 tx_time;
526+ u8 mcs;
527+ bool ldpc;
528+ u8 inf;
529+ u8 rsv;
530+ } __packed req = {
531+ .cmd_category_id = BF_CMD_TXSND_INFO,
532+ .action = action,
533+ };
534+
535+ switch (action) {
536+ case BF_SND_CFG_OPT:
537+ req.vht_opt = v1;
538+ req.he_opt = v2;
539+ req.glo_opt = v3;
540+ break;
541+ default:
542+ return -EINVAL;
543+ }
544+
545+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
546+ sizeof(req), false);
547+}
548+
549+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type)
550+{
551+ struct mt7915_dev *dev = phy->dev;
552+ int ret = 0;
553+ struct {
554+ __le32 cmd;
555+ u8 trig_type;
556+ } __packed req = {
557+ .cmd = cpu_to_le32(MURU_SET_TRIG_TYPE),
558+ .trig_type = trig_type,
559+ };
560+
561+ if (enable) {
562+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
563+ sizeof(req), false);
564+ if (ret)
565+ return ret;
566+ }
567+
568+ switch (trig_type) {
569+ case CAPI_BASIC:
570+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 0, 0, enable);
571+ case CAPI_BRP:
572+ return mt7915_mcu_set_txbf_sound_info(phy, BF_SND_CFG_OPT,
573+ 0x0, 0x0, 0x1b);
574+ case CAPI_MU_BAR:
575+ return mt7915_mcu_set_mu_dl_ack_policy(phy,
576+ MU_DL_ACK_POLICY_MU_BAR);
577+ case CAPI_BSRP:
578+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 4, 0, enable);
579+ default:
580+ return 0;
581+ }
582+}
583 #endif
584
585 #ifdef MTK_DEBUG
586diff --git a/mt7915/mcu.h b/mt7915/mcu.h
developer05f3b2b2024-08-19 19:17:34 +0800587index f44146ed..eef2fc00 100644
developer73e5a572022-04-19 10:21:20 +0800588--- a/mt7915/mcu.h
589+++ b/mt7915/mcu.h
developer753619c2024-02-22 13:42:45 +0800590@@ -486,10 +486,14 @@ enum {
developer73e5a572022-04-19 10:21:20 +0800591 RATE_PARAM_FIXED = 3,
592 RATE_PARAM_MMPS_UPDATE = 5,
593 RATE_PARAM_FIXED_HE_LTF = 7,
594- RATE_PARAM_FIXED_MCS,
595+ RATE_PARAM_FIXED_MCS = 8,
596 RATE_PARAM_FIXED_GI = 11,
597 RATE_PARAM_AUTO = 20,
developer072c5612022-07-15 18:30:03 +0800598 RATE_PARAM_SPE_UPDATE = 22,
developer73e5a572022-04-19 10:21:20 +0800599+#ifdef CONFIG_MTK_VENDOR
600+ RATE_PARAM_FIXED_MIMO = 30,
601+ RATE_PARAM_FIXED_OFDMA = 31,
602+#endif
603 };
604
605 #define RATE_CFG_MCS GENMASK(3, 0)
developer753619c2024-02-22 13:42:45 +0800606@@ -501,6 +505,9 @@ enum {
developer73e5a572022-04-19 10:21:20 +0800607 #define RATE_CFG_PHY_TYPE GENMASK(27, 24)
608 #define RATE_CFG_HE_LTF GENMASK(31, 28)
609
610+#define RATE_CFG_MODE GENMASK(15, 8)
611+#define RATE_CFG_VAL GENMASK(7, 0)
612+
613 enum {
developer3609d782022-11-29 18:07:22 +0800614 TX_POWER_LIMIT_ENABLE,
615 TX_POWER_LIMIT_TABLE = 0x4,
developer753619c2024-02-22 13:42:45 +0800616@@ -683,5 +690,203 @@ enum CSI_CHAIN_TYPE {
developer7c3a5082022-06-24 13:40:42 +0800617 #define OFDMA_UL BIT(1)
618 #define MUMIMO_DL BIT(2)
619 #define MUMIMO_UL BIT(3)
620+#define MUMIMO_DL_CERT BIT(4)
developer73e5a572022-04-19 10:21:20 +0800621+
622+#ifdef CONFIG_MTK_VENDOR
623+struct mt7915_muru_comm {
developer7c3a5082022-06-24 13:40:42 +0800624+ u8 ppdu_format;
625+ u8 sch_type;
626+ u8 band;
627+ u8 wmm_idx;
628+ u8 spe_idx;
629+ u8 proc_type;
developer73e5a572022-04-19 10:21:20 +0800630+};
631+
632+struct mt7915_muru_dl {
developer7c3a5082022-06-24 13:40:42 +0800633+ u8 user_num;
634+ u8 tx_mode;
635+ u8 bw;
636+ u8 gi;
637+ u8 ltf;
638+ /* sigB */
639+ u8 mcs;
640+ u8 dcm;
641+ u8 cmprs;
developer73e5a572022-04-19 10:21:20 +0800642+
developer7c3a5082022-06-24 13:40:42 +0800643+ u8 ru[8];
644+ u8 c26[2];
645+ u8 ack_policy;
developer73e5a572022-04-19 10:21:20 +0800646+
developer7c3a5082022-06-24 13:40:42 +0800647+ struct {
648+ __le16 wlan_idx;
649+ u8 ru_alloc_seg;
650+ u8 ru_idx;
651+ u8 ldpc;
652+ u8 nss;
653+ u8 mcs;
654+ u8 mu_group_idx;
655+ u8 vht_groud_id;
656+ u8 vht_up;
657+ u8 he_start_stream;
658+ u8 he_mu_spatial;
659+ u8 ack_policy;
660+ __le16 tx_power_alpha;
661+ } usr[16];
developer73e5a572022-04-19 10:21:20 +0800662+};
663+
664+struct mt7915_muru_ul {
developer7c3a5082022-06-24 13:40:42 +0800665+ u8 user_num;
developer73e5a572022-04-19 10:21:20 +0800666+
developer7c3a5082022-06-24 13:40:42 +0800667+ /* UL TX */
668+ u8 trig_type;
669+ __le16 trig_cnt;
670+ __le16 trig_intv;
671+ u8 bw;
672+ u8 gi_ltf;
673+ __le16 ul_len;
674+ u8 pad;
675+ u8 trig_ta[ETH_ALEN];
676+ u8 ru[8];
677+ u8 c26[2];
developer73e5a572022-04-19 10:21:20 +0800678+
developer7c3a5082022-06-24 13:40:42 +0800679+ struct {
680+ __le16 wlan_idx;
681+ u8 ru_alloc;
682+ u8 ru_idx;
683+ u8 ldpc;
684+ u8 nss;
685+ u8 mcs;
686+ u8 target_rssi;
687+ __le32 trig_pkt_size;
688+ } usr[16];
developer73e5a572022-04-19 10:21:20 +0800689+
developer7c3a5082022-06-24 13:40:42 +0800690+ /* HE TB RX Debug */
691+ __le32 rx_hetb_nonsf_en_bitmap;
692+ __le32 rx_hetb_cfg[2];
developer73e5a572022-04-19 10:21:20 +0800693+
developer7c3a5082022-06-24 13:40:42 +0800694+ /* DL TX */
695+ u8 ba_type;
developer73e5a572022-04-19 10:21:20 +0800696+};
697+
698+struct mt7915_muru {
developer7c3a5082022-06-24 13:40:42 +0800699+ __le32 cfg_comm;
700+ __le32 cfg_dl;
701+ __le32 cfg_ul;
developer73e5a572022-04-19 10:21:20 +0800702+
developer7c3a5082022-06-24 13:40:42 +0800703+ struct mt7915_muru_comm comm;
704+ struct mt7915_muru_dl dl;
705+ struct mt7915_muru_ul ul;
developer73e5a572022-04-19 10:21:20 +0800706+};
707+
developer7c3a5082022-06-24 13:40:42 +0800708+#define MURU_PPDU_HE_TRIG BIT(2)
developer73e5a572022-04-19 10:21:20 +0800709+#define MURU_PPDU_HE_MU BIT(3)
710+
711+#define MURU_OFDMA_SCH_TYPE_DL BIT(0)
712+#define MURU_OFDMA_SCH_TYPE_UL BIT(1)
713+
714+/* Common Config */
715+#define MURU_COMM_PPDU_FMT BIT(0)
716+#define MURU_COMM_SCH_TYPE BIT(1)
717+#define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_SCH_TYPE)
developer73e5a572022-04-19 10:21:20 +0800718+/* DL&UL User config*/
719+#define MURU_USER_CNT BIT(4)
720+
721+enum {
developer7c3a5082022-06-24 13:40:42 +0800722+ CAPI_SU,
723+ CAPI_MU,
724+ CAPI_ER_SU,
725+ CAPI_TB,
726+ CAPI_LEGACY
developer73e5a572022-04-19 10:21:20 +0800727+};
728+
729+enum {
developer7c3a5082022-06-24 13:40:42 +0800730+ CAPI_BASIC,
731+ CAPI_BRP,
732+ CAPI_MU_BAR,
733+ CAPI_MU_RTS,
734+ CAPI_BSRP,
735+ CAPI_GCR_MU_BAR,
736+ CAPI_BQRP,
737+ CAPI_NDP_FRP
developer73e5a572022-04-19 10:21:20 +0800738+};
739+
740+enum {
developer7c3a5082022-06-24 13:40:42 +0800741+ MURU_SET_BSRP_CTRL = 1,
742+ MURU_SET_SUTX = 16,
743+ MURU_SET_MUMIMO_CTRL = 17,
744+ MURU_SET_MANUAL_CFG = 100,
745+ MURU_SET_MU_DL_ACK_POLICY = 200,
746+ MURU_SET_TRIG_TYPE = 201,
747+ MURU_SET_20M_DYN_ALGO = 202,
748+ MURU_SET_PROT_FRAME_THR = 204,
749+ MURU_SET_CERT_MU_EDCA_OVERRIDE = 205,
developer73e5a572022-04-19 10:21:20 +0800750+};
751+
752+enum {
developer7c3a5082022-06-24 13:40:42 +0800753+ MU_DL_ACK_POLICY_MU_BAR = 3,
754+ MU_DL_ACK_POLICY_TF_FOR_ACK = 4,
755+ MU_DL_ACK_POLICY_SU_BAR = 5,
developer73e5a572022-04-19 10:21:20 +0800756+};
757+
758+enum {
developer7c3a5082022-06-24 13:40:42 +0800759+ BF_SOUNDING_OFF = 0,
760+ BF_SOUNDING_ON,
761+ BF_DATA_PACKET_APPLY,
762+ BF_PFMU_MEM_ALLOCATE,
763+ BF_PFMU_MEM_RELEASE,
764+ BF_PFMU_TAG_READ,
765+ BF_PFMU_TAG_WRITE,
766+ BF_PROFILE_READ,
767+ BF_PROFILE_WRITE,
768+ BF_PN_READ,
769+ BF_PN_WRITE,
770+ BF_PFMU_MEM_ALLOC_MAP_READ,
771+ BF_AID_SET,
772+ BF_STA_REC_READ,
773+ BF_PHASE_CALIBRATION,
774+ BF_IBF_PHASE_COMP,
775+ BF_LNA_GAIN_CONFIG,
776+ BF_PROFILE_WRITE_20M_ALL,
777+ BF_APCLIENT_CLUSTER,
778+ BF_AWARE_CTRL,
779+ BF_HW_ENABLE_STATUS_UPDATE,
780+ BF_REPT_CLONED_STA_TO_NORMAL_STA,
781+ BF_GET_QD,
782+ BF_BFEE_HW_CTRL,
783+ BF_PFMU_SW_TAG_WRITE,
784+ BF_MOD_EN_CTRL,
785+ BF_DYNSND_EN_INTR,
786+ BF_DYNSND_CFG_DMCS_TH,
787+ BF_DYNSND_EN_PFID_INTR,
788+ BF_CONFIG,
789+ BF_PFMU_DATA_WRITE,
790+ BF_FBRPT_DBG_INFO_READ,
791+ BF_CMD_TXSND_INFO,
792+ BF_CMD_PLY_INFO,
793+ BF_CMD_MU_METRIC,
794+ BF_CMD_TXCMD,
795+ BF_CMD_CFG_PHY,
796+ BF_CMD_SND_CNT,
797+ BF_CMD_MAX
developer73e5a572022-04-19 10:21:20 +0800798+};
799+
800+enum {
developer7c3a5082022-06-24 13:40:42 +0800801+ BF_SND_READ_INFO = 0,
802+ BF_SND_CFG_OPT,
803+ BF_SND_CFG_INTV,
804+ BF_SND_STA_STOP,
805+ BF_SND_CFG_MAX_STA,
806+ BF_SND_CFG_BFRP,
807+ BF_SND_CFG_INF
developer73e5a572022-04-19 10:21:20 +0800808+};
809+
810+enum {
developer7c3a5082022-06-24 13:40:42 +0800811+ MURU_UPDATE = 0,
812+ MURU_DL_USER_CNT,
813+ MURU_UL_USER_CNT,
814+ MURU_DL_INIT,
815+ MURU_UL_INIT,
developer73e5a572022-04-19 10:21:20 +0800816+};
817+#endif
818
819 #endif
820diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
developer05f3b2b2024-08-19 19:17:34 +0800821index 14107de3..cf49ac86 100644
developer73e5a572022-04-19 10:21:20 +0800822--- a/mt7915/mt7915.h
823+++ b/mt7915/mt7915.h
developer05f3b2b2024-08-19 19:17:34 +0800824@@ -749,6 +749,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
developerec567112022-10-11 11:02:55 +0800825 bool pci, int *irq);
developer73e5a572022-04-19 10:21:20 +0800826
827 #ifdef CONFIG_MTK_VENDOR
828+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta);
829+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
830+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
831+ struct ieee80211_vif *vif, struct ieee80211_sta *sta);
832+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type);
833+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num);
834+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type);
835+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt);
836+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
837+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable);
838+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val);
839+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type);
840+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val);
841 void mt7915_vendor_register(struct mt7915_phy *phy);
842 int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
developer753619c2024-02-22 13:42:45 +0800843 u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval);
developer73e5a572022-04-19 10:21:20 +0800844diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
developer05f3b2b2024-08-19 19:17:34 +0800845index 0beb3644..54daa736 100644
developer73e5a572022-04-19 10:21:20 +0800846--- a/mt7915/mtk_debugfs.c
847+++ b/mt7915/mtk_debugfs.c
developer753619c2024-02-22 13:42:45 +0800848@@ -2560,7 +2560,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
developer73e5a572022-04-19 10:21:20 +0800849
developer4d581862023-02-13 16:01:56 +0800850 *val = phy->muru_onoff;
developer73e5a572022-04-19 10:21:20 +0800851
developer4d581862023-02-13 16:01:56 +0800852- printk("mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
853+ printk("cert mumimo dl:%d, normal mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
854+ !!(phy->muru_onoff & MUMIMO_DL_CERT),
855 !!(phy->muru_onoff & MUMIMO_UL),
856 !!(phy->muru_onoff & MUMIMO_DL),
857 !!(phy->muru_onoff & OFDMA_UL),
developer753619c2024-02-22 13:42:45 +0800858@@ -2573,8 +2574,8 @@ static int mt7915_muru_onoff_set(void *data, u64 val)
developer73e5a572022-04-19 10:21:20 +0800859 {
developer4d581862023-02-13 16:01:56 +0800860 struct mt7915_phy *phy = data;
developer73e5a572022-04-19 10:21:20 +0800861
developer4d581862023-02-13 16:01:56 +0800862- if (val > 15) {
863- printk("Wrong value! The value is between 0 ~ 15.\n");
864+ if (val > 31) {
865+ printk("Wrong value! The value is between 0 ~ 31.\n");
866 goto exit;
867 }
developer73e5a572022-04-19 10:21:20 +0800868
869diff --git a/mt7915/vendor.c b/mt7915/vendor.c
developer05f3b2b2024-08-19 19:17:34 +0800870index fb32cd6d..e4317af3 100644
developer73e5a572022-04-19 10:21:20 +0800871--- a/mt7915/vendor.c
872+++ b/mt7915/vendor.c
developer05f3b2b2024-08-19 19:17:34 +0800873@@ -24,6 +24,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = {
874 [MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER] = { .type = NLA_NESTED },
developer73e5a572022-04-19 10:21:20 +0800875 };
876
877+static const struct nla_policy
878+wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
879+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
880+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA] = {.type = NLA_U8 },
881+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
882+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
883+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
884+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
885+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA] = {.type = NLA_U8 },
886+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
887+};
888+
889+static const struct nla_policy
890+rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
891+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
892+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
893+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
894+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
895+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
896+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
897+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
898+};
899+
900 struct csi_null_tone {
901 u8 start;
902 u8 end;
developer05f3b2b2024-08-19 19:17:34 +0800903@@ -933,6 +956,149 @@ mt7915_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
developer73e5a572022-04-19 10:21:20 +0800904 return len + 1;
905 }
906
907+static int mt7915_vendor_rfeature_ctrl(struct wiphy *wiphy,
908+ struct wireless_dev *wdev,
909+ const void *data,
910+ int data_len)
911+{
912+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
913+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
914+ struct mt7915_dev *dev = phy->dev;
915+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL];
916+ int err;
917+ u32 val;
918+
919+ err = nla_parse(tb, MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX, data, data_len,
920+ rfeature_ctrl_policy, NULL);
921+ if (err)
922+ return err;
923+
924+ val = CAPI_RFEATURE_CHANGED;
925+
926+ if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]) {
927+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_GI)|
928+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]));
929+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
930+ ieee80211_queue_work(hw, &dev->rc_work);
931+ }
932+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]) {
933+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_HE_LTF)|
934+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]));
935+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
936+ ieee80211_queue_work(hw, &dev->rc_work);
937+ }
938+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG]) {
939+ u8 enable, trig_type;
940+ int rem;
941+ struct nlattr *cur;
942+
943+ nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG], rem) {
944+ switch(nla_type(cur)) {
945+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN:
946+ enable = nla_get_u8(cur);
947+ break;
948+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE:
949+ trig_type = nla_get_u8(cur);
950+ break;
951+ default:
952+ return -EINVAL;
953+ };
954+ }
955+
956+ err = mt7915_mcu_set_rfeature_trig_type(phy, enable, trig_type);
957+ if (err)
958+ return err;
959+ }
960+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]) {
961+ u8 ack_policy;
962+
963+ ack_policy = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]);
964+#define HE_TB_PPDU_ACK 4
965+ switch (ack_policy) {
966+ case HE_TB_PPDU_ACK:
967+ return mt7915_mcu_set_mu_dl_ack_policy(phy, ack_policy);
968+ default:
969+ return 0;
970+ }
971+ }
972+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]) {
973+ u8 trig_txbf;
974+
975+ trig_txbf = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]);
976+ /* CAPI only issues trig_txbf=disable */
977+ }
978+
979+ return 0;
980+}
981+
982+static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
983+ struct wireless_dev *wdev,
984+ const void *data,
985+ int data_len)
986+{
987+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
988+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
989+ struct mt7915_dev *dev = phy->dev;
990+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL];
991+ int err;
992+ u8 val8;
993+ u16 val16;
994+ u32 val32;
995+
996+ err = nla_parse(tb, MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, data, data_len,
997+ wireless_ctrl_policy, NULL);
998+ if (err)
999+ return err;
1000+
1001+ val32 = CAPI_WIRELESS_CHANGED;
1002+
1003+ if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]) {
1004+ val32 &= ~CAPI_WIRELESS_CHANGED;
1005+ val32 |= CAPI_RFEATURE_CHANGED |
1006+ FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MCS) |
1007+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]));
1008+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val32);
1009+ ieee80211_queue_work(hw, &dev->rc_work);
1010+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]) {
1011+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]);
1012+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_OFDMA) |
1013+ FIELD_PREP(RATE_CFG_VAL, val8);
1014+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1015+ mt7915_set_wireless_vif, &val32);
1016+ if (val8 == 3) /* DL20and80 */
1017+ mt7915_mcu_set_dynalgo(phy, 1); /* Enable dynamic algo */
developer70180b02023-11-14 17:01:47 +08001018+ mt7915_mcu_set_mu_prot_frame_th(phy, 9999);
developer73e5a572022-04-19 10:21:20 +08001019+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]) {
1020+ val16 = nla_get_u16(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]);
1021+ hw->max_tx_aggregation_subframes = val16;
1022+ hw->max_rx_aggregation_subframes = val16;
1023+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]) {
1024+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]);
1025+ mt7915_mcu_set_mu_edca(phy, val8);
1026+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]) {
1027+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]);
1028+ mt7915_mcu_set_ppdu_tx_type(phy, val8);
1029+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]) {
1030+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]);
developer4d581862023-02-13 16:01:56 +08001031+ if (FIELD_GET(OFDMA_UL, phy->muru_onoff) == 1)
developer73e5a572022-04-19 10:21:20 +08001032+ mt7915_mcu_set_nusers_ofdma(phy, MURU_UL_USER_CNT, val8);
1033+ else
1034+ mt7915_mcu_set_nusers_ofdma(phy, MURU_DL_USER_CNT, val8);
1035+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]) {
1036+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]);
1037+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MIMO) |
1038+ FIELD_PREP(RATE_CFG_VAL, val8);
1039+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1040+ mt7915_set_wireless_vif, &val32);
1041+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) {
1042+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
1043+ mt7915_mcu_set_cert(phy, val8); /* Cert Enable for OMI */
1044+ mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
1045+ }
1046+
1047+ return 0;
1048+}
1049+
1050 static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
1051 {
1052 .info = {
developer05f3b2b2024-08-19 19:17:34 +08001053@@ -957,6 +1123,28 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
developer73e5a572022-04-19 10:21:20 +08001054 .dumpit = mt7915_vendor_amnt_ctrl_dump,
1055 .policy = amnt_ctrl_policy,
1056 .maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
1057+ },
1058+ {
1059+ .info = {
1060+ .vendor_id = MTK_NL80211_VENDOR_ID,
1061+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL,
1062+ },
1063+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
1064+ WIPHY_VENDOR_CMD_NEED_RUNNING,
1065+ .doit = mt7915_vendor_rfeature_ctrl,
1066+ .policy = rfeature_ctrl_policy,
1067+ .maxattr = MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX,
1068+ },
1069+ {
1070+ .info = {
1071+ .vendor_id = MTK_NL80211_VENDOR_ID,
1072+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL,
1073+ },
1074+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
1075+ WIPHY_VENDOR_CMD_NEED_RUNNING,
1076+ .doit = mt7915_vendor_wireless_ctrl,
1077+ .policy = wireless_ctrl_policy,
1078+ .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
1079 }
1080 };
1081
1082diff --git a/mt7915/vendor.h b/mt7915/vendor.h
developer05f3b2b2024-08-19 19:17:34 +08001083index 429b25b7..1a0139d7 100644
developer73e5a572022-04-19 10:21:20 +08001084--- a/mt7915/vendor.h
1085+++ b/mt7915/vendor.h
developer753619c2024-02-22 13:42:45 +08001086@@ -7,6 +7,48 @@
developer73e5a572022-04-19 10:21:20 +08001087 enum mtk_nl80211_vendor_subcmds {
1088 MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
1089 MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
1090+ MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
1091+ MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
1092+};
1093+
1094+enum mtk_capi_control_changed {
1095+ CAPI_RFEATURE_CHANGED = BIT(16),
1096+ CAPI_WIRELESS_CHANGED = BIT(17),
1097+};
1098+
1099+enum mtk_vendor_attr_wireless_ctrl {
1100+ MTK_VENDOR_ATTR_WIRELESS_CTRL_UNSPEC,
1101+
1102+ MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS,
1103+ MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA,
1104+ MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE,
1105+ MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA,
1106+ MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
1107+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
1108+ MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
1109+
1110+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA, /* reserve */
1111+ /* keep last */
1112+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL,
1113+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX =
1114+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
1115+};
1116+
1117+enum mtk_vendor_attr_rfeature_ctrl {
1118+ MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
1119+
1120+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI,
1121+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF,
1122+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG,
1123+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
1124+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
1125+ MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
1126+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
1127+
1128+ /* keep last */
1129+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
1130+ MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX =
1131+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL - 1
1132 };
1133
1134 enum mtk_vendor_attr_csi_ctrl {
1135--
developerbd9fa1e2023-10-16 11:04:00 +080011362.18.0
developer73e5a572022-04-19 10:21:20 +08001137