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