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