blob: 3048405501890edac8170639ccd88675bfac65d3 [file] [log] [blame]
developer1a173672023-12-21 14:49:33 +08001From 05cf83b4947264a8afca95116afd98cb4519a9d5 Mon Sep 17 00:00:00 2001
2From: Howard Hsu <howard-yh.hsu@mediatek.com>
3Date: Tue, 3 Jan 2023 09:42:07 +0800
4Subject: [PATCH 1030/1041] mtk: wifi: mt76: mt7996: support BF/MIMO debug
5 commands
6
7This commit includes the following commands:
81. starec_bf_read
92. txbf_snd_info: start/stop sounding and set sounding period
103. fbkRptInfo
114. fix muru rate
12
13Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
14
15fix the wrong wlan_idx for user3
16
17Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
18---
19 mt7996/mcu.c | 5 +
20 mt7996/mcu.h | 4 +
21 mt7996/mt7996.h | 5 +
22 mt7996/mtk_debugfs.c | 120 +++++++++
23 mt7996/mtk_mcu.c | 626 +++++++++++++++++++++++++++++++++++++++++++
24 mt7996/mtk_mcu.h | 342 +++++++++++++++++++++++
25 6 files changed, 1102 insertions(+)
26
27diff --git a/mt7996/mcu.c b/mt7996/mcu.c
28index 726d2adf..d3dab186 100644
29--- a/mt7996/mcu.c
30+++ b/mt7996/mcu.c
31@@ -741,6 +741,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
32 case MCU_UNI_EVENT_TESTMODE_CTRL:
33 mt7996_tm_rf_test_event(dev, skb);
34 break;
35+#endif
36+#if defined CONFIG_NL80211_TESTMODE || defined CONFIG_MTK_DEBUG
37+ case MCU_UNI_EVENT_BF:
38+ mt7996_mcu_rx_bf_event(dev, skb);
39+ break;
40 #endif
41 default:
42 break;
43diff --git a/mt7996/mcu.h b/mt7996/mcu.h
44index 34fdfb26..347893c8 100644
45--- a/mt7996/mcu.h
46+++ b/mt7996/mcu.h
47@@ -770,8 +770,12 @@ enum {
48
49 enum {
50 BF_SOUNDING_ON = 1,
51+ BF_PFMU_TAG_READ = 5,
52+ BF_STA_REC_READ = 11,
53 BF_HW_EN_UPDATE = 17,
54 BF_MOD_EN_CTRL = 20,
55+ BF_FBRPT_DBG_INFO_READ = 23,
56+ BF_TXSND_INFO = 24,
57 };
58
59 enum {
60diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
61index 71602b9b..a321e8e8 100644
62--- a/mt7996/mt7996.h
63+++ b/mt7996/mt7996.h
64@@ -809,6 +809,11 @@ int mt7996_mcu_muru_dbg_info(struct mt7996_dev *dev, u16 item, u8 val);
65 int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
66 void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
67 int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev);
68+int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx);
69+void mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb);
70+int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val);
71+int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para);
72+int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para);
73 #endif
74
75 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
76diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
77index e1689605..938da645 100644
78--- a/mt7996/mtk_debugfs.c
79+++ b/mt7996/mtk_debugfs.c
80@@ -2798,6 +2798,117 @@ static int mt7996_rx_counters(struct seq_file *s, void *data)
81 return 0;
82 }
83
84+static int
85+mt7996_starec_bf_read_set(void *data, u64 wlan_idx)
86+{
87+ struct mt7996_phy *phy = data;
88+
89+ return mt7996_mcu_set_txbf_internal(phy, BF_STA_REC_READ, wlan_idx);
90+}
91+DEFINE_DEBUGFS_ATTRIBUTE(fops_starec_bf_read, NULL,
92+ mt7996_starec_bf_read_set, "%lld\n");
93+
94+static ssize_t
95+mt7996_bf_txsnd_info_set(struct file *file,
96+ const char __user *user_buf,
97+ size_t count, loff_t *ppos)
98+{
99+ struct mt7996_phy *phy = file->private_data;
100+ char buf[40];
101+ int ret;
102+
103+ if (count >= sizeof(buf))
104+ return -EINVAL;
105+
106+ if (copy_from_user(buf, user_buf, count))
107+ return -EFAULT;
108+
109+ if (count && buf[count - 1] == '\n')
110+ buf[count - 1] = '\0';
111+ else
112+ buf[count] = '\0';
113+
114+ ret = mt7996_mcu_set_txbf_snd_info(phy, buf);
115+
116+ if (ret) return -EFAULT;
117+
118+ return count;
119+}
120+
121+static const struct file_operations fops_bf_txsnd_info = {
122+ .write = mt7996_bf_txsnd_info_set,
123+ .read = NULL,
124+ .open = simple_open,
125+ .llseek = default_llseek,
126+};
127+
128+static int
129+mt7996_bf_fbk_rpt_set(void *data, u64 wlan_idx)
130+{
131+ struct mt7996_phy *phy = data;
132+
133+ return mt7996_mcu_set_txbf_internal(phy, BF_FBRPT_DBG_INFO_READ, wlan_idx);
134+}
135+DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_fbk_rpt, NULL,
136+ mt7996_bf_fbk_rpt_set, "%lld\n");
137+
138+static int
139+mt7996_bf_pfmu_tag_read_set(void *data, u64 wlan_idx)
140+{
141+ struct mt7996_phy *phy = data;
142+
143+ return mt7996_mcu_set_txbf_internal(phy, BF_PFMU_TAG_READ, wlan_idx);
144+}
145+DEFINE_DEBUGFS_ATTRIBUTE(fops_bf_pfmu_tag_read, NULL,
146+ mt7996_bf_pfmu_tag_read_set, "%lld\n");
147+
148+static int
149+mt7996_muru_fixed_rate_set(void *data, u64 val)
150+{
151+ struct mt7996_dev *dev = data;
152+
153+ return mt7996_mcu_set_muru_fixed_rate_enable(dev, UNI_CMD_MURU_FIXED_RATE_CTRL,
154+ val);
155+}
156+DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_fixed_rate_enable, NULL,
157+ mt7996_muru_fixed_rate_set, "%lld\n");
158+
159+static ssize_t
160+mt7996_muru_fixed_rate_parameter_set(struct file *file,
161+ const char __user *user_buf,
162+ size_t count, loff_t *ppos)
163+{
164+ struct mt7996_dev *dev = file->private_data;
165+ char buf[40];
166+ int ret;
167+
168+ if (count >= sizeof(buf))
169+ return -EINVAL;
170+
171+ if (copy_from_user(buf, user_buf, count))
172+ return -EFAULT;
173+
174+ if (count && buf[count - 1] == '\n')
175+ buf[count - 1] = '\0';
176+ else
177+ buf[count] = '\0';
178+
179+
180+ ret = mt7996_mcu_set_muru_fixed_rate_parameter(dev, UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
181+ buf);
182+
183+ if (ret) return -EFAULT;
184+
185+ return count;
186+}
187+
188+static const struct file_operations fops_muru_fixed_group_rate = {
189+ .write = mt7996_muru_fixed_rate_parameter_set,
190+ .read = NULL,
191+ .open = simple_open,
192+ .llseek = default_llseek,
193+};
194+
195 int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
196 {
197 struct mt7996_dev *dev = phy->dev;
198@@ -2883,6 +2994,15 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
199 debugfs_create_file("sr_stats", 0400, dir, phy, &mt7996_sr_stats_fops);
200 debugfs_create_file("sr_scene_cond", 0400, dir, phy, &mt7996_sr_scene_cond_fops);
201
202+ debugfs_create_file("muru_fixed_rate_enable", 0600, dir, dev,
203+ &fops_muru_fixed_rate_enable);
204+ debugfs_create_file("muru_fixed_group_rate", 0600, dir, dev,
205+ &fops_muru_fixed_group_rate);
206+ debugfs_create_file("bf_txsnd_info", 0600, dir, phy, &fops_bf_txsnd_info);
207+ debugfs_create_file("bf_starec_read", 0600, dir, phy, &fops_starec_bf_read);
208+ debugfs_create_file("bf_fbk_rpt", 0600, dir, phy, &fops_bf_fbk_rpt);
209+ debugfs_create_file("pfmu_tag_read", 0600, dir, phy, &fops_bf_pfmu_tag_read);
210+
211 return 0;
212 }
213
214diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
215index ea4e5bf2..67419cd9 100644
216--- a/mt7996/mtk_mcu.c
217+++ b/mt7996/mtk_mcu.c
218@@ -280,4 +280,630 @@ int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev)
219 return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(CHIP_CONFIG), &req,
220 sizeof(req), true);
221 }
222+
223+static struct tlv *
224+__mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)
225+{
226+ struct tlv *ptlv, tlv = {
227+ .tag = cpu_to_le16(tag),
228+ .len = cpu_to_le16(len),
229+ };
230+
231+ ptlv = skb_put(skb, len);
232+ memcpy(ptlv, &tlv, sizeof(tlv));
233+
234+ return ptlv;
235+}
236+
237+int mt7996_mcu_set_txbf_internal(struct mt7996_phy *phy, u8 action, int idx)
238+{
239+ struct mt7996_dev *dev = phy->dev;
240+#define MT7996_MTK_BF_MAX_SIZE sizeof(struct bf_starec_read)
241+ struct uni_header hdr;
242+ struct sk_buff *skb;
243+ struct tlv *tlv;
244+ int len = sizeof(hdr) + MT7996_MTK_BF_MAX_SIZE;
245+
246+ memset(&hdr, 0, sizeof(hdr));
247+
248+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);
249+ if (!skb)
250+ return -ENOMEM;
251+
252+ skb_put_data(skb, &hdr, sizeof(hdr));
253+
254+ switch (action) {
255+ case BF_PFMU_TAG_READ: {
256+ struct bf_pfmu_tag *req;
257+
258+ tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
259+ req = (struct bf_pfmu_tag *)tlv;
260+#define BFER 1
261+ req->pfmu_id = idx;
262+ req->bfer = BFER;
263+ req->band_idx = phy->mt76->band_idx;
264+ break;
265+ }
266+ case BF_STA_REC_READ: {
267+ struct bf_starec_read *req;
268+
269+ tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
270+ req = (struct bf_starec_read *)tlv;
271+ req->wlan_idx = idx;
272+ break;
273+ }
274+ case BF_FBRPT_DBG_INFO_READ: {
275+ struct bf_fbk_rpt_info *req;
276+
277+ if (idx != 0) {
278+ dev_info(dev->mt76.dev, "Invalid input");
279+ return 0;
280+ }
281+
282+ tlv = __mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req));
283+ req = (struct bf_fbk_rpt_info *)tlv;
284+ req->action = idx;
285+ req->band_idx = phy->mt76->band_idx;
286+ break;
287+ }
288+ default:
289+ return -EINVAL;
290+ }
291+
292+ return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb, MCU_WM_UNI_CMD(BF), false);
293+}
294+
295+int mt7996_mcu_set_txbf_snd_info(struct mt7996_phy *phy, void *para)
296+{
297+ char *buf = (char *)para;
298+ __le16 input[5] = {0};
299+ u8 recv_arg = 0;
300+ struct bf_txsnd_info *req;
301+ struct uni_header hdr;
302+ struct sk_buff *skb;
303+ struct tlv *tlv;
304+ int len = sizeof(hdr) + MT7996_MTK_BF_MAX_SIZE;
305+
306+ memset(&hdr, 0, sizeof(hdr));
307+
308+ skb = mt76_mcu_msg_alloc(&phy->dev->mt76, NULL, len);
309+ if (!skb)
310+ return -ENOMEM;
311+
312+ skb_put_data(skb, &hdr, sizeof(hdr));
313+
314+ recv_arg = sscanf(buf, "%hx:%hx:%hx:%hx:%hx", &input[0], &input[1], &input[2],
315+ &input[3], &input[4]);
316+
317+ if (!recv_arg)
318+ return -EINVAL;
319+
320+ tlv = __mt7996_mcu_add_uni_tlv(skb, BF_TXSND_INFO, sizeof(*req));
321+ req = (struct bf_txsnd_info *)tlv;
322+ req->action = input[0];
323+
324+ switch (req->action) {
325+ case BF_SND_READ_INFO: {
326+ req->read_clr = input[1];
327+ break;
328+ }
329+ case BF_SND_CFG_OPT: {
330+ req->vht_opt = input[1];
331+ req->he_opt = input[2];
332+ req->glo_opt = input[3];
333+ break;
334+ }
335+ case BF_SND_CFG_INTV: {
336+ req->wlan_idx = input[1];
337+ req->snd_intv = input[2];
338+ break;
339+ }
340+ case BF_SND_STA_STOP: {
341+ req->wlan_idx = input[1];
342+ req->snd_stop = input[2];
343+ break;
344+ }
345+ case BF_SND_CFG_MAX_STA: {
346+ req->max_snd_stas = input[1];
347+ break;
348+ }
349+ case BF_SND_CFG_BFRP: {
350+ req->man = input[1];
351+ req->tx_time = input[2];
352+ req->mcs = input[3];
353+ req->ldpc = input[4];
354+ break;
355+ }
356+ case BF_SND_CFG_INF: {
357+ req->inf = input[1];
358+ break;
359+ }
360+ case BF_SND_CFG_TXOP_SND: {
361+ req->man = input[1];
362+ req->ac_queue = input[2];
363+ req->sxn_protect = input[3];
364+ req->direct_fbk = input[4];
365+ break;
366+ }
367+ default:
368+ return -EINVAL;
369+ }
370+
371+ return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb, MCU_WM_UNI_CMD(BF), false);
372+}
373+
374+void
375+mt7996_mcu_rx_bf_event(struct mt7996_dev *dev, struct sk_buff *skb)
376+{
377+#define HE_MODE 3
378+ struct mt7996_mcu_bf_basic_event *event;
379+
380+ event = (struct mt7996_mcu_bf_basic_event *)skb->data;
381+
382+ dev_info(dev->mt76.dev, " bf_event tag = %d\n", event->tag);
383+
384+ switch (event->tag) {
385+ case UNI_EVENT_BF_PFMU_TAG: {
386+
387+ struct mt7996_pfmu_tag_event *tag;
388+ u32 *raw_t1, *raw_t2;
389+
390+ tag = (struct mt7996_pfmu_tag_event *) skb->data;
391+
392+ raw_t1 = (u32 *)&tag->t1;
393+ raw_t2 = (u32 *)&tag->t2;
394+
395+ dev_info(dev->mt76.dev, "=================== TXBf Profile Tag1 Info ==================\n");
396+ dev_info(dev->mt76.dev,
397+ "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
398+ raw_t1[0], raw_t1[1], raw_t1[2]);
399+ dev_info(dev->mt76.dev,
400+ "DW4 = 0x%08x, DW5 = 0x%08x, DW6 = 0x%08x\n\n",
401+ raw_t1[3], raw_t1[4], raw_t1[5]);
402+ dev_info(dev->mt76.dev, "PFMU ID = %d Invalid status = %d\n",
403+ tag->t1.pfmu_idx, tag->t1.invalid_prof);
404+ dev_info(dev->mt76.dev, "iBf/eBf = %d\n\n", tag->t1.ebf);
405+ dev_info(dev->mt76.dev, "DBW = %d\n", tag->t1.data_bw);
406+ dev_info(dev->mt76.dev, "SU/MU = %d\n", tag->t1.is_mu);
407+ dev_info(dev->mt76.dev,
408+ "nrow = %d, ncol = %d, ng = %d, LM = %d, CodeBook = %d MobCalEn = %d\n",
409+ tag->t1.nr, tag->t1.nc, tag->t1.ngroup, tag->t1.lm, tag->t1.codebook,
410+ tag->t1.mob_cal_en);
411+
412+ if (tag->t1.lm <= HE_MODE) {
413+ dev_info(dev->mt76.dev, "RU start = %d, RU end = %d\n",
414+ tag->t1.field.ru_start_id, tag->t1.field.ru_end_id);
415+ } else {
416+ dev_info(dev->mt76.dev, "PartialBW = %d\n",
417+ tag->t1.bw_info.partial_bw_info);
418+ }
419+
420+ dev_info(dev->mt76.dev, "Mem Col1 = %d, Mem Row1 = %d, Mem Col2 = %d, Mem Row2 = %d\n",
421+ tag->t1.col_id1, tag->t1.row_id1, tag->t1.col_id2, tag->t1.row_id2);
422+ dev_info(dev->mt76.dev, "Mem Col3 = %d, Mem Row3 = %d, Mem Col4 = %d, Mem Row4 = %d\n\n",
423+ tag->t1.col_id3, tag->t1.row_id3, tag->t1.col_id4, tag->t1.row_id4);
424+ dev_info(dev->mt76.dev,
425+ "STS0_SNR = 0x%02x, STS1_SNR = 0x%02x, STS2_SNR = 0x%02x, STS3_SNR = 0x%02x\n",
426+ tag->t1.snr_sts0, tag->t1.snr_sts1, tag->t1.snr_sts2, tag->t1.snr_sts3);
427+ dev_info(dev->mt76.dev,
428+ "STS4_SNR = 0x%02x, STS5_SNR = 0x%02x, STS6_SNR = 0x%02x, STS7_SNR = 0x%02x\n",
429+ tag->t1.snr_sts4, tag->t1.snr_sts5, tag->t1.snr_sts6, tag->t1.snr_sts7);
430+ dev_info(dev->mt76.dev, "=============================================================\n");
431+
432+ dev_info(dev->mt76.dev, "=================== TXBf Profile Tag2 Info ==================\n");
433+ dev_info(dev->mt76.dev,
434+ "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
435+ raw_t2[0], raw_t2[1], raw_t2[2]);
436+ dev_info(dev->mt76.dev,
437+ "DW3 = 0x%08x, DW4 = 0x%08x, DW5 = 0x%08x\n\n",
438+ raw_t2[3], raw_t2[4], raw_t2[5]);
439+ dev_info(dev->mt76.dev, "Smart antenna ID = 0x%x, SE index = %d\n",
440+ tag->t2.smart_ant, tag->t2.se_idx);
441+ dev_info(dev->mt76.dev, "Timeout = 0x%x\n", tag->t2.ibf_timeout);
442+ dev_info(dev->mt76.dev, "Desired BW = %d, Desired Ncol = %d, Desired Nrow = %d\n",
443+ tag->t2.ibf_data_bw, tag->t2.ibf_nc, tag->t2.ibf_nr);
444+ dev_info(dev->mt76.dev, "Desired RU Allocation = %d\n", tag->t2.ibf_ru);
445+ dev_info(dev->mt76.dev, "Mobility DeltaT = %d, Mobility LQ = %d\n",
446+ tag->t2.mob_delta_t, tag->t2.mob_lq_result);
447+ dev_info(dev->mt76.dev, "=============================================================\n");
448+ break;
449+ }
450+ case UNI_EVENT_BF_STAREC: {
451+
452+ struct mt7996_mcu_bf_starec_read *r;
453+
454+ r = (struct mt7996_mcu_bf_starec_read *)skb->data;
455+ dev_info(dev->mt76.dev, "=================== BF StaRec ===================\n"
456+ "rStaRecBf.u2PfmuId = %d\n"
457+ "rStaRecBf.fgSU_MU = %d\n"
458+ "rStaRecBf.u1TxBfCap = %d\n"
459+ "rStaRecBf.ucSoundingPhy = %d\n"
460+ "rStaRecBf.ucNdpaRate = %d\n"
461+ "rStaRecBf.ucNdpRate = %d\n"
462+ "rStaRecBf.ucReptPollRate= %d\n"
463+ "rStaRecBf.ucTxMode = %d\n"
464+ "rStaRecBf.ucNc = %d\n"
465+ "rStaRecBf.ucNr = %d\n"
466+ "rStaRecBf.ucCBW = %d\n"
467+ "rStaRecBf.ucMemRequire20M = %d\n"
468+ "rStaRecBf.ucMemRow0 = %d\n"
469+ "rStaRecBf.ucMemCol0 = %d\n"
470+ "rStaRecBf.ucMemRow1 = %d\n"
471+ "rStaRecBf.ucMemCol1 = %d\n"
472+ "rStaRecBf.ucMemRow2 = %d\n"
473+ "rStaRecBf.ucMemCol2 = %d\n"
474+ "rStaRecBf.ucMemRow3 = %d\n"
475+ "rStaRecBf.ucMemCol3 = %d\n",
476+ r->pfmu_id,
477+ r->is_su_mu,
478+ r->txbf_cap,
479+ r->sounding_phy,
480+ r->ndpa_rate,
481+ r->ndp_rate,
482+ r->rpt_poll_rate,
483+ r->tx_mode,
484+ r->nc,
485+ r->nr,
486+ r->bw,
487+ r->mem_require_20m,
488+ r->mem_row0,
489+ r->mem_col0,
490+ r->mem_row1,
491+ r->mem_col1,
492+ r->mem_row2,
493+ r->mem_col2,
494+ r->mem_row3,
495+ r->mem_col3);
496+
497+ dev_info(dev->mt76.dev, "rStaRecBf.u2SmartAnt = 0x%x\n"
498+ "rStaRecBf.ucSEIdx = %d\n"
499+ "rStaRecBf.uciBfTimeOut = 0x%x\n"
500+ "rStaRecBf.uciBfDBW = %d\n"
501+ "rStaRecBf.uciBfNcol = %d\n"
502+ "rStaRecBf.uciBfNrow = %d\n"
503+ "rStaRecBf.nr_bw160 = %d\n"
504+ "rStaRecBf.nc_bw160 = %d\n"
505+ "rStaRecBf.ru_start_idx = %d\n"
506+ "rStaRecBf.ru_end_idx = %d\n"
507+ "rStaRecBf.trigger_su = %d\n"
508+ "rStaRecBf.trigger_mu = %d\n"
509+ "rStaRecBf.ng16_su = %d\n"
510+ "rStaRecBf.ng16_mu = %d\n"
511+ "rStaRecBf.codebook42_su = %d\n"
512+ "rStaRecBf.codebook75_mu = %d\n"
513+ "rStaRecBf.he_ltf = %d\n"
514+ "rStaRecBf.pp_fd_val = %d\n"
515+ "======================================\n",
516+ r->smart_ant,
517+ r->se_idx,
518+ r->bf_timeout,
519+ r->bf_dbw,
520+ r->bf_ncol,
521+ r->bf_nrow,
522+ r->nr_lt_bw80,
523+ r->nc_lt_bw80,
524+ r->ru_start_idx,
525+ r->ru_end_idx,
526+ r->trigger_su,
527+ r->trigger_mu,
528+ r->ng16_su,
529+ r->ng16_mu,
530+ r->codebook42_su,
531+ r->codebook75_mu,
532+ r->he_ltf,
533+ r->pp_fd_val);
534+ break;
535+ }
536+ case UNI_EVENT_BF_FBK_INFO: {
537+ struct mt7996_mcu_txbf_fbk_info *info;
538+ __le32 total, i;
539+
540+ info = (struct mt7996_mcu_txbf_fbk_info *)skb->data;
541+
542+ total = info->u4PFMUWRDoneCnt + info->u4PFMUWRFailCnt;
543+ total += info->u4PFMUWRTimeoutFreeCnt + info->u4FbRptPktDropCnt;
544+
545+ dev_info(dev->mt76.dev, "\n");
546+ dev_info(dev->mt76.dev, "\x1b[32m =================================\x1b[m\n");
547+ dev_info(dev->mt76.dev, "\x1b[32m PFMUWRDoneCnt = %u\x1b[m\n",
548+ info->u4PFMUWRDoneCnt);
549+ dev_info(dev->mt76.dev, "\x1b[32m PFMUWRFailCnt = %u\x1b[m\n",
550+ info->u4PFMUWRFailCnt);
551+ dev_info(dev->mt76.dev, "\x1b[32m PFMUWRTimeOutCnt = %u\x1b[m\n",
552+ info->u4PFMUWRTimeOutCnt);
553+ dev_info(dev->mt76.dev, "\x1b[32m PFMUWRTimeoutFreeCnt = %u\x1b[m\n",
554+ info->u4PFMUWRTimeoutFreeCnt);
555+ dev_info(dev->mt76.dev, "\x1b[32m FbRptPktDropCnt = %u\x1b[m\n",
556+ info->u4FbRptPktDropCnt);
557+ dev_info(dev->mt76.dev, "\x1b[32m TotalFbRptPkt = %u\x1b[m\n", total);
558+ dev_info(dev->mt76.dev, "\x1b[32m PollPFMUIntrStatTimeOut = %u(micro-sec)\x1b[m\n",
559+ info->u4PollPFMUIntrStatTimeOut);
560+ dev_info(dev->mt76.dev, "\x1b[32m FbRptDeQInterval = %u(milli-sec)\x1b[m\n",
561+ info->u4DeQInterval);
562+ dev_info(dev->mt76.dev, "\x1b[32m PktCntInFbRptTimeOutQ = %u\x1b[m\n",
563+ info->u4RptPktTimeOutListNum);
564+ dev_info(dev->mt76.dev, "\x1b[32m PktCntInFbRptQ = %u\x1b[m\n",
565+ info->u4RptPktListNum);
566+
567+ // [ToDo] Check if it is valid entry
568+ for (i = 0; ((i < 5) && (i < CFG_BF_STA_REC_NUM)); i++) {
569+
570+ // [ToDo] AID needs to be refined
571+ dev_info(dev->mt76.dev,"\x1b[32m AID%u RxFbRptCnt = %u\x1b[m\n"
572+ , i, info->au4RxPerStaFbRptCnt[i]);
573+ }
574+
575+ break;
576+ }
577+ case UNI_EVENT_BF_TXSND_INFO: {
578+ struct mt7996_mcu_tx_snd_info *info;
579+ struct uni_event_bf_txsnd_sta_info *snd_sta_info;
580+ int Idx;
581+ int max_wtbl_size = mt7996_wtbl_size(dev);
582+
583+ info = (struct mt7996_mcu_tx_snd_info *)skb->data;
584+ dev_info(dev->mt76.dev, "=================== Global Setting ===================\n");
585+
586+ dev_info(dev->mt76.dev, "VhtOpt = 0x%02X, HeOpt = 0x%02X, GloOpt = 0x%02X\n",
587+ info->vht_opt, info->he_opt, info->glo_opt);
588+
589+ for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
590+ dev_info(dev->mt76.dev, "SuSta[%d] = 0x%08X,", Idx,
591+ info->snd_rec_su_sta[Idx]);
592+ if ((Idx & 0x03) == 0x03)
593+ dev_info(dev->mt76.dev, "\n");
594+ }
595+
596+ if ((Idx & 0x03) != 0x03)
597+ dev_info(dev->mt76.dev, "\n");
598+
599+
600+ for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
601+ dev_info(dev->mt76.dev, "VhtMuSta[%d] = 0x%08X,", Idx, info->snd_rec_vht_mu_sta[Idx]);
602+ if ((Idx & 0x03) == 0x03)
603+ dev_info(dev->mt76.dev, "\n");
604+ }
605+
606+ if ((Idx & 0x03) != 0x03)
607+ dev_info(dev->mt76.dev, "\n");
608+
609+ for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
610+ dev_info(dev->mt76.dev, "HeTBSta[%d] = 0x%08X,", Idx, info->snd_rec_he_tb_sta[Idx]);
611+ if ((Idx & 0x03) == 0x03)
612+ dev_info(dev->mt76.dev, "\n");
613+ }
614+
615+ if ((Idx & 0x03) != 0x03)
616+ dev_info(dev->mt76.dev, "\n");
617+
618+ for (Idx = 0; Idx < BF_SND_CTRL_STA_DWORD_CNT; Idx++) {
619+ dev_info(dev->mt76.dev, "EhtTBSta[%d] = 0x%08X,", Idx, info->snd_rec_eht_tb_sta[Idx]);
620+ if ((Idx & 0x03) == 0x03)
621+ dev_info(dev->mt76.dev, "\n");
622+ }
623+
624+ if ((Idx & 0x03) != 0x03)
625+ dev_info(dev->mt76.dev, "\n");
626+
627+ for (Idx = 0; Idx < CFG_WIFI_RAM_BAND_NUM; Idx++) {
628+ dev_info(dev->mt76.dev, "Band%u:\n", Idx);
629+ dev_info(dev->mt76.dev, " Wlan Idx For VHT MC Sounding = %u\n", info->wlan_idx_for_mc_snd[Idx]);
630+ dev_info(dev->mt76.dev, " Wlan Idx For HE TB Sounding = %u\n", info->wlan_idx_for_he_tb_snd[Idx]);
631+ dev_info(dev->mt76.dev, " Wlan Idx For EHT TB Sounding = %u\n", info->wlan_idx_for_eht_tb_snd[Idx]);
632+ }
633+
634+ dev_info(dev->mt76.dev, "ULLen = %d, ULMcs = %d, ULLDCP = %d\n",
635+ info->ul_length, info->mcs, info->ldpc);
636+
637+ dev_info(dev->mt76.dev, "=================== STA Info ===================\n");
638+
639+ for (Idx = 1; (Idx < 5 && (Idx < CFG_BF_STA_REC_NUM)); Idx++) {
640+ snd_sta_info = &info->snd_sta_info[Idx];
641+ dev_info(dev->mt76.dev, "Idx%2u Interval = %d, interval counter = %d, TxCnt = %d, StopReason = 0x%02X\n",
642+ Idx,
643+ snd_sta_info->snd_intv,
644+ snd_sta_info->snd_intv_cnt,
645+ snd_sta_info->snd_tx_cnt,
646+ snd_sta_info->snd_stop_reason);
647+ }
648+
649+ dev_info(dev->mt76.dev, "=================== STA Info Connected ===================\n");
650+ // [ToDo] How to iterate and get AID info of station
651+ // Check UniEventBFCtrlTxSndHandle() on Logan
652+
653+ //hardcode max_wtbl_size as 5
654+ max_wtbl_size = 5;
655+ for (Idx = 1; ((Idx < max_wtbl_size) && (Idx < CFG_BF_STA_REC_NUM)); Idx++) {
656+
657+ // [ToDo] We do not show AID info here
658+ snd_sta_info = &info->snd_sta_info[Idx];
659+ dev_info(dev->mt76.dev, " Interval = %d (%u ms), interval counter = %d (%u ms), TxCnt = %d, StopReason = 0x%02X\n",
660+ snd_sta_info->snd_intv,
661+ snd_sta_info->snd_intv * 10,
662+ snd_sta_info->snd_intv_cnt,
663+ snd_sta_info->snd_intv_cnt * 10,
664+ snd_sta_info->snd_tx_cnt,
665+ snd_sta_info->snd_stop_reason);
666+ }
667+
668+ dev_info(dev->mt76.dev, "======================================\n");
669+
670+ break;
671+ }
672+ default:
673+ dev_info(dev->mt76.dev, "%s: unknown bf event tag %d\n",
674+ __func__, event->tag);
675+ }
676+
677+}
678+
679+
680+int mt7996_mcu_set_muru_fixed_rate_enable(struct mt7996_dev *dev, u8 action, int val)
681+{
682+ struct {
683+ u8 _rsv[4];
684+
685+ __le16 tag;
686+ __le16 len;
687+
688+ __le16 value;
689+ __le16 rsv;
690+ } __packed data = {
691+ .tag = cpu_to_le16(action),
692+ .len = cpu_to_le16(sizeof(data) - 4),
693+ .value = cpu_to_le16(!!val),
694+ };
695+
696+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data, sizeof(data),
697+ false);
698+}
699+
700+int mt7996_mcu_set_muru_fixed_rate_parameter(struct mt7996_dev *dev, u8 action, void *para)
701+{
702+ char *buf = (char *)para;
703+ u8 num_user = 0, recv_arg = 0, max_mcs = 0, usr_mcs[4] = {0};
704+ __le16 bw;
705+ int i;
706+ struct {
707+ u8 _rsv[4];
708+
709+ __le16 tag;
710+ __le16 len;
711+
712+ u8 cmd_version;
713+ u8 cmd_revision;
714+ __le16 rsv;
715+
716+ struct uni_muru_mum_set_group_tbl_entry entry;
717+ } __packed data = {
718+ .tag = cpu_to_le16(action),
719+ .len = cpu_to_le16(sizeof(data) - 4),
720+ };
721+
722+#define __RUALLOC_TYPE_CHECK_HE(BW) ((BW == RUALLOC_BW20) || (BW == RUALLOC_BW40) || (BW == RUALLOC_BW80) || (BW == RUALLOC_BW160))
723+#define __RUALLOC_TYPE_CHECK_EHT(BW) (__RUALLOC_TYPE_CHECK_HE(BW) || (BW == RUALLOC_BW320))
724+ /* [Num of user] - 1~4
725+ * [RUAlloc] - BW320: 395, BW160: 137, BW80: 134, BW40: 130, BW20: 122
726+ * [LTF/GI] - For VHT, short GI: 0, Long GI: 1; *
727+ * For HE/EHT, 4xLTF+3.2us: 0, 4xLTF+0.8us: 1, 2xLTF+0.8us:2
728+ * [Phy/FullBW] - VHT: 0 / HEFullBw: 1 / HEPartialBw: 2 / EHTFullBW: 3, EHTPartialBW: 4
729+ * [DL/UL] DL: 0, UL: 1, DL_UL: 2
730+ * [Wcid User0] - WCID 0
731+ * [MCS of WCID0] - For HE/VHT, 0-11: 1ss MCS0-MCS11, 12-23: 2SS MCS0-MCS11
732+ * For EHT, 0-13: 1ss MCS0-MCS13, 14-27: 2SS MCS0-MCS13
733+ * [WCID 1]
734+ * [MCS of WCID1]
735+ * [WCID 2]
736+ * [MCS of WCID2]
737+ * [WCID 3]
738+ * [MCS of WCID3]
739+ */
740+
741+ recv_arg = sscanf(buf, "%hhu %hu %hhu %hhu %hhu %hu %hhu %hu %hhu %hu %hhu %hu %hhu",
742+ &num_user, &bw, &data.entry.gi, &data.entry.capa, &data.entry.dl_ul,
743+ &data.entry.wlan_idx0, &usr_mcs[0],
744+ &data.entry.wlan_idx1, &usr_mcs[1],
745+ &data.entry.wlan_idx2, &usr_mcs[2],
746+ &data.entry.wlan_idx3, &usr_mcs[3]);
747+
748+ if (recv_arg != (5 + (2 * num_user))) {
749+ dev_err(dev->mt76.dev, "The number of argument is invalid\n");
750+ goto error;
751+ }
752+
753+ if (num_user > 0 && num_user < 5)
754+ data.entry.num_user = num_user - 1;
755+ else {
756+ dev_err(dev->mt76.dev, "The number of user count is invalid\n");
757+ goto error;
758+ }
759+
760+ /**
761+ * Older chip shall be set as HE. Refer to getHWSupportByChip() in Logan
762+ * driver to know the value for differnt chips
763+ */
764+ data.cmd_version = UNI_CMD_MURU_VER_EHT;
765+
766+ if (data.cmd_version == UNI_CMD_MURU_VER_EHT)
767+ max_mcs = UNI_MAX_MCS_SUPPORT_EHT;
768+ else
769+ max_mcs = UNI_MAX_MCS_SUPPORT_HE;
770+
771+
772+ // Parameter Check
773+ if (data.cmd_version != UNI_CMD_MURU_VER_EHT) {
774+ if ((data.entry.capa > MAX_MODBF_HE) || (bw == RUALLOC_BW320))
775+ goto error;
776+ } else {
777+ if ((data.entry.capa <= MAX_MODBF_HE) && (bw == RUALLOC_BW320))
778+ goto error;
779+ }
780+
781+ if (data.entry.capa <= MAX_MODBF_HE)
782+ max_mcs = UNI_MAX_MCS_SUPPORT_HE;
783+
784+ if (__RUALLOC_TYPE_CHECK_EHT(bw)) {
785+ data.entry.ru_alloc = (u8)(bw & 0xFF);
786+ if (bw == RUALLOC_BW320)
787+ data.entry.ru_alloc_ext = (u8)(bw >> 8);
788+ } else {
789+ dev_err(dev->mt76.dev, "RU_ALLOC argument is invalid\n");
790+ goto error;
791+ }
792+
793+ if ((data.entry.gi > 2) ||
794+ ((data.entry.gi > 1) && (data.entry.capa == MAX_MODBF_VHT))) {
795+ dev_err(dev->mt76.dev, "GI argument is invalid\n");
796+ goto error;
797+ }
798+
799+ if (data.entry.dl_ul > 2) {
800+ dev_err(dev->mt76.dev, "DL_UL argument is invalid\n");
801+ goto error;
802+ }
803+
804+#define __mcs_handler(_n) \
805+ do { \
806+ if (usr_mcs[_n] > max_mcs) { \
807+ usr_mcs[_n] -= (max_mcs + 1); \
808+ data.entry.nss##_n = 1; \
809+ if (usr_mcs[_n] > max_mcs) \
810+ usr_mcs[_n] = max_mcs; \
811+ } \
812+ if ((data.entry.dl_ul & 0x1) == 0) \
813+ data.entry.dl_mcs_user##_n = usr_mcs[_n]; \
814+ if ((data.entry.dl_ul & 0x3) > 0) \
815+ data.entry.ul_mcs_user##_n = usr_mcs[_n]; \
816+ } \
817+ while (0)
818+
819+ for (i=0; i<= data.entry.num_user; i++) {
820+ switch (i) {
821+ case 0:
822+ __mcs_handler(0);
823+ break;
824+ case 1:
825+ __mcs_handler(1);
826+ break;
827+ case 2:
828+ __mcs_handler(2);
829+ break;
830+ case 3:
831+ __mcs_handler(3);
832+ break;
833+ default:
834+ break;
835+ }
836+ }
837+#undef __mcs_handler
838+
839+
840+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(MURU), &data,
841+ sizeof(data), false);
842+
843+error:
844+ dev_err(dev->mt76.dev, "Command failed!\n");
845+ return -EINVAL;
846+}
847+
848 #endif
849diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
850index cc2de8f4..519ffe1c 100644
851--- a/mt7996/mtk_mcu.h
852+++ b/mt7996/mtk_mcu.h
853@@ -106,6 +106,348 @@ enum {
854 EDCCA_FCC = 1,
855 EDCCA_ETSI = 2,
856 EDCCA_JAPAN = 3
857+
858+struct bf_pfmu_tag {
859+ __le16 tag;
860+ __le16 len;
861+
862+ u8 pfmu_id;
863+ bool bfer;
864+ u8 band_idx;
865+ u8 __rsv[5];
866+ u8 buf[56];
867+} __packed;
868+
869+struct bf_starec_read {
870+ __le16 tag;
871+ __le16 len;
872+
873+ __le16 wlan_idx;
874+ u8 __rsv[2];
875+} __packed;
876+
877+struct bf_fbk_rpt_info {
878+ __le16 tag;
879+ __le16 len;
880+
881+ __le16 wlan_idx; // Only need for dynamic_pfmu_update 0x4
882+ u8 action;
883+ u8 band_idx;
884+ u8 __rsv[4];
885+
886+} __packed;
887+
888+struct bf_txsnd_info {
889+ __le16 tag;
890+ __le16 len;
891+
892+ u8 action;
893+ u8 read_clr;
894+ u8 vht_opt;
895+ u8 he_opt;
896+ __le16 wlan_idx;
897+ u8 glo_opt;
898+ u8 snd_intv;
899+ u8 snd_stop;
900+ u8 max_snd_stas;
901+ u8 tx_time;
902+ u8 mcs;
903+ u8 ldpc;
904+ u8 inf;
905+ u8 man;
906+ u8 ac_queue;
907+ u8 sxn_protect;
908+ u8 direct_fbk;
909+ u8 __rsv[2];
910+} __packed;
911+
912+struct mt7996_mcu_bf_basic_event {
913+ struct mt7996_mcu_rxd rxd;
914+
915+ u8 __rsv1[4];
916+
917+ __le16 tag;
918+ __le16 len;
919+};
920+
921+struct mt7996_mcu_bf_starec_read {
922+
923+ struct mt7996_mcu_bf_basic_event event;
924+
925+ __le16 pfmu_id;
926+ bool is_su_mu;
927+ u8 txbf_cap;
928+ u8 sounding_phy;
929+ u8 ndpa_rate;
930+ u8 ndp_rate;
931+ u8 rpt_poll_rate;
932+ u8 tx_mode;
933+ u8 nc;
934+ u8 nr;
935+ u8 bw;
936+ u8 total_mem_require;
937+ u8 mem_require_20m;
938+ u8 mem_row0;
939+ u8 mem_col0:6;
940+ u8 mem_row0_msb:2;
941+ u8 mem_row1;
942+ u8 mem_col1:6;
943+ u8 mem_row1_msb:2;
944+ u8 mem_row2;
945+ u8 mem_col2:6;
946+ u8 mem_row2_msb:2;
947+ u8 mem_row3;
948+ u8 mem_col3:6;
949+ u8 mem_row3_msb:2;
950+
951+ __le16 smart_ant;
952+ u8 se_idx;
953+ u8 auto_sounding_ctrl;
954+
955+ u8 bf_timeout;
956+ u8 bf_dbw;
957+ u8 bf_ncol;
958+ u8 bf_nrow;
959+
960+ u8 nr_lt_bw80;
961+ u8 nc_lt_bw80;
962+ u8 ru_start_idx;
963+ u8 ru_end_idx;
964+
965+ bool trigger_su;
966+ bool trigger_mu;
967+
968+ bool ng16_su;
969+ bool ng16_mu;
970+
971+ bool codebook42_su;
972+ bool codebook75_mu;
973+
974+ u8 he_ltf;
975+ u8 pp_fd_val;
976+};
977+
978+#define TXBF_PFMU_ID_NUM_MAX 48
979+
980+#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND0 TXBF_PFMU_ID_NUM_MAX
981+#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND1 TXBF_PFMU_ID_NUM_MAX
982+#define TXBF_PFMU_ID_NUM_MAX_TBTC_BAND2 TXBF_PFMU_ID_NUM_MAX
983+
984+/* CFG_BF_STA_REC shall be varied based on BAND Num */
985+#define CFG_BF_STA_REC_NUM (TXBF_PFMU_ID_NUM_MAX_TBTC_BAND0 + TXBF_PFMU_ID_NUM_MAX_TBTC_BAND1 + TXBF_PFMU_ID_NUM_MAX_TBTC_BAND2)
986+
987+#define BF_SND_CTRL_STA_DWORD_CNT ((CFG_BF_STA_REC_NUM + 0x1F) >> 5)
988+
989+#ifndef ALIGN_4
990+ #define ALIGN_4(_value) (((_value) + 3) & ~3u)
991+#endif /* ALIGN_4 */
992+
993+#define CFG_WIFI_RAM_BAND_NUM 3
994+
995+struct uni_event_bf_txsnd_sta_info {
996+ u8 snd_intv; /* Sounding interval upper bound, unit:15ms */
997+ u8 snd_intv_cnt; /* Sounding interval counter */
998+ u8 snd_tx_cnt; /* Tx sounding count for debug */
999+ u8 snd_stop_reason; /* Bitwise reason to put in Stop Queue */
1000+};
1001+
1002+struct mt7996_mcu_tx_snd_info {
1003+
1004+ struct mt7996_mcu_bf_basic_event event;
1005+
1006+ u8 vht_opt;
1007+ u8 he_opt;
1008+ u8 glo_opt;
1009+ u8 __rsv;
1010+ __le32 snd_rec_su_sta[BF_SND_CTRL_STA_DWORD_CNT];
1011+ __le32 snd_rec_vht_mu_sta[BF_SND_CTRL_STA_DWORD_CNT];
1012+ __le32 snd_rec_he_tb_sta[BF_SND_CTRL_STA_DWORD_CNT];
1013+ __le32 snd_rec_eht_tb_sta[BF_SND_CTRL_STA_DWORD_CNT];
1014+ __le16 wlan_idx_for_mc_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
1015+ __le16 wlan_idx_for_he_tb_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
1016+ __le16 wlan_idx_for_eht_tb_snd[ALIGN_4(CFG_WIFI_RAM_BAND_NUM)];
1017+ __le16 ul_length;
1018+ u8 mcs;
1019+ u8 ldpc;
1020+ struct uni_event_bf_txsnd_sta_info snd_sta_info[CFG_BF_STA_REC_NUM];
1021+};
1022+
1023+struct mt7996_mcu_txbf_fbk_info {
1024+
1025+ struct mt7996_mcu_bf_basic_event event;
1026+
1027+ __le32 u4DeQInterval; /* By ms */
1028+ __le32 u4PollPFMUIntrStatTimeOut; /* micro-sec */
1029+ __le32 u4RptPktTimeOutListNum;
1030+ __le32 u4RptPktListNum;
1031+ __le32 u4PFMUWRTimeOutCnt;
1032+ __le32 u4PFMUWRFailCnt;
1033+ __le32 u4PFMUWRDoneCnt;
1034+ __le32 u4PFMUWRTimeoutFreeCnt;
1035+ __le32 u4FbRptPktDropCnt;
1036+ __le32 au4RxPerStaFbRptCnt[CFG_BF_STA_REC_NUM];
1037+};
1038+
1039+struct pfmu_ru_field {
1040+ __le32 ru_start_id:7;
1041+ __le32 _rsv1:1;
1042+ __le32 ru_end_id:7;
1043+ __le32 _rsv2:1;
1044+} __packed;
1045+
1046+struct pfmu_partial_bw_info {
1047+ __le32 partial_bw_info:9;
1048+ __le32 _rsv1:7;
1049+} __packed;
1050+
1051+struct mt7996_pfmu_tag1 {
1052+ __le32 pfmu_idx:10;
1053+ __le32 ebf:1;
1054+ __le32 data_bw:3;
1055+ __le32 lm:3;
1056+ __le32 is_mu:1;
1057+ __le32 nr:3;
1058+ __le32 nc:3;
1059+ __le32 codebook:2;
1060+ __le32 ngroup:2;
1061+ __le32 invalid_prof:1;
1062+ __le32 _rsv:3;
1063+
1064+ __le32 col_id1:7, row_id1:9;
1065+ __le32 col_id2:7, row_id2:9;
1066+ __le32 col_id3:7, row_id3:9;
1067+ __le32 col_id4:7, row_id4:9;
1068+
1069+ union {
1070+ struct pfmu_ru_field field;
1071+ struct pfmu_partial_bw_info bw_info;
1072+ };
1073+ __le32 mob_cal_en:1;
1074+ __le32 _rsv2:3;
1075+ __le32 mob_ru_alloc:9; /* EHT profile uses full 9 bit */
1076+ __le32 _rsv3:3;
1077+
1078+ __le32 snr_sts0:8, snr_sts1:8, snr_sts2:8, snr_sts3:8;
1079+ __le32 snr_sts4:8, snr_sts5:8, snr_sts6:8, snr_sts7:8;
1080+
1081+ __le32 _rsv4;
1082+} __packed;
1083+
1084+struct mt7996_pfmu_tag2 {
1085+ __le32 smart_ant:24;
1086+ __le32 se_idx:5;
1087+ __le32 _rsv:3;
1088+
1089+ __le32 _rsv1:16;
1090+ __le32 ibf_timeout:8;
1091+ __le32 _rsv2:8;
1092+
1093+ __le32 ibf_data_bw:3;
1094+ __le32 ibf_nc:3;
1095+ __le32 ibf_nr:3;
1096+ __le32 ibf_ru:9;
1097+ __le32 _rsv3:14;
1098+
1099+ __le32 mob_delta_t:8;
1100+ __le32 mob_lq_result:7;
1101+ __le32 _rsv5:1;
1102+ __le32 _rsv6:16;
1103+
1104+ __le32 _rsv7;
1105+} __packed;
1106+
1107+struct mt7996_pfmu_tag_event {
1108+ struct mt7996_mcu_bf_basic_event event;
1109+
1110+ u8 bfer;
1111+ u8 __rsv[3];
1112+
1113+ struct mt7996_pfmu_tag1 t1;
1114+ struct mt7996_pfmu_tag2 t2;
1115+};
1116+
1117+enum {
1118+ UNI_EVENT_BF_PFMU_TAG = 0x5,
1119+ UNI_EVENT_BF_PFMU_DATA = 0x7,
1120+ UNI_EVENT_BF_STAREC = 0xB,
1121+ UNI_EVENT_BF_CAL_PHASE = 0xC,
1122+ UNI_EVENT_BF_FBK_INFO = 0x17,
1123+ UNI_EVENT_BF_TXSND_INFO = 0x18,
1124+ UNI_EVENT_BF_PLY_INFO = 0x19,
1125+ UNI_EVENT_BF_METRIC_INFO = 0x1A,
1126+ UNI_EVENT_BF_TXCMD_CFG_INFO = 0x1B,
1127+ UNI_EVENT_BF_SND_CNT_INFO = 0x1D,
1128+ UNI_EVENT_BF_MAX_NUM
1129+};
1130+
1131+enum {
1132+ UNI_CMD_MURU_FIXED_RATE_CTRL = 0x11,
1133+ UNI_CMD_MURU_FIXED_GROUP_RATE_CTRL,
1134+};
1135+
1136+struct uni_muru_mum_set_group_tbl_entry {
1137+ __le16 wlan_idx0;
1138+ __le16 wlan_idx1;
1139+ __le16 wlan_idx2;
1140+ __le16 wlan_idx3;
1141+
1142+ u8 dl_mcs_user0:4;
1143+ u8 dl_mcs_user1:4;
1144+ u8 dl_mcs_user2:4;
1145+ u8 dl_mcs_user3:4;
1146+ u8 ul_mcs_user0:4;
1147+ u8 ul_mcs_user1:4;
1148+ u8 ul_mcs_user2:4;
1149+ u8 ul_mcs_user3:4;
1150+
1151+ u8 num_user:2;
1152+ u8 rsv:6;
1153+ u8 nss0:2;
1154+ u8 nss1:2;
1155+ u8 nss2:2;
1156+ u8 nss3:2;
1157+ u8 ru_alloc;
1158+ u8 ru_alloc_ext;
1159+
1160+ u8 capa;
1161+ u8 gi;
1162+ u8 dl_ul;
1163+ u8 _rsv2;
1164+};
1165+
1166+enum UNI_CMD_MURU_VER_T {
1167+ UNI_CMD_MURU_VER_LEG = 0,
1168+ UNI_CMD_MURU_VER_HE,
1169+ UNI_CMD_MURU_VER_EHT,
1170+ UNI_CMD_MURU_VER_MAX
1171+};
1172+
1173+#define UNI_MAX_MCS_SUPPORT_HE 11
1174+#define UNI_MAX_MCS_SUPPORT_EHT 13
1175+
1176+enum {
1177+ RUALLOC_BW20 = 122,
1178+ RUALLOC_BW40 = 130,
1179+ RUALLOC_BW80 = 134,
1180+ RUALLOC_BW160 = 137,
1181+ RUALLOC_BW320 = 395,
1182+};
1183+
1184+enum {
1185+ MAX_MODBF_VHT = 0,
1186+ MAX_MODBF_HE = 2,
1187+ MAX_MODBF_EHT = 4,
1188+};
1189+
1190+enum {
1191+ BF_SND_READ_INFO = 0,
1192+ BF_SND_CFG_OPT,
1193+ BF_SND_CFG_INTV,
1194+ BF_SND_STA_STOP,
1195+ BF_SND_CFG_MAX_STA,
1196+ BF_SND_CFG_BFRP,
1197+ BF_SND_CFG_INF,
1198+ BF_SND_CFG_TXOP_SND
1199 };
1200
1201 enum {
1202--
12032.18.0
1204