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