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