blob: e4bef963c3527ca353b0bc6326f1aaddf6161e8b [file] [log] [blame]
developer3fa816c2022-04-19 10:21:20 +08001From f438253052b9cea4ec1339b53a44224393b0ad9d Mon Sep 17 00:00:00 2001
2From: MeiChia Chiu <meichia.chiu@mediatek.com>
3Date: Fri, 21 Jan 2022 11:22:10 +0800
4Subject: [PATCH] mt76: certification patches
5
6Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
7---
8 mt76_connac_mcu.h | 1 +
9 mt7915/init.c | 7 +-
10 mt7915/mac.c | 23 +++
11 mt7915/main.c | 15 +-
12 mt7915/mcu.c | 466 +++++++++++++++++++++++++++++++++++++++++++
13 mt7915/mcu.h | 209 ++++++++++++++++++-
14 mt7915/mt7915.h | 13 ++
15 mt7915/mtk_debugfs.c | 7 +-
16 mt7915/vendor.c | 187 +++++++++++++++++
17 mt7915/vendor.h | 42 ++++
18 10 files changed, 964 insertions(+), 6 deletions(-)
19
20diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
21index f5acdf20..e0e5d10d 100644
22--- a/mt76_connac_mcu.h
23+++ b/mt76_connac_mcu.h
24@@ -994,6 +994,7 @@ enum {
25 MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
26 /* for vendor csi and air monitor */
27 MCU_EXT_CMD_SMESH_CTRL = 0xae,
28+ MCU_EXT_CMD_CERT_CFG = 0xb7,
29 MCU_EXT_CMD_CSI_CTRL = 0xc2,
30 };
31
32diff --git a/mt7915/init.c b/mt7915/init.c
33index c58f045f..d6156453 100644
34--- a/mt7915/init.c
35+++ b/mt7915/init.c
36@@ -369,12 +369,17 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
37 if (!phy->dev->dbdc_support)
38 wiphy->txq_memory_limit = 32 << 20; /* 32 MiB */
39
40- if (phy->mt76->cap.has_2ghz)
41+ if (phy->mt76->cap.has_2ghz) {
42+ phy->mt76->sband_2g.sband.ht_cap.ampdu_density =
43+ IEEE80211_HT_MPDU_DENSITY_4;
44 phy->mt76->sband_2g.sband.ht_cap.cap |=
45 IEEE80211_HT_CAP_LDPC_CODING |
46 IEEE80211_HT_CAP_MAX_AMSDU;
47+ }
48
49 if (phy->mt76->cap.has_5ghz) {
50+ phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
51+ IEEE80211_HT_MPDU_DENSITY_4;
52 phy->mt76->sband_5g.sband.ht_cap.cap |=
53 IEEE80211_HT_CAP_LDPC_CODING |
54 IEEE80211_HT_CAP_MAX_AMSDU;
55diff --git a/mt7915/mac.c b/mt7915/mac.c
56index a56f9be8..6637fa44 100644
57--- a/mt7915/mac.c
58+++ b/mt7915/mac.c
59@@ -7,6 +7,7 @@
60 #include "../dma.h"
61 #include "mac.h"
62 #include "mcu.h"
63+#include "vendor.h"
64
65 #define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2)
66
67@@ -2411,6 +2412,21 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)
68 }
69 }
70
71+#ifdef CONFIG_MTK_VENDOR
72+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta)
73+{
74+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
75+ struct mt7915_dev *dev = msta->vif->phy->dev;
76+ u32 *changed = data;
77+
78+ spin_lock_bh(&dev->sta_poll_lock);
79+ msta->changed |= *changed;
80+ if (list_empty(&msta->rc_list))
81+ list_add_tail(&msta->rc_list, &dev->sta_rc_list);
82+ spin_unlock_bh(&dev->sta_poll_lock);
83+}
84+#endif
85+
86 void mt7915_mac_sta_rc_work(struct work_struct *work)
87 {
88 struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
89@@ -2433,6 +2449,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
90 sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
91 vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
92
93+#ifdef CONFIG_MTK_VENDOR
94+ if (changed & CAPI_RFEATURE_CHANGED) {
95+ mt7915_mcu_set_rfeature_starec(&changed, dev, vif, sta);
96+ spin_lock_bh(&dev->sta_poll_lock);
97+ continue;
98+ }
99+#endif
100 if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED |
101 IEEE80211_RC_NSS_CHANGED |
102 IEEE80211_RC_BW_CHANGED))
103diff --git a/mt7915/main.c b/mt7915/main.c
104index 12de9e35..d628f768 100644
105--- a/mt7915/main.c
106+++ b/mt7915/main.c
107@@ -655,6 +655,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
108 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
109 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
110 bool ext_phy = mvif->phy != &dev->phy;
111+#ifdef CONFIG_MTK_VENDOR
112+ struct mt7915_phy *phy;
113+#endif
114 int ret, idx;
115
116 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
117@@ -680,7 +683,17 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
118 #ifdef CONFIG_MTK_VENDOR
119 mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
120 #endif
121- return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
122+ ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
123+ if (ret)
124+ return ret;
125+
126+#ifdef CONFIG_MTK_VENDOR
127+ if (dev->dbg.muru_onoff & MUMIMO_DL_CERT) {
128+ phy = mvif->mt76.band_idx ? mt7915_ext_phy(dev) : &dev->phy;
129+ mt7915_mcu_set_mimo(phy, 0);
130+ }
131+#endif
132+ return 0;
133 }
134
135 void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
136diff --git a/mt7915/mcu.c b/mt7915/mcu.c
137index 817298a1..e418742a 100644
138--- a/mt7915/mcu.c
139+++ b/mt7915/mcu.c
140@@ -3793,6 +3793,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
141
142 return 0;
143 }
144+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
145+{
146+ u8 mode, val;
147+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
148+ struct mt7915_dev *dev = mvif->phy->dev;
149+
150+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
151+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
152+
153+ switch (mode) {
154+ case RATE_PARAM_FIXED_OFDMA:
155+ if (val == 3) /* DL 20 and 80 */
156+ dev->dbg.muru_onoff = OFDMA_DL; /* Enable OFDMA DL only */
157+ else
158+ dev->dbg.muru_onoff = val;
159+ break;
160+ case RATE_PARAM_FIXED_MIMO:
161+ if (val == 0)
162+ dev->dbg.muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
163+ break;
164+ }
165+}
166+
167+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
168+ struct ieee80211_vif *vif, struct ieee80211_sta *sta)
169+{
170+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
171+ struct mt7915_vif *mvif = msta->vif;
172+ struct sta_rec_ra_fixed *ra;
173+ struct sk_buff *skb;
174+ struct tlv *tlv;
175+ u8 mode, val;
176+ int len = sizeof(struct sta_req_hdr) + sizeof(*ra);
177+
178+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
179+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
180+
181+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &msta->wcid, len);
182+ if (IS_ERR(skb))
183+ return;
184+
185+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
186+ ra = (struct sta_rec_ra_fixed *)tlv;
187+
188+ switch (mode) {
189+ case RATE_PARAM_FIXED_GI:
190+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_GI);
191+ ra->phy.sgi = val * 85;
192+ break;
193+ case RATE_PARAM_FIXED_HE_LTF:
194+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_HE_LTF);
195+ ra->phy.he_ltf = val * 85;
196+ break;
197+ case RATE_PARAM_FIXED_MCS:
198+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_MCS);
199+ ra->phy.mcs = val;
200+ break;
201+ }
202+
203+ mt76_mcu_skb_send_msg(&dev->mt76, skb,
204+ MCU_EXT_CMD(STA_REC_UPDATE), true);
205+}
206+
207+int mt7915_mcu_set_mu_prot_frame_th(struct mt7915_phy *phy, u32 val)
208+{
209+ struct mt7915_dev *dev = phy->dev;
210+ struct {
211+ __le32 cmd;
212+ __le32 threshold;
213+ } __packed req = {
214+ .cmd = cpu_to_le32(MURU_SET_PROT_FRAME_THR),
215+ .threshold = val,
216+ };
217+
218+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
219+ sizeof(req), false);
220+}
221+
222+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val)
223+{
224+ struct mt7915_dev *dev = phy->dev;
225+ struct {
226+ __le32 cmd;
227+ u8 override;
228+ } __packed req = {
229+ .cmd = cpu_to_le32(MURU_SET_CERT_MU_EDCA_OVERRIDE),
230+ .override = val,
231+ };
232+
233+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
234+ sizeof(req), false);
235+}
236+
237+int mt7915_mcu_set_muru_cfg(struct mt7915_phy *phy, struct mt7915_muru *muru)
238+{
239+ struct mt7915_dev *dev = phy->dev;
240+ struct {
241+ __le32 cmd;
242+ struct mt7915_muru muru;
243+ } __packed req = {
244+ .cmd = cpu_to_le32(MURU_SET_MANUAL_CFG),
245+ };
246+
247+ memcpy(&req.muru, muru, sizeof(struct mt7915_muru));
248+
249+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
250+ sizeof(req), false);
251+}
252+
253+int mt7915_set_muru_cfg(struct mt7915_phy *phy, u8 action, u8 val)
254+{
255+ struct mt7915_muru muru;
256+ struct mt7915_muru_dl *dl = &muru.dl;
257+ struct mt7915_muru_ul *ul = &muru.ul;
258+ struct mt7915_muru_comm *comm = &muru.comm;
259+
260+ memset(&muru, 0, sizeof(muru));
261+
262+ switch (action) {
263+ case MURU_DL_USER_CNT:
264+ dl->user_num = val;
265+ comm->ppdu_format |= MURU_PPDU_HE_MU;
266+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_DL;
267+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
268+ muru.cfg_dl = cpu_to_le32(MURU_USER_CNT);
269+ return mt7915_mcu_set_muru_cfg(phy, &muru);
270+ case MURU_UL_USER_CNT:
271+ ul->user_num = val;
272+ comm->ppdu_format |= MURU_PPDU_HE_TRIG;
273+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_UL;
274+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
275+ muru.cfg_ul = cpu_to_le32(MURU_USER_CNT);
276+ return mt7915_mcu_set_muru_cfg(phy, &muru);
277+ default:
278+ return 0;
279+ }
280+}
281+
282+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type)
283+{
284+ struct mt7915_dev *dev = phy->dev;
285+ struct {
286+ __le32 cmd;
287+ u8 enable_su;
288+ } __packed ppdu_type_req = {
289+ .cmd = cpu_to_le32(MURU_SET_SUTX),
290+ };
291+
292+ switch(ppdu_type) {
293+ case CAPI_SU:
294+ ppdu_type_req.enable_su = 1;
295+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
296+ &ppdu_type_req, sizeof(ppdu_type_req), false);
297+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, 0);
298+ break;
299+ case CAPI_MU:
300+ ppdu_type_req.enable_su = 0;
301+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
302+ &ppdu_type_req, sizeof(ppdu_type_req), false);
303+ break;
304+ default:
305+ break;
306+ }
307+}
308+
309+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt)
310+{
311+ struct mt7915_dev *dev = phy->dev;
312+ struct {
313+ __le32 cmd;
314+ u8 enable_su;
315+ } __packed nusers_ofdma_req = {
316+ .cmd = cpu_to_le32(MURU_SET_SUTX),
317+ .enable_su = 0,
318+ };
319+
320+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
321+ &nusers_ofdma_req, sizeof(nusers_ofdma_req), false);
322+
323+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
324+ mt7915_mcu_set_mu_prot_frame_th(phy, 9999);
325+ switch(type) {
326+ case MURU_UL_USER_CNT:
327+ mt7915_set_muru_cfg(phy, MURU_UL_USER_CNT, ofdma_user_cnt);
328+ break;
329+ case MURU_DL_USER_CNT:
330+ default:
331+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, ofdma_user_cnt);
332+ break;
333+ }
334+}
335+
336+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction)
337+{
338+#define MUMIMO_SET_FIXED_RATE 10
339+#define MUMIMO_SET_FIXED_GRP_RATE 11
340+#define MUMIMO_SET_FORCE_MU 12
341+ struct mt7915_dev *dev = phy->dev;
342+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
343+ struct {
344+ __le32 cmd;
345+ __le16 sub_cmd;
346+ __le16 disable_ra;
347+ } __packed fixed_rate_req = {
348+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
349+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FIXED_RATE),
350+ .disable_ra = cpu_to_le16(1),
351+ };
352+ struct {
353+ __le32 cmd;
354+ __le32 sub_cmd;
355+ struct {
356+ u8 user_cnt:2;
357+ u8 rsv:2;
358+ u8 ns0:1;
359+ u8 ns1:1;
360+ u8 ns2:1;
361+ u8 ns3:1;
362+
363+ __le16 wlan_id_user0;
364+ __le16 wlan_id_user1;
365+ __le16 wlan_id_user2;
366+ __le16 wlan_id_user3;
367+
368+ u8 dl_mcs_user0:4;
369+ u8 dl_mcs_user1:4;
370+ u8 dl_mcs_user2:4;
371+ u8 dl_mcs_user3:4;
372+
373+ u8 ul_mcs_user0:4;
374+ u8 ul_mcs_user1:4;
375+ u8 ul_mcs_user2:4;
376+ u8 ul_mcs_user3:4;
377+
378+ u8 ru_alloc;
379+ u8 cap;
380+ u8 gi;
381+ u8 dl_ul;
382+ } grp_rate_conf;
383+ } fixed_grp_rate_req = {
384+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
385+ .sub_cmd = cpu_to_le32(MUMIMO_SET_FIXED_GRP_RATE),
386+ .grp_rate_conf = {
387+ .user_cnt = 1,
388+ .ru_alloc = 134,
389+ .gi = 0,
390+ .cap = 1,
391+ .dl_ul = 0,
392+ .wlan_id_user0 = cpu_to_le16(1),
393+ .dl_mcs_user0 = 2,
394+ .wlan_id_user1 = cpu_to_le16(2),
395+ .dl_mcs_user1 = 2,
396+ },
397+ };
398+ struct {
399+ __le32 cmd;
400+ __le16 sub_cmd;
401+ bool force_mu;
402+ } __packed force_mu_req = {
403+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
404+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FORCE_MU),
405+ .force_mu = true,
406+ };
407+
408+ switch (chandef->width) {
409+ case NL80211_CHAN_WIDTH_20_NOHT:
410+ case NL80211_CHAN_WIDTH_20:
411+ fixed_grp_rate_req.grp_rate_conf.ru_alloc = 122;
412+ break;
413+ case NL80211_CHAN_WIDTH_80:
414+ default:
415+ break;
416+ }
417+
418+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
419+
420+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
421+ &fixed_rate_req, sizeof(fixed_rate_req), false);
422+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
423+ &fixed_grp_rate_req, sizeof(fixed_grp_rate_req), false);
424+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
425+ &force_mu_req, sizeof(force_mu_req), false);
426+}
427+
428+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
429+{
430+ struct mt7915_dev *dev = phy->dev;
431+ struct {
432+ __le32 cmd;
433+ u8 enable;
434+ } __packed req = {
435+ .cmd = cpu_to_le32(MURU_SET_20M_DYN_ALGO),
436+ .enable = enable,
437+ };
438+
439+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
440+ &req, sizeof(req), false);
441+}
442+
443+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type)
444+{
445+#define CFGINFO_CERT_CFG 4
446+ struct mt7915_dev *dev = phy->dev;
447+ struct {
448+ struct basic_info{
449+ u8 dbdc_idx;
450+ u8 rsv[3];
451+ __le32 tlv_num;
452+ u8 tlv_buf[0];
453+ } hdr;
454+ struct cert_cfg{
455+ __le16 tag;
456+ __le16 length;
457+ u8 cert_program;
458+ u8 rsv[3];
459+ } tlv;
460+ } req = {
461+ .hdr = {
462+ .dbdc_idx = phy != &dev->phy,
463+ .tlv_num = cpu_to_le32(1),
464+ },
465+ .tlv = {
466+ .tag = cpu_to_le16(CFGINFO_CERT_CFG),
467+ .length = cpu_to_le16(sizeof(struct cert_cfg)),
468+ .cert_program = type, /* 1: CAPI Enable */
469+ }
470+ };
471+
472+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CERT_CFG),
473+ &req, sizeof(req), false);
474+}
475+
476+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val)
477+{
478+#define BF_CMD_CFG_PHY 36
479+#define BF_PHY_SMTH_INTL_BYPASS 0
480+ struct mt7915_dev *dev = phy->dev;
481+ struct {
482+ u8 cmd_category_id;
483+ u8 action;
484+ u8 band_idx;
485+ u8 smthintbypass;
486+ u8 rsv[12];
487+ } req = {
488+ .cmd_category_id = BF_CMD_CFG_PHY,
489+ .action = BF_PHY_SMTH_INTL_BYPASS,
490+ .band_idx = phy != &dev->phy,
491+ .smthintbypass = val,
492+ };
493+
494+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
495+ &req, sizeof(req), false);
496+}
497+
498+int mt7915_mcu_set_bsrp_ctrl(struct mt7915_phy *phy, u16 interval,
499+ u16 ru_alloc, u32 ppdu_dur, u8 trig_flow, u8 ext_cmd)
500+{
501+ struct mt7915_dev *dev = phy->dev;
502+ struct {
503+ __le32 cmd;
504+ __le16 bsrp_interval;
505+ __le16 bsrp_ru_alloc;
506+ __le32 ppdu_duration;
507+ u8 trigger_flow;
508+ u8 ext_cmd_bsrp;
509+ } __packed req = {
510+ .cmd = cpu_to_le32(MURU_SET_BSRP_CTRL),
511+ .bsrp_interval = cpu_to_le16(interval),
512+ .bsrp_ru_alloc = cpu_to_le16(ru_alloc),
513+ .ppdu_duration = cpu_to_le32(ppdu_dur),
514+ .trigger_flow = trig_flow,
515+ .ext_cmd_bsrp = ext_cmd,
516+ };
517+
518+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
519+ sizeof(req), false);
520+}
521+
522+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num)
523+{
524+ struct mt7915_dev *dev = phy->dev;
525+ struct {
526+ __le32 cmd;
527+ u8 ack_policy;
528+ } __packed req = {
529+ .cmd = cpu_to_le32(MURU_SET_MU_DL_ACK_POLICY),
530+ .ack_policy = policy_num,
531+ };
532+
533+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
534+ sizeof(req), false);
535+}
536+
537+int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
538+ u8 v1, u8 v2, u8 v3)
539+{
540+ struct mt7915_dev *dev = phy->dev;
541+ struct {
542+ u8 cmd_category_id;
543+ u8 action;
544+ u8 read_clear;
545+ u8 vht_opt;
546+ u8 he_opt;
547+ u8 glo_opt;
548+ __le16 wlan_idx;
549+ u8 sound_interval;
550+ u8 sound_stop;
551+ u8 max_sound_sta;
552+ u8 tx_time;
553+ u8 mcs;
554+ bool ldpc;
555+ u8 inf;
556+ u8 rsv;
557+ } __packed req = {
558+ .cmd_category_id = BF_CMD_TXSND_INFO,
559+ .action = action,
560+ };
561+
562+ switch (action) {
563+ case BF_SND_CFG_OPT:
564+ req.vht_opt = v1;
565+ req.he_opt = v2;
566+ req.glo_opt = v3;
567+ break;
568+ default:
569+ return -EINVAL;
570+ }
571+
572+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
573+ sizeof(req), false);
574+}
575+
576+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type)
577+{
578+ struct mt7915_dev *dev = phy->dev;
579+ int ret = 0;
580+ struct {
581+ __le32 cmd;
582+ u8 trig_type;
583+ } __packed req = {
584+ .cmd = cpu_to_le32(MURU_SET_TRIG_TYPE),
585+ .trig_type = trig_type,
586+ };
587+
588+ if (enable) {
589+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
590+ sizeof(req), false);
591+ if (ret)
592+ return ret;
593+ }
594+
595+ switch (trig_type) {
596+ case CAPI_BASIC:
597+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 0, 0, enable);
598+ case CAPI_BRP:
599+ return mt7915_mcu_set_txbf_sound_info(phy, BF_SND_CFG_OPT,
600+ 0x0, 0x0, 0x1b);
601+ case CAPI_MU_BAR:
602+ return mt7915_mcu_set_mu_dl_ack_policy(phy,
603+ MU_DL_ACK_POLICY_MU_BAR);
604+ case CAPI_BSRP:
605+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 4, 0, enable);
606+ default:
607+ return 0;
608+ }
609+}
610 #endif
611
612 #ifdef MTK_DEBUG
613diff --git a/mt7915/mcu.h b/mt7915/mcu.h
614index a5e5afae..c15f89bf 100644
615--- a/mt7915/mcu.h
616+++ b/mt7915/mcu.h
617@@ -431,9 +431,13 @@ enum {
618 RATE_PARAM_FIXED = 3,
619 RATE_PARAM_MMPS_UPDATE = 5,
620 RATE_PARAM_FIXED_HE_LTF = 7,
621- RATE_PARAM_FIXED_MCS,
622+ RATE_PARAM_FIXED_MCS = 8,
623 RATE_PARAM_FIXED_GI = 11,
624 RATE_PARAM_AUTO = 20,
625+#ifdef CONFIG_MTK_VENDOR
626+ RATE_PARAM_FIXED_MIMO = 30,
627+ RATE_PARAM_FIXED_OFDMA = 31,
628+#endif
629 };
630
631 #define RATE_CFG_MCS GENMASK(3, 0)
632@@ -445,6 +449,9 @@ enum {
633 #define RATE_CFG_PHY_TYPE GENMASK(27, 24)
634 #define RATE_CFG_HE_LTF GENMASK(31, 28)
635
636+#define RATE_CFG_MODE GENMASK(15, 8)
637+#define RATE_CFG_VAL GENMASK(7, 0)
638+
639 enum {
640 THERMAL_PROTECT_PARAMETER_CTRL,
641 THERMAL_PROTECT_BASIC_INFO,
642@@ -574,5 +581,205 @@ struct csi_data {
643 #define OFDMA_UL BIT(1)
644 #define MUMIMO_DL BIT(2)
645 #define MUMIMO_UL BIT(3)
646+#define MUMIMO_DL_CERT BIT(4)
647+
648+
649+#ifdef CONFIG_MTK_VENDOR
650+struct mt7915_muru_comm {
651+ u8 ppdu_format;
652+ u8 sch_type;
653+ u8 band;
654+ u8 wmm_idx;
655+ u8 spe_idx;
656+ u8 proc_type;
657+};
658+
659+struct mt7915_muru_dl {
660+ u8 user_num;
661+ u8 tx_mode;
662+ u8 bw;
663+ u8 gi;
664+ u8 ltf;
665+ /* sigB */
666+ u8 mcs;
667+ u8 dcm;
668+ u8 cmprs;
669+
670+ u8 ru[8];
671+ u8 c26[2];
672+ u8 ack_policy;
673+
674+ struct {
675+ __le16 wlan_idx;
676+ u8 ru_alloc_seg;
677+ u8 ru_idx;
678+ u8 ldpc;
679+ u8 nss;
680+ u8 mcs;
681+ u8 mu_group_idx;
682+ u8 vht_groud_id;
683+ u8 vht_up;
684+ u8 he_start_stream;
685+ u8 he_mu_spatial;
686+ u8 ack_policy;
687+ __le16 tx_power_alpha;
688+ } usr[16];
689+};
690+
691+struct mt7915_muru_ul {
692+ u8 user_num;
693+
694+ /* UL TX */
695+ u8 trig_type;
696+ __le16 trig_cnt;
697+ __le16 trig_intv;
698+ u8 bw;
699+ u8 gi_ltf;
700+ __le16 ul_len;
701+ u8 pad;
702+ u8 trig_ta[ETH_ALEN];
703+ u8 ru[8];
704+ u8 c26[2];
705+
706+ struct {
707+ __le16 wlan_idx;
708+ u8 ru_alloc;
709+ u8 ru_idx;
710+ u8 ldpc;
711+ u8 nss;
712+ u8 mcs;
713+ u8 target_rssi;
714+ __le32 trig_pkt_size;
715+ } usr[16];
716+
717+ /* HE TB RX Debug */
718+ __le32 rx_hetb_nonsf_en_bitmap;
719+ __le32 rx_hetb_cfg[2];
720+
721+ /* DL TX */
722+ u8 ba_type;
723+};
724+
725+struct mt7915_muru {
726+ __le32 cfg_comm;
727+ __le32 cfg_dl;
728+ __le32 cfg_ul;
729+
730+ struct mt7915_muru_comm comm;
731+ struct mt7915_muru_dl dl;
732+ struct mt7915_muru_ul ul;
733+};
734+
735+#define MURU_PPDU_HE_TRIG BIT(2)
736+#define MURU_PPDU_HE_MU BIT(3)
737+
738+#define MURU_OFDMA_SCH_TYPE_DL BIT(0)
739+#define MURU_OFDMA_SCH_TYPE_UL BIT(1)
740+
741+/* Common Config */
742+#define MURU_COMM_PPDU_FMT BIT(0)
743+#define MURU_COMM_SCH_TYPE BIT(1)
744+#define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_SCH_TYPE)
745+
746+/* DL&UL User config*/
747+#define MURU_USER_CNT BIT(4)
748+
749+enum {
750+ CAPI_SU,
751+ CAPI_MU,
752+ CAPI_ER_SU,
753+ CAPI_TB,
754+ CAPI_LEGACY
755+};
756+
757+enum {
758+ CAPI_BASIC,
759+ CAPI_BRP,
760+ CAPI_MU_BAR,
761+ CAPI_MU_RTS,
762+ CAPI_BSRP,
763+ CAPI_GCR_MU_BAR,
764+ CAPI_BQRP,
765+ CAPI_NDP_FRP
766+};
767+
768+enum {
769+ MURU_SET_BSRP_CTRL = 1,
770+ MURU_SET_SUTX = 16,
771+ MURU_SET_MUMIMO_CTRL = 17,
772+ MURU_SET_MANUAL_CFG = 100,
773+ MURU_SET_MU_DL_ACK_POLICY = 200,
774+ MURU_SET_TRIG_TYPE = 201,
775+ MURU_SET_20M_DYN_ALGO = 202,
776+ MURU_SET_PROT_FRAME_THR = 204,
777+ MURU_SET_CERT_MU_EDCA_OVERRIDE = 205,
778+};
779+
780+enum {
781+ MU_DL_ACK_POLICY_MU_BAR = 3,
782+ MU_DL_ACK_POLICY_TF_FOR_ACK = 4,
783+ MU_DL_ACK_POLICY_SU_BAR = 5,
784+};
785+
786+enum {
787+ BF_SOUNDING_OFF = 0,
788+ BF_SOUNDING_ON,
789+ BF_DATA_PACKET_APPLY,
790+ BF_PFMU_MEM_ALLOCATE,
791+ BF_PFMU_MEM_RELEASE,
792+ BF_PFMU_TAG_READ,
793+ BF_PFMU_TAG_WRITE,
794+ BF_PROFILE_READ,
795+ BF_PROFILE_WRITE,
796+ BF_PN_READ,
797+ BF_PN_WRITE,
798+ BF_PFMU_MEM_ALLOC_MAP_READ,
799+ BF_AID_SET,
800+ BF_STA_REC_READ,
801+ BF_PHASE_CALIBRATION,
802+ BF_IBF_PHASE_COMP,
803+ BF_LNA_GAIN_CONFIG,
804+ BF_PROFILE_WRITE_20M_ALL,
805+ BF_APCLIENT_CLUSTER,
806+ BF_AWARE_CTRL,
807+ BF_HW_ENABLE_STATUS_UPDATE,
808+ BF_REPT_CLONED_STA_TO_NORMAL_STA,
809+ BF_GET_QD,
810+ BF_BFEE_HW_CTRL,
811+ BF_PFMU_SW_TAG_WRITE,
812+ BF_MOD_EN_CTRL,
813+ BF_DYNSND_EN_INTR,
814+ BF_DYNSND_CFG_DMCS_TH,
815+ BF_DYNSND_EN_PFID_INTR,
816+ BF_CONFIG,
817+ BF_PFMU_DATA_WRITE,
818+ BF_FBRPT_DBG_INFO_READ,
819+ BF_CMD_TXSND_INFO,
820+ BF_CMD_PLY_INFO,
821+ BF_CMD_MU_METRIC,
822+ BF_CMD_TXCMD,
823+ BF_CMD_CFG_PHY,
824+ BF_CMD_SND_CNT,
825+ BF_CMD_MAX
826+};
827+
828+enum {
829+ BF_SND_READ_INFO = 0,
830+ BF_SND_CFG_OPT,
831+ BF_SND_CFG_INTV,
832+ BF_SND_STA_STOP,
833+ BF_SND_CFG_MAX_STA,
834+ BF_SND_CFG_BFRP,
835+ BF_SND_CFG_INF
836+};
837+
838+enum {
839+ MURU_UPDATE = 0,
840+ MURU_DL_USER_CNT,
841+ MURU_UL_USER_CNT,
842+ MURU_DL_INIT,
843+ MURU_UL_INIT,
844+};
845+#endif
846
847 #endif
848diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
849index 56057ace..ad4e20dd 100644
850--- a/mt7915/mt7915.h
851+++ b/mt7915/mt7915.h
852@@ -664,6 +664,19 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
853 #endif
854
855 #ifdef CONFIG_MTK_VENDOR
856+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta);
857+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
858+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
859+ struct ieee80211_vif *vif, struct ieee80211_sta *sta);
860+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type);
861+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num);
862+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type);
863+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt);
864+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
865+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable);
866+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val);
867+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type);
868+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val);
869 void mt7915_vendor_register(struct mt7915_phy *phy);
870 int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
871 u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
872diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
873index 6c48f115..03de46a9 100644
874--- a/mt7915/mtk_debugfs.c
875+++ b/mt7915/mtk_debugfs.c
876@@ -2460,7 +2460,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
877
878 *val = dev->dbg.muru_onoff;
879
880- printk("mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
881+ printk("cert mumimo dl:%d, mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
882+ !!(dev->dbg.muru_onoff & MUMIMO_DL_CERT),
883 !!(dev->dbg.muru_onoff & MUMIMO_UL),
884 !!(dev->dbg.muru_onoff & MUMIMO_DL),
885 !!(dev->dbg.muru_onoff & OFDMA_UL),
886@@ -2473,8 +2474,8 @@ static int mt7915_muru_onoff_set(void *data, u64 val)
887 {
888 struct mt7915_dev *dev = data;
889
890- if (val > 15) {
891- printk("Wrong value! The value is between 0 ~ 15.\n");
892+ if (val > 31) {
893+ printk("Wrong value! The value is between 0 ~ 31.\n");
894 goto exit;
895 }
896
897diff --git a/mt7915/vendor.c b/mt7915/vendor.c
898index b94d787e..7456c577 100644
899--- a/mt7915/vendor.c
900+++ b/mt7915/vendor.c
901@@ -22,6 +22,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = {
902 [MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
903 };
904
905+static const struct nla_policy
906+wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
907+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
908+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA] = {.type = NLA_U8 },
909+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
910+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
911+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
912+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
913+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA] = {.type = NLA_U8 },
914+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
915+};
916+
917+static const struct nla_policy
918+rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
919+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
920+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
921+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
922+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
923+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
924+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
925+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
926+};
927+
928 struct csi_null_tone {
929 u8 start;
930 u8 end;
931@@ -777,6 +800,148 @@ mt7915_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
932 return len + 1;
933 }
934
935+static int mt7915_vendor_rfeature_ctrl(struct wiphy *wiphy,
936+ struct wireless_dev *wdev,
937+ const void *data,
938+ int data_len)
939+{
940+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
941+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
942+ struct mt7915_dev *dev = phy->dev;
943+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL];
944+ int err;
945+ u32 val;
946+
947+ err = nla_parse(tb, MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX, data, data_len,
948+ rfeature_ctrl_policy, NULL);
949+ if (err)
950+ return err;
951+
952+ val = CAPI_RFEATURE_CHANGED;
953+
954+ if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]) {
955+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_GI)|
956+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]));
957+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
958+ ieee80211_queue_work(hw, &dev->rc_work);
959+ }
960+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]) {
961+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_HE_LTF)|
962+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]));
963+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
964+ ieee80211_queue_work(hw, &dev->rc_work);
965+ }
966+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG]) {
967+ u8 enable, trig_type;
968+ int rem;
969+ struct nlattr *cur;
970+
971+ nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG], rem) {
972+ switch(nla_type(cur)) {
973+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN:
974+ enable = nla_get_u8(cur);
975+ break;
976+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE:
977+ trig_type = nla_get_u8(cur);
978+ break;
979+ default:
980+ return -EINVAL;
981+ };
982+ }
983+
984+ err = mt7915_mcu_set_rfeature_trig_type(phy, enable, trig_type);
985+ if (err)
986+ return err;
987+ }
988+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]) {
989+ u8 ack_policy;
990+
991+ ack_policy = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]);
992+#define HE_TB_PPDU_ACK 4
993+ switch (ack_policy) {
994+ case HE_TB_PPDU_ACK:
995+ return mt7915_mcu_set_mu_dl_ack_policy(phy, ack_policy);
996+ default:
997+ return 0;
998+ }
999+ }
1000+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]) {
1001+ u8 trig_txbf;
1002+
1003+ trig_txbf = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]);
1004+ /* CAPI only issues trig_txbf=disable */
1005+ }
1006+
1007+ return 0;
1008+}
1009+
1010+static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
1011+ struct wireless_dev *wdev,
1012+ const void *data,
1013+ int data_len)
1014+{
1015+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1016+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
1017+ struct mt7915_dev *dev = phy->dev;
1018+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL];
1019+ int err;
1020+ u8 val8;
1021+ u16 val16;
1022+ u32 val32;
1023+
1024+ err = nla_parse(tb, MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, data, data_len,
1025+ wireless_ctrl_policy, NULL);
1026+ if (err)
1027+ return err;
1028+
1029+ val32 = CAPI_WIRELESS_CHANGED;
1030+
1031+ if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]) {
1032+ val32 &= ~CAPI_WIRELESS_CHANGED;
1033+ val32 |= CAPI_RFEATURE_CHANGED |
1034+ FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MCS) |
1035+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]));
1036+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val32);
1037+ ieee80211_queue_work(hw, &dev->rc_work);
1038+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]) {
1039+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]);
1040+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_OFDMA) |
1041+ FIELD_PREP(RATE_CFG_VAL, val8);
1042+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1043+ mt7915_set_wireless_vif, &val32);
1044+ if (val8 == 3) /* DL20and80 */
1045+ mt7915_mcu_set_dynalgo(phy, 1); /* Enable dynamic algo */
1046+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]) {
1047+ val16 = nla_get_u16(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]);
1048+ hw->max_tx_aggregation_subframes = val16;
1049+ hw->max_rx_aggregation_subframes = val16;
1050+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]) {
1051+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]);
1052+ mt7915_mcu_set_mu_edca(phy, val8);
1053+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]) {
1054+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]);
1055+ mt7915_mcu_set_ppdu_tx_type(phy, val8);
1056+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]) {
1057+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]);
1058+ if (FIELD_GET(OFDMA_UL, dev->dbg.muru_onoff) == 1)
1059+ mt7915_mcu_set_nusers_ofdma(phy, MURU_UL_USER_CNT, val8);
1060+ else
1061+ mt7915_mcu_set_nusers_ofdma(phy, MURU_DL_USER_CNT, val8);
1062+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]) {
1063+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]);
1064+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MIMO) |
1065+ FIELD_PREP(RATE_CFG_VAL, val8);
1066+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1067+ mt7915_set_wireless_vif, &val32);
1068+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) {
1069+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
1070+ mt7915_mcu_set_cert(phy, val8); /* Cert Enable for OMI */
1071+ mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
1072+ }
1073+
1074+ return 0;
1075+}
1076+
1077 static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
1078 {
1079 .info = {
1080@@ -801,6 +966,28 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
1081 .dumpit = mt7915_vendor_amnt_ctrl_dump,
1082 .policy = amnt_ctrl_policy,
1083 .maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
1084+ },
1085+ {
1086+ .info = {
1087+ .vendor_id = MTK_NL80211_VENDOR_ID,
1088+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL,
1089+ },
1090+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
1091+ WIPHY_VENDOR_CMD_NEED_RUNNING,
1092+ .doit = mt7915_vendor_rfeature_ctrl,
1093+ .policy = rfeature_ctrl_policy,
1094+ .maxattr = MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX,
1095+ },
1096+ {
1097+ .info = {
1098+ .vendor_id = MTK_NL80211_VENDOR_ID,
1099+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL,
1100+ },
1101+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
1102+ WIPHY_VENDOR_CMD_NEED_RUNNING,
1103+ .doit = mt7915_vendor_wireless_ctrl,
1104+ .policy = wireless_ctrl_policy,
1105+ .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
1106 }
1107 };
1108
1109diff --git a/mt7915/vendor.h b/mt7915/vendor.h
1110index 976817f3..1b08321c 100644
1111--- a/mt7915/vendor.h
1112+++ b/mt7915/vendor.h
1113@@ -6,6 +6,48 @@
1114 enum mtk_nl80211_vendor_subcmds {
1115 MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
1116 MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
1117+ MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
1118+ MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
1119+};
1120+
1121+enum mtk_capi_control_changed {
1122+ CAPI_RFEATURE_CHANGED = BIT(16),
1123+ CAPI_WIRELESS_CHANGED = BIT(17),
1124+};
1125+
1126+enum mtk_vendor_attr_wireless_ctrl {
1127+ MTK_VENDOR_ATTR_WIRELESS_CTRL_UNSPEC,
1128+
1129+ MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS,
1130+ MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA,
1131+ MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE,
1132+ MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA,
1133+ MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
1134+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
1135+ MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
1136+
1137+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA, /* reserve */
1138+ /* keep last */
1139+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL,
1140+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX =
1141+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
1142+};
1143+
1144+enum mtk_vendor_attr_rfeature_ctrl {
1145+ MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
1146+
1147+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI,
1148+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF,
1149+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG,
1150+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
1151+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
1152+ MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
1153+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
1154+
1155+ /* keep last */
1156+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
1157+ MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX =
1158+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL - 1
1159 };
1160
1161 enum mtk_vendor_attr_csi_ctrl {
1162--
11632.18.0
1164