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