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