blob: 264bb50076f431d7de2f4e9b2a2bb8e6c4f786e2 [file] [log] [blame]
developerdad04b12022-12-22 16:47:31 +08001From acc136bc397c9417ca42de7642ede1c35745dae3 Mon Sep 17 00:00:00 2001
developerc5ce7502022-12-19 11:33:22 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Thu, 15 Dec 2022 19:45:18 +0800
developerdad04b12022-12-22 16:47:31 +08004Subject: [PATCH] mt76: testmode: add iBF/eBF cal and cert commands with golden
developerc5ce7502022-12-19 11:33:22 +08005
6Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
7---
8 mt76.h | 4 +
9 mt76_connac_mcu.c | 3 +
10 mt7915/mac.c | 4 +-
11 mt7915/main.c | 54 ++---
12 mt7915/mcu.c | 29 ++-
13 mt7915/mcu.h | 172 ++++++++++++++++
14 mt7915/mmio.c | 2 +
15 mt7915/mt7915.h | 14 +-
16 mt7915/mtk_debugfs.c | 35 ++++
17 mt7915/mtk_mcu.c | 246 ++++++++++++++++++++++-
18 mt7915/regs.h | 4 +
developerdad04b12022-12-22 16:47:31 +080019 mt7915/testmode.c | 460 ++++++++++++++++++++++++++++---------------
developerc5ce7502022-12-19 11:33:22 +080020 mt7915/testmode.h | 134 +------------
21 testmode.c | 1 +
22 testmode.h | 9 +
23 tools/fields.c | 9 +
developerdad04b12022-12-22 16:47:31 +080024 16 files changed, 856 insertions(+), 324 deletions(-)
developerc5ce7502022-12-19 11:33:22 +080025
26diff --git a/mt76.h b/mt76.h
27index 2bacc1b..c6aefbf 100644
28--- a/mt76.h
29+++ b/mt76.h
30@@ -681,6 +681,7 @@ struct mt76_testmode_data {
31
32 struct list_head tm_entry_list;
33 struct mt76_wcid *cur_entry;
34+ struct ieee80211_vif *second_vif;
35 u8 entry_num;
36 union {
37 struct mt76_testmode_entry_data ed;
38@@ -709,6 +710,9 @@ struct mt76_testmode_data {
39
40 u8 txbf_act;
41 u16 txbf_param[8];
42+ bool is_txbf_dut;
43+ bool bf_en;
44+ bool ebf;
45
46 u32 tx_pending;
47 u32 tx_queued;
48diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
49index 291a7c1..14ce09e 100644
50--- a/mt76_connac_mcu.c
51+++ b/mt76_connac_mcu.c
52@@ -2756,6 +2756,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
53 u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
54 struct bss_info_basic *bss;
55 struct tlv *tlv;
56+ struct mt76_testmode_data *td = &phy->test;
57
58 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
59 bss = (struct bss_info_basic *)tlv;
60@@ -2815,6 +2816,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
61 bss->dtim_period = vif->bss_conf.dtim_period;
62 bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
63 chandef->chan->band, NULL);
64+ } else if (td->bf_en) {
65+ memcpy(bss->bssid, vif->addr, ETH_ALEN);
66 } else {
67 memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
68 }
69diff --git a/mt7915/mac.c b/mt7915/mac.c
70index 0746e4b..013dfbd 100644
71--- a/mt7915/mac.c
72+++ b/mt7915/mac.c
73@@ -753,8 +753,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
74 val |= MT_TXD6_LDPC;
75
76 txwi[3] &= ~cpu_to_le32(MT_TXD3_SN_VALID);
77- if (phy->test.bf_en)
78+ if (td->bf_en && !td->ebf)
79 val |= MT_TXD6_TX_IBF | MT_TXD6_TX_EBF;
80+ else if (td->bf_en && td->ebf)
81+ val |= MT_TXD6_TX_EBF;
82
83 txwi[6] |= cpu_to_le32(val);
84 #endif
85diff --git a/mt7915/main.c b/mt7915/main.c
86index 4c3d822..a347e77 100644
87--- a/mt7915/main.c
88+++ b/mt7915/main.c
89@@ -205,46 +205,37 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)
90 }
91 }
92
93-static int mt7915_add_interface(struct ieee80211_hw *hw,
94- struct ieee80211_vif *vif)
95+int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_en)
96 {
97 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
98- struct mt7915_dev *dev = mt7915_hw_dev(hw);
99- struct mt7915_phy *phy = mt7915_hw_phy(hw);
100+ struct mt7915_dev *dev = phy->dev;
101 struct mt76_txq *mtxq;
102 bool ext_phy = phy != &dev->phy;
103 int idx, ret = 0;
104
105- mutex_lock(&dev->mt76.mutex);
106-
107- mt76_testmode_reset(phy->mt76, true);
108-
109- if (vif->type == NL80211_IFTYPE_MONITOR &&
110- is_zero_ether_addr(vif->addr))
111- phy->monitor_vif = vif;
112+ /* To differentiate the mac address of TXD and TXCMD interface */
113+ vif->addr[0] |= bf_en;
114
115 mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask);
116- if (mvif->mt76.idx >= (MT7915_MAX_INTERFACES << dev->dbdc_support)) {
117- ret = -ENOSPC;
118- goto out;
119- }
120+ if (mvif->mt76.idx >= (MT7915_MAX_INTERFACES << dev->dbdc_support))
121+ return -ENOSPC;
122
123 idx = get_omac_idx(vif->type, phy->omac_mask);
124- if (idx < 0) {
125- ret = -ENOSPC;
126- goto out;
127- }
128+ if (idx < 0)
129+ return -ENOSPC;
130+
131 mvif->mt76.omac_idx = idx;
132 mvif->phy = phy;
133 mvif->mt76.band_idx = phy->mt76->band_idx;
134
135- mvif->mt76.wmm_idx = (vif->type != NL80211_IFTYPE_AP && vif->type != NL80211_IFTYPE_MONITOR);
136+ mvif->mt76.wmm_idx = (vif->type != NL80211_IFTYPE_AP &&
137+ vif->type != NL80211_IFTYPE_MONITOR) || bf_en;
138 if (ext_phy)
139 mvif->mt76.wmm_idx += 2;
140
141 ret = mt7915_mcu_add_dev_info(phy, vif, true);
142 if (ret)
143- goto out;
144+ return ret;
145
146 dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
147 phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
148@@ -279,7 +270,26 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
149 mt7915_mcu_add_sta(dev, vif, NULL, true);
150 rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
151
152-out:
153+ return ret;
154+}
155+
156+static int mt7915_add_interface(struct ieee80211_hw *hw,
157+ struct ieee80211_vif *vif)
158+{
159+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
160+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
161+ int ret = 0;
162+
163+ mutex_lock(&dev->mt76.mutex);
164+
165+ mt76_testmode_reset(phy->mt76, true);
166+
167+ if (vif->type == NL80211_IFTYPE_MONITOR &&
168+ is_zero_ether_addr(vif->addr))
169+ phy->monitor_vif = vif;
170+
171+ ret = mt7915_init_vif(phy, vif, false);
172+
173 mutex_unlock(&dev->mt76.mutex);
174
175 return ret;
176diff --git a/mt7915/mcu.c b/mt7915/mcu.c
177index b8243e1..5d41ebf 100644
178--- a/mt7915/mcu.c
179+++ b/mt7915/mcu.c
180@@ -193,6 +193,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
181 int ret;
182
183 ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq);
184+
185 if (ret)
186 return ret;
187
188@@ -383,10 +384,12 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
189 case MCU_EXT_EVENT_BCC_NOTIFY:
190 mt7915_mcu_rx_bcc_notify(dev, skb);
191 break;
192-#ifdef CONFIG_NL80211_TESTMODE
193+#if defined CONFIG_NL80211_TESTMODE || defined MTK_DEBUG
194 case MCU_EXT_EVENT_BF_STATUS_READ:
195- mt7915_tm_txbf_status_read(dev, skb);
196+ mt7915_mcu_txbf_status_read(dev, skb);
197 break;
198+#endif
199+#ifdef CONFIG_NL80211_TESTMODE
200 case MCU_EXT_EVENT_RF_TEST:
201 mt7915_tm_rf_test_event(dev, skb);
202 break;
203@@ -673,11 +676,22 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
204 if (enable)
205 mt76_connac_mcu_bss_omac_tlv(skb, vif);
206
207- mt76_connac_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76,
208- mvif->sta.wcid.idx, enable);
209+ if (vif->type == NL80211_IFTYPE_MONITOR) {
210+ struct mt76_testmode_data *td = &phy->mt76->test;
211+ struct mt76_wcid *wcid;
212+
213+ if (!td->aid || list_empty(&td->tm_entry_list))
214+ wcid = &mvif->sta.wcid;
215+ else
216+ wcid = list_first_entry(&td->tm_entry_list, struct mt76_wcid, list);
217
218- if (vif->type == NL80211_IFTYPE_MONITOR)
219+ mt76_connac_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76,
220+ wcid->idx, enable);
221 goto out;
222+ }
223+
224+ mt76_connac_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76,
225+ mvif->sta.wcid.idx, enable);
226
227 if (enable) {
228 mt7915_mcu_bss_rfch_tlv(skb, vif, phy);
229@@ -3403,6 +3417,7 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
230
231 int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
232 {
233+#define MT_BF_PROCESSING 4
234 struct {
235 u8 action;
236 union {
237@@ -3429,7 +3444,6 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
238 .action = action,
239 };
240
241-#define MT_BF_PROCESSING 4
242 switch (action) {
243 case MT_BF_SOUNDING_ON:
244 req.snd.snd_mode = MT_BF_PROCESSING;
245@@ -4347,6 +4361,9 @@ int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
246 req.he_opt = v2;
247 req.glo_opt = v3;
248 break;
249+ case BF_SND_CFG_INF:
250+ req.inf = v1;
251+ break;
252 default:
253 return -EINVAL;
254 }
255diff --git a/mt7915/mcu.h b/mt7915/mcu.h
256index 9a48524..a30f52d 100644
257--- a/mt7915/mcu.h
258+++ b/mt7915/mcu.h
259@@ -475,10 +475,12 @@ enum {
260 };
261
262 enum {
263+ MT_BF_SOUNDING_OFF = 0,
264 MT_BF_SOUNDING_ON = 1,
265 MT_BF_DATA_PACKET_APPLY = 2,
266 MT_BF_PFMU_TAG_READ = 5,
267 MT_BF_PFMU_TAG_WRITE = 6,
268+ MT_BF_STA_REC_READ = 13,
269 MT_BF_PHASE_CAL = 14,
270 MT_BF_IBF_PHASE_COMP = 15,
271 MT_BF_PROFILE_WRITE_ALL = 17,
272@@ -486,6 +488,176 @@ enum {
273 MT_BF_MODULE_UPDATE = 25
274 };
275
276+#if defined CONFIG_NL80211_TESTMODE || defined MTK_DEBUG
277+struct mt7915_pfmu_tag1 {
278+ __le32 pfmu_idx:10;
279+ __le32 ebf:1;
280+ __le32 data_bw:2;
281+ __le32 lm:2;
282+ __le32 is_mu:1;
283+ __le32 nr:3, nc:3;
284+ __le32 codebook:2;
285+ __le32 ngroup:2;
286+ __le32 _rsv:2;
287+ __le32 invalid_prof:1;
288+ __le32 rmsd:3;
289+
290+ __le32 col_id1:6, row_id1:10;
291+ __le32 col_id2:6, row_id2:10;
292+ __le32 col_id3:6, row_id3:10;
293+ __le32 col_id4:6, row_id4:10;
294+
295+ __le32 ru_start_id:7;
296+ __le32 _rsv1:1;
297+ __le32 ru_end_id:7;
298+ __le32 _rsv2:1;
299+ __le32 mob_cal_en:1;
300+ __le32 _rsv3:15;
301+
302+ __le32 snr_sts0:8, snr_sts1:8, snr_sts2:8, snr_sts3:8;
303+ __le32 snr_sts4:8, snr_sts5:8, snr_sts6:8, snr_sts7:8;
304+
305+ __le32 _rsv4;
306+} __packed;
307+
308+struct mt7915_pfmu_tag2 {
309+ __le32 smart_ant:24;
310+ __le32 se_idx:5;
311+ __le32 _rsv:3;
312+
313+ __le32 _rsv1:8;
314+ __le32 rmsd_thres:3;
315+ __le32 _rsv2:5;
316+ __le32 ibf_timeout:8;
317+ __le32 _rsv3:8;
318+
319+ __le32 _rsv4:16;
320+ __le32 ibf_data_bw:2;
321+ __le32 ibf_nc:3;
322+ __le32 ibf_nr:3;
323+ __le32 ibf_ru:8;
324+
325+ __le32 mob_delta_t:8;
326+ __le32 mob_lq_result:7;
327+ __le32 _rsv5:1;
328+ __le32 _rsv6:16;
329+
330+ __le32 _rsv7;
331+} __packed;
332+
333+struct mt7915_pfmu_tag {
334+ struct mt7915_pfmu_tag1 t1;
335+ struct mt7915_pfmu_tag2 t2;
336+};
337+
338+struct mt7915_bf_status_hdr {
339+ u8 format_id;
340+ u8 bw;
341+ u16 subcarrier_idx;
342+ bool bfer;
343+ u8 rsv[3];
344+} __packed;
345+
346+struct mt7915_bf_status {
347+ struct mt7915_bf_status_hdr hdr;
348+ u8 buf[1000];
349+} __packed;
350+
351+struct mt7915_txbf_phase_out {
352+ u8 c0_l;
353+ u8 c1_l;
354+ u8 c2_l;
355+ u8 c3_l;
356+ u8 c0_m;
357+ u8 c1_m;
358+ u8 c2_m;
359+ u8 c3_m;
360+ u8 c0_h;
361+ u8 c1_h;
362+ u8 c2_h;
363+ u8 c3_h;
364+ u8 c0_uh;
365+ u8 c1_uh;
366+ u8 c2_uh;
367+ u8 c3_uh;
368+};
369+
370+struct mt7915_txbf_phase {
371+ u8 status;
372+ struct {
373+ u8 r0_uh;
374+ u8 r0_h;
375+ u8 r0_m;
376+ u8 r0_l;
377+ u8 r0_ul;
378+ u8 r1_uh;
379+ u8 r1_h;
380+ u8 r1_m;
381+ u8 r1_l;
382+ u8 r1_ul;
383+ u8 r2_uh;
384+ u8 r2_h;
385+ u8 r2_m;
386+ u8 r2_l;
387+ u8 r2_ul;
388+ u8 r3_uh;
389+ u8 r3_h;
390+ u8 r3_m;
391+ u8 r3_l;
392+ u8 r3_ul;
393+ u8 r2_uh_sx2;
394+ u8 r2_h_sx2;
395+ u8 r2_m_sx2;
396+ u8 r2_l_sx2;
397+ u8 r2_ul_sx2;
398+ u8 r3_uh_sx2;
399+ u8 r3_h_sx2;
400+ u8 r3_m_sx2;
401+ u8 r3_l_sx2;
402+ u8 r3_ul_sx2;
403+ u8 m_t0_h;
404+ u8 m_t1_h;
405+ u8 m_t2_h;
406+ u8 m_t2_h_sx2;
407+ u8 r0_reserved;
408+ u8 r1_reserved;
409+ u8 r2_reserved;
410+ u8 r3_reserved;
411+ u8 r2_sx2_reserved;
412+ u8 r3_sx2_reserved;
413+ } phase;
414+};
415+
416+struct mt7915_pfmu_data {
417+ __le16 subc_idx;
418+ __le16 phi11;
419+ __le16 phi21;
420+ __le16 phi31;
421+};
422+
423+struct mt7915_ibf_cal_info {
424+ u8 format_id;
425+ u8 group_l_m_n;
426+ u8 group;
427+ bool sx2;
428+ u8 status;
429+ u8 cal_type;
430+ u8 _rsv[2];
431+ u8 buf[1000];
432+} __packed;
433+
434+enum {
435+ IBF_PHASE_CAL_UNSPEC,
436+ IBF_PHASE_CAL_NORMAL,
437+ IBF_PHASE_CAL_VERIFY,
438+ IBF_PHASE_CAL_NORMAL_INSTRUMENT,
439+ IBF_PHASE_CAL_VERIFY_INSTRUMENT,
440+};
441+
442+#define MT7915_TXBF_SUBCAR_NUM 64
443+
444+#endif
445+
446 enum {
447 MURU_SET_ARB_OP_MODE = 14,
448 MURU_SET_PLATFORM_TYPE = 25,
449diff --git a/mt7915/mmio.c b/mt7915/mmio.c
450index 26881fd..c1b421d 100644
451--- a/mt7915/mmio.c
452+++ b/mt7915/mmio.c
453@@ -131,6 +131,7 @@ static const u32 mt7915_offs[] = {
454 [MDP_BNRCFR1] = 0x074,
455 [ARB_DRNGR0] = 0x194,
456 [ARB_SCR] = 0x080,
457+ [ARB_TQSAXM0] = 0x030,
458 [RMAC_MIB_AIRTIME14] = 0x3b8,
459 [AGG_AALCR0] = 0x048,
460 [AGG_AWSCR0] = 0x05c,
461@@ -207,6 +208,7 @@ static const u32 mt7916_offs[] = {
462 [MDP_BNRCFR1] = 0x094,
463 [ARB_DRNGR0] = 0x1e0,
464 [ARB_SCR] = 0x000,
465+ [ARB_TQSAXM0] = 0x180,
466 [RMAC_MIB_AIRTIME14] = 0x0398,
467 [AGG_AALCR0] = 0x028,
468 [AGG_AWSCR0] = 0x030,
469diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
470index d845206..ab1efe6 100644
471--- a/mt7915/mt7915.h
472+++ b/mt7915/mt7915.h
473@@ -322,7 +322,6 @@ struct mt7915_phy {
474
475 u8 spe_idx;
476
477- bool bf_en;
478 bool bf_ever_en;
479 } test;
480 #endif
481@@ -427,7 +426,7 @@ struct mt7915_dev {
482 void __iomem *dcm;
483 void __iomem *sku;
484
485-#ifdef CONFIG_NL80211_TESTMODE
486+#if defined CONFIG_NL80211_TESTMODE || defined MTK_DEBUG
487 struct {
488 void *txbf_phase_cal;
489 void *txbf_pfmu_data;
490@@ -566,6 +565,7 @@ void mt7915_dma_prefetch(struct mt7915_dev *dev);
491 void mt7915_dma_cleanup(struct mt7915_dev *dev);
492 int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
493 int mt7915_txbf_init(struct mt7915_dev *dev);
494+int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_en);
495 void mt7915_init_txpower(struct mt7915_dev *dev,
496 struct ieee80211_supported_band *sband);
497 void mt7915_reset(struct mt7915_dev *dev);
498@@ -644,8 +644,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
499 int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
500 void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
501 void mt7915_mcu_exit(struct mt7915_dev *dev);
502-int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb);
503+
504+#ifdef CONFIG_NL80211_TESTMODE
505 void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb);
506+#endif
507
508 static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
509 {
510@@ -782,4 +784,10 @@ enum {
511
512 #endif
513
514+#if defined CONFIG_NL80211_TESTMODE || defined MTK_DEBUG
515+int mt7915_mcu_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb);
516+int mt7915_mcu_txbf_profile_tag_read(struct mt7915_phy *phy, u8 pfmu_idx, bool bfer);
517+int mt7915_mcu_txbf_sta_rec_read(struct mt7915_dev *dev, u16 wlan_idx);
518+#endif
519+
520 #endif
521diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
522index 583bc19..a2ceb6f 100644
523--- a/mt7915/mtk_debugfs.c
524+++ b/mt7915/mtk_debugfs.c
525@@ -2831,6 +2831,36 @@ mt7915_txpower_level_set(void *data, u64 val)
526 DEFINE_DEBUGFS_ATTRIBUTE(fops_txpower_level, NULL,
527 mt7915_txpower_level_set, "%lld\n");
528
529+static int
530+mt7915_txbf_pfmu_tag_read(void *data, u64 val)
531+{
532+ struct mt7915_phy *phy = data;
533+ u8 pfmu_idx = (u8)val;
534+
535+ pr_info("%s: %d pfmu_tag cmd sent out ---\n", __func__, __LINE__);
536+ mt7915_mcu_txbf_profile_tag_read(phy, pfmu_idx, true);
537+
538+ return 0;
539+}
540+
541+DEFINE_DEBUGFS_ATTRIBUTE(fops_txbf_pfmu_tag_idx, NULL,
542+ mt7915_txbf_pfmu_tag_read, "%llx\n");
543+
544+static int
545+mt7915_txbf_sta_rec_read(void *data, u64 val)
546+{
547+ struct mt7915_dev *dev = data;
548+ u16 wlan_idx = (u16)val;
549+
550+ pr_info("%s: %d sta_rec cmd sent out ---\n", __func__, __LINE__);
551+ mt7915_mcu_txbf_sta_rec_read(dev, wlan_idx);
552+
553+ return 0;
554+}
555+
556+DEFINE_DEBUGFS_ATTRIBUTE(fops_txbf_sta_rec, NULL,
557+ mt7915_txbf_sta_rec_read, "%llx\n");
558+
559 /* usage: echo 0x[arg3][arg2][arg1] > fw_wa_set */
560 static int
561 mt7915_wa_set(void *data, u64 val)
562@@ -2969,6 +2999,11 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
563 debugfs_create_file("txpower_level", 0400, dir, dev,
564 &fops_txpower_level);
565
566+ debugfs_create_file("txbf_pfmu_tag_idx", 0600, dir, phy,
567+ &fops_txbf_pfmu_tag_idx);
568+ debugfs_create_file("txbf_sta_rec", 0600, dir, dev,
569+ &fops_txbf_sta_rec);
570+
571 debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
572
573 debugfs_create_devm_seqfile(dev->mt76.dev, "fw_version", dir,
574diff --git a/mt7915/mtk_mcu.c b/mt7915/mtk_mcu.c
575index 143dae2..906c872 100644
576--- a/mt7915/mtk_mcu.c
577+++ b/mt7915/mtk_mcu.c
578@@ -1,9 +1,10 @@
579 #include <linux/firmware.h>
580 #include <linux/fs.h>
581-#include<linux/inet.h>
582+#include <linux/inet.h>
583 #include "mt7915.h"
584 #include "mcu.h"
585 #include "mac.h"
586+#include "testmode.h"
587
588 int mt7915_mcu_set_txpower_level(struct mt7915_phy *phy, u8 drop_level)
589 {
590@@ -49,3 +50,246 @@ int mt7915_mcu_set_txpower_level(struct mt7915_phy *phy, u8 drop_level)
591 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
592 sizeof(req), true);
593 }
594+
595+#if defined CONFIG_NL80211_TESTMODE || defined MTK_DEBUG
596+static void mt7915_txbf_dump_pfmu_tag(struct mt7915_dev *dev, struct mt7915_pfmu_tag *tag)
597+{
598+ u32 *raw_t1 = (u32 *)&tag->t1;
599+ u32 *raw_t2 = (u32 *)&tag->t2;
600+
601+ dev_info(dev->mt76.dev, "=================== TXBf Profile Tag1 Info ==================\n");
602+ dev_info(dev->mt76.dev,
603+ "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
604+ raw_t1[0], raw_t1[1], raw_t1[2]);
605+ dev_info(dev->mt76.dev,
606+ "DW4 = 0x%08x, DW5 = 0x%08x, DW6 = 0x%08x\n\n",
607+ raw_t1[3], raw_t1[4], raw_t1[5]);
608+ dev_info(dev->mt76.dev, "PFMU ID = %d Invalid status = %d\n",
609+ tag->t1.pfmu_idx, tag->t1.invalid_prof);
610+ dev_info(dev->mt76.dev, "iBf/eBf = %d\n\n", tag->t1.ebf);
611+ dev_info(dev->mt76.dev, "DBW = %d\n", tag->t1.data_bw);
612+ dev_info(dev->mt76.dev, "SU/MU = %d\n", tag->t1.is_mu);
613+ dev_info(dev->mt76.dev, "RMSD = %d\n", tag->t1.rmsd);
614+ dev_info(dev->mt76.dev,
615+ "nrow = %d, ncol = %d, ng = %d, LM = %d, CodeBook = %d MobCalEn = %d\n",
616+ tag->t1.nr, tag->t1.nc, tag->t1.ngroup, tag->t1.lm, tag->t1.codebook,
617+ tag->t1.mob_cal_en);
618+ dev_info(dev->mt76.dev, "RU start = %d, RU end = %d\n",
619+ tag->t1.ru_start_id, tag->t1.ru_end_id);
620+ dev_info(dev->mt76.dev, "Mem Col1 = %d, Mem Row1 = %d, Mem Col2 = %d, Mem Row2 = %d\n",
621+ tag->t1.col_id1, tag->t1.row_id1, tag->t1.col_id2, tag->t1.row_id2);
622+ dev_info(dev->mt76.dev, "Mem Col3 = %d, Mem Row3 = %d, Mem Col4 = %d, Mem Row4 = %d\n\n",
623+ tag->t1.col_id3, tag->t1.row_id3, tag->t1.col_id4, tag->t1.row_id4);
624+ dev_info(dev->mt76.dev,
625+ "STS0_SNR = 0x%02x, STS1_SNR = 0x%02x, STS2_SNR = 0x%02x, STS3_SNR = 0x%02x\n",
626+ tag->t1.snr_sts0, tag->t1.snr_sts1, tag->t1.snr_sts2, tag->t1.snr_sts3);
627+ dev_info(dev->mt76.dev,
628+ "STS4_SNR = 0x%02x, STS5_SNR = 0x%02x, STS6_SNR = 0x%02x, STS7_SNR = 0x%02x\n",
629+ tag->t1.snr_sts4, tag->t1.snr_sts5, tag->t1.snr_sts6, tag->t1.snr_sts7);
630+ dev_info(dev->mt76.dev, "=============================================================\n");
631+
632+ dev_info(dev->mt76.dev, "=================== TXBf Profile Tag2 Info ==================\n");
633+ dev_info(dev->mt76.dev,
634+ "DW0 = 0x%08x, DW1 = 0x%08x, DW2 = 0x%08x\n",
635+ raw_t2[0], raw_t2[1], raw_t2[2]);
636+ dev_info(dev->mt76.dev,
637+ "DW3 = 0x%08x, DW4 = 0x%08x, DW5 = 0x%08x\n\n",
638+ raw_t2[3], raw_t2[4], raw_t2[5]);
639+ dev_info(dev->mt76.dev, "Smart antenna ID = 0x%x, SE index = %d\n",
640+ tag->t2.smart_ant, tag->t2.se_idx);
641+ dev_info(dev->mt76.dev, "RMSD threshold = %d\n", tag->t2.rmsd_thres);
642+ dev_info(dev->mt76.dev, "Timeout = 0x%x\n", tag->t2.ibf_timeout);
643+ dev_info(dev->mt76.dev, "Desired BW = %d, Desired Ncol = %d, Desired Nrow = %d\n",
644+ tag->t2.ibf_data_bw, tag->t2.ibf_nc, tag->t2.ibf_nr);
645+ dev_info(dev->mt76.dev, "Desired RU Allocation = %d\n", tag->t2.ibf_ru);
646+ dev_info(dev->mt76.dev, "Mobility DeltaT = %d, Mobility LQ = %d\n",
647+ tag->t2.mob_delta_t, tag->t2.mob_lq_result);
648+ dev_info(dev->mt76.dev, "=============================================================\n");
649+}
650+
651+static void mt7915_txbf_dump_sta_rec(struct mt7915_dev *dev, struct sta_rec_bf *sta_info)
652+{
653+ dev_info(dev->mt76.dev, "===================== BF Station Record =====================\n");
654+ dev_info(dev->mt76.dev, "pfmu = %d\n", sta_info->pfmu);
655+ dev_info(dev->mt76.dev, "su_mu = %d\n", sta_info->su_mu);
656+ dev_info(dev->mt76.dev, "bf_cap = %d\n", sta_info->bf_cap);
657+ dev_info(dev->mt76.dev, "sounding_phy = %d\n", sta_info->sounding_phy);
658+ dev_info(dev->mt76.dev, "ndpa_rate = %d\n", sta_info->ndpa_rate);
659+ dev_info(dev->mt76.dev, "ndp_rate = %d\n", sta_info->ndp_rate);
660+ dev_info(dev->mt76.dev, "rept_poll_rate = %d\n", sta_info->rept_poll_rate);
661+ dev_info(dev->mt76.dev, "tx_mode = %d\n", sta_info->tx_mode);
662+ dev_info(dev->mt76.dev, "ncol = %d\n", sta_info->ncol);
663+ dev_info(dev->mt76.dev, "nrow = %d\n", sta_info->nrow);
664+ dev_info(dev->mt76.dev, "bw = %d\n", sta_info->bw);
665+ dev_info(dev->mt76.dev, "mem_total = %d\n", sta_info->mem_total);
666+ dev_info(dev->mt76.dev, "mem_20m = %d\n", sta_info->mem_20m);
667+ dev_info(dev->mt76.dev, "mem_row0 = %d\n", sta_info->mem[0].row);
668+ dev_info(dev->mt76.dev, "mem_col0 = %d\n", sta_info->mem[0].col);
669+ dev_info(dev->mt76.dev, "mem_row1 = %d\n", sta_info->mem[1].row);
670+ dev_info(dev->mt76.dev, "mem_col1 = %d\n", sta_info->mem[1].col);
671+ dev_info(dev->mt76.dev, "mem_row2 = %d\n", sta_info->mem[2].row);
672+ dev_info(dev->mt76.dev, "mem_col2 = %d\n", sta_info->mem[2].col);
673+ dev_info(dev->mt76.dev, "mem_row3 = %d\n", sta_info->mem[3].row);
674+ dev_info(dev->mt76.dev, "mem_col3 = %d\n", sta_info->mem[3].col);
675+ dev_info(dev->mt76.dev, "smart_ant = 0x%x\n", sta_info->smart_ant);
676+ dev_info(dev->mt76.dev, "se_idx = %d\n", sta_info->se_idx);
677+ dev_info(dev->mt76.dev, "auto_sounding = %d\n", sta_info->auto_sounding);
678+ dev_info(dev->mt76.dev, "ibf_timeout = 0x%x\n", sta_info->ibf_timeout);
679+ dev_info(dev->mt76.dev, "ibf_dbw = %d\n", sta_info->ibf_dbw);
680+ dev_info(dev->mt76.dev, "ibf_ncol = %d\n", sta_info->ibf_ncol);
681+ dev_info(dev->mt76.dev, "ibf_nrow = %d\n", sta_info->ibf_nrow);
682+ dev_info(dev->mt76.dev, "nrow_gt_bw80 = %d\n", sta_info->nrow_gt_bw80);
683+ dev_info(dev->mt76.dev, "ncol_gt_bw80 = %d\n", sta_info->ncol_gt_bw80);
684+ dev_info(dev->mt76.dev, "ru_start_idx = %d\n", sta_info->ru_start_idx);
685+ dev_info(dev->mt76.dev, "trigger_su = %d\n", sta_info->trigger_su);
686+ dev_info(dev->mt76.dev, "trigger_mu = %d\n", sta_info->trigger_mu);
687+ dev_info(dev->mt76.dev, "ng16_su = %d\n", sta_info->ng16_su);
688+ dev_info(dev->mt76.dev, "ng16_mu = %d\n", sta_info->ng16_mu);
689+ dev_info(dev->mt76.dev, "codebook42_su = %d\n", sta_info->codebook42_su);
690+ dev_info(dev->mt76.dev, "codebook75_mu = %d\n", sta_info->codebook75_mu);
691+ dev_info(dev->mt76.dev, "he_ltf = %d\n", sta_info->he_ltf);
692+ dev_info(dev->mt76.dev, "=============================================================\n");
693+}
694+
695+static void mt7915_txbf_dump_cal_phase(struct mt7915_dev *dev,
696+ struct mt7915_txbf_phase *phase, int group)
697+{
698+ dev_info(dev->mt76.dev, "Group %d and Group M\n", group);
699+ dev_info(dev->mt76.dev, "m_t0_h = %d\n", phase->phase.m_t0_h);
700+ dev_info(dev->mt76.dev, "m_t1_h = %d\n", phase->phase.m_t1_h);
701+ dev_info(dev->mt76.dev, "m_t2_h = %d\n", phase->phase.m_t2_h);
702+
703+ dev_info(dev->mt76.dev, "r0_uh = %d\n", phase->phase.r0_uh);
704+ dev_info(dev->mt76.dev, "r0_h = %d\n", phase->phase.r0_h);
705+ dev_info(dev->mt76.dev, "r0_m = %d\n", phase->phase.r0_m);
706+ dev_info(dev->mt76.dev, "r0_l = %d\n", phase->phase.r0_l);
707+
708+ dev_info(dev->mt76.dev, "r1_uh = %d\n", phase->phase.r1_uh);
709+ dev_info(dev->mt76.dev, "r1_h = %d\n", phase->phase.r1_h);
710+ dev_info(dev->mt76.dev, "r1_m = %d\n", phase->phase.r1_m);
711+ dev_info(dev->mt76.dev, "r1_l = %d\n", phase->phase.r1_l);
712+
713+ dev_info(dev->mt76.dev, "r2_uh = %d\n", phase->phase.r2_uh);
714+ dev_info(dev->mt76.dev, "r2_h = %d\n", phase->phase.r2_h);
715+ dev_info(dev->mt76.dev, "r2_m = %d\n", phase->phase.r2_m);
716+ dev_info(dev->mt76.dev, "r2_l = %d\n", phase->phase.r2_l);
717+
718+ dev_info(dev->mt76.dev, "r3_uh = %d\n", phase->phase.r3_uh);
719+ dev_info(dev->mt76.dev, "r3_h = %d\n", phase->phase.r3_h);
720+ dev_info(dev->mt76.dev, "r3_m = %d\n", phase->phase.r3_m);
721+ dev_info(dev->mt76.dev, "r3_l = %d\n", phase->phase.r3_l);
722+ dev_info(dev->mt76.dev, "r3_ul = %d\n", phase->phase.r3_ul);
723+}
724+
725+int mt7915_mcu_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
726+{
727+#define BF_PFMU_TAG 16
728+#define BF_STA_REC 20
729+#define BF_CAL_PHASE 21
730+#define GROUP_M 1
731+ u8 format_id;
732+
733+ skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
734+ format_id = *(u8 *)skb->data;
735+
736+ if (format_id == BF_PFMU_TAG) {
737+ struct mt7915_pfmu_tag *pfmu_tag;
738+
739+ skb_pull(skb, 8);
740+ pfmu_tag = (struct mt7915_pfmu_tag *)skb->data;
741+ mt7915_txbf_dump_pfmu_tag(dev, pfmu_tag);
742+ if (dev->test.txbf_pfmu_tag)
743+ memcpy(dev->test.txbf_pfmu_tag, pfmu_tag, sizeof(struct mt7915_pfmu_tag));
744+ } else if (format_id == BF_STA_REC) {
745+ struct sta_rec_bf *sta_rec;
746+
747+ skb_pull(skb, sizeof(struct mt7915_bf_status_hdr));
748+ /* padding 4 byte since bf_status->buf does not contain tag & len */
749+ skb_push(skb, 4);
750+ sta_rec = (struct sta_rec_bf *)skb->data;
751+
752+ mt7915_txbf_dump_sta_rec(dev, sta_rec);
753+ } else if (format_id == BF_CAL_PHASE) {
754+ u8 phase_out_len = sizeof(struct mt7915_txbf_phase_out);
755+ struct mt7915_ibf_cal_info *cal;
756+ struct mt7915_txbf_phase_out phase_out;
757+ struct mt7915_txbf_phase *phase =
758+ (struct mt7915_txbf_phase *)dev->test.txbf_phase_cal;
759+
760+ cal = (struct mt7915_ibf_cal_info *)skb->data;
761+ memcpy(&phase_out, cal->buf, phase_out_len);
762+ switch (cal->cal_type) {
763+ case IBF_PHASE_CAL_NORMAL:
764+ case IBF_PHASE_CAL_NORMAL_INSTRUMENT:
765+ /* Only calibrate group M */
766+ if (cal->group_l_m_n != GROUP_M)
767+ break;
768+ phase = &phase[cal->group];
769+ memcpy(&phase->phase, cal->buf + phase_out_len, sizeof(phase->phase));
770+ phase->status = cal->status;
771+
772+ dev_info(dev->mt76.dev, "Calibrated result = %d\n", phase->status);
773+ mt7915_txbf_dump_cal_phase(dev, phase, cal->group);
774+ break;
775+ case IBF_PHASE_CAL_VERIFY:
776+ case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
777+ dev_info(dev->mt76.dev, "Verification result = %d\n", cal->status);
778+ break;
779+ default:
780+ break;
781+ }
782+
783+ dev_info(dev->mt76.dev, "c0_h = %d, c1_h = %d, c2_h = %d\n",
784+ phase_out.c0_h, phase_out.c1_h, phase_out.c2_h);
785+ dev_info(dev->mt76.dev, "c0_m = %d, c1_m = %d, c2_m = %d\n",
786+ phase_out.c0_m, phase_out.c1_m, phase_out.c2_m);
787+ dev_info(dev->mt76.dev, "c0_l = %d, c1_l = %d, c2_l = %d\n",
788+ phase_out.c0_l, phase_out.c1_l, phase_out.c2_l);
789+ dev_info(dev->mt76.dev, "c3_m = %d, c3_h = %d\n", phase_out.c3_m, phase_out.c3_h);
790+ }
791+
792+ wake_up(&dev->mt76.tx_wait);
793+
794+ return 0;
795+}
796+
797+int mt7915_mcu_txbf_profile_tag_read(struct mt7915_phy *phy, u8 pfmu_idx, bool bfer)
798+{
799+ struct mt7915_dev *dev = phy->dev;
800+ struct {
801+ u8 format_id;
802+ u8 pfmu_idx;
803+ bool bfer;
804+ u8 dbdc_idx;
805+ } __packed req = {
806+ .format_id = MT_BF_PFMU_TAG_READ,
807+ .pfmu_idx = pfmu_idx,
808+ .bfer = bfer,
809+ .dbdc_idx = phy->mt76->band_idx,
810+ };
811+ struct mt7915_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
812+
813+ /* Reset to 0 for mt7915_tm_txbf_profile_tag_write wait_event */
814+ tag->t1.pfmu_idx = 0;
815+
816+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
817+ sizeof(req), true);
818+}
819+
820+int mt7915_mcu_txbf_sta_rec_read(struct mt7915_dev *dev, u16 wlan_idx)
821+{
822+ struct {
823+ u8 action;
824+ u8 wlan_idx_lo;
825+ u8 wlan_idx_hi;
826+ u8 rsv[5];
827+ } __packed req = {
828+ .action = MT_BF_STA_REC_READ,
829+ .wlan_idx_lo = to_wcid_lo(wlan_idx),
830+ .wlan_idx_hi = to_wcid_hi(wlan_idx),
831+ };
832+
833+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
834+ sizeof(req), true);
835+}
836+#endif
837diff --git a/mt7915/regs.h b/mt7915/regs.h
838index f4b5709..007fd4d 100644
839--- a/mt7915/regs.h
840+++ b/mt7915/regs.h
841@@ -61,6 +61,7 @@ enum offs_rev {
842 MDP_BNRCFR1,
843 ARB_DRNGR0,
844 ARB_SCR,
845+ ARB_TQSAXM0,
846 RMAC_MIB_AIRTIME14,
847 AGG_AALCR0,
848 AGG_AWSCR0,
849@@ -530,6 +531,9 @@ enum offs_rev {
850 #define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, (__OFFS(ARB_DRNGR0) + \
851 (_n) * 4))
852
853+#define MT_ARB_TQSAXM0(_band) MT_WF_ARB(_band, __OFFS(ARB_TQSAXM0))
854+#define MT_ARB_TQSAXM_ALTX_START_MASK GENMASK(12, 8)
855+
856 /* RMAC: band 0(0x820e5000), band 1(0x820f5000) */
857 #define MT_WF_RMAC_BASE(_band) ((_band) ? 0x820f5000 : 0x820e5000)
858 #define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs))
859diff --git a/mt7915/testmode.c b/mt7915/testmode.c
developerdad04b12022-12-22 16:47:31 +0800860index 2ae6c07..e4af5e1 100644
developerc5ce7502022-12-19 11:33:22 +0800861--- a/mt7915/testmode.c
862+++ b/mt7915/testmode.c
863@@ -53,6 +53,8 @@ struct reg_band {
864 static struct reg_band reg_backup_list[TM_REG_MAX_ID];
865
866 static void mt7915_tm_update_entry(struct mt7915_phy *phy);
867+static int mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode, bool bf_sounding);
868+static int mt7915_tm_txbf_set_rate(struct mt7915_phy *phy, struct mt76_wcid *wcid);
869
870 static u8 mt7915_tm_chan_bw(enum nl80211_chan_width width)
871 {
872@@ -73,6 +75,25 @@ static u8 mt7915_tm_chan_bw(enum nl80211_chan_width width)
873 return width_to_bw[width];
874 }
875
876+static u8 mt7915_tm_rate_to_phy(u8 tx_rate_mode)
877+{
878+ static const u8 rate_to_phy[] = {
879+ [MT76_TM_TX_MODE_CCK] = MT_PHY_TYPE_CCK,
880+ [MT76_TM_TX_MODE_OFDM] = MT_PHY_TYPE_OFDM,
881+ [MT76_TM_TX_MODE_HT] = MT_PHY_TYPE_HT,
882+ [MT76_TM_TX_MODE_VHT] = MT_PHY_TYPE_VHT,
883+ [MT76_TM_TX_MODE_HE_SU] = MT_PHY_TYPE_HE_SU,
884+ [MT76_TM_TX_MODE_HE_EXT_SU] = MT_PHY_TYPE_HE_EXT_SU,
885+ [MT76_TM_TX_MODE_HE_TB] = MT_PHY_TYPE_HE_TB,
886+ [MT76_TM_TX_MODE_HE_MU] = MT_PHY_TYPE_HE_MU,
887+ };
888+
889+ if (tx_rate_mode > MT76_TM_TX_MODE_MAX)
890+ return -EINVAL;
891+
892+ return rate_to_phy[tx_rate_mode];
893+}
894+
895 static void
896 mt7915_tm_update_channel(struct mt7915_phy *phy)
897 {
898@@ -273,17 +294,33 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
899 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
900 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
901 struct mt7915_dev *dev = phy->dev;
902+ struct mt76_testmode_data *td = &phy->mt76->test;
903 struct sk_buff *skb;
904 struct sta_rec_bf *bf;
905 struct tlv *tlv;
906- u8 ndp_rate;
907+ u8 ndp_rate, ndpa_rate, rept_poll_rate, bf_bw;
908+
909+ if (td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU) {
910+ rept_poll_rate = 0x49;
911+ ndpa_rate = 0x49;
912+ ndp_rate = 0;
913+ } else if (td->tx_rate_mode == MT76_TM_TX_MODE_VHT) {
914+ rept_poll_rate = 0x9;
915+ ndpa_rate = 0x9;
916+ ndp_rate = 0;
917+ } else {
918+ rept_poll_rate = 0;
919+ ndpa_rate = 0;
920+ if (nr == 1)
921+ ndp_rate = 8;
922+ else if (nr == 2)
923+ ndp_rate = 16;
924+ else
925+ ndp_rate = 24;
926+ }
927
928- if (nr == 1)
929- ndp_rate = 8;
930- else if (nr == 2)
931- ndp_rate = 16;
932- else
933- ndp_rate = 24;
developerdad04b12022-12-22 16:47:31 +0800934+ /* BF use CMD_CBW instead of TM_CBW */
935+ bf_bw = mt76_connac_chan_bw(&phy->mt76->chandef);
developerc5ce7502022-12-19 11:33:22 +0800936
937 skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
938 &msta->wcid);
939@@ -299,8 +336,11 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
940 bf->ncol = nc;
941 bf->nrow = nr;
942 bf->ndp_rate = ndp_rate;
943+ bf->ndpa_rate = ndpa_rate;
944+ bf->rept_poll_rate = rept_poll_rate;
945+ bf->bw = bf_bw;
946 bf->ibf_timeout = 0xff;
947- bf->tx_mode = MT_PHY_TYPE_HT;
948+ bf->tx_mode = mt7915_tm_rate_to_phy(td->tx_rate_mode);
949
950 if (ebf) {
951 bf->mem[0].row = 0;
952@@ -353,11 +393,8 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
953 }
954
955 memcpy(sta->addr, ed->addr[0], ETH_ALEN);
956- if (phy->test.bf_en) {
957- u8 addr[ETH_ALEN] = {0x00, 0x11, 0x11, 0x11, 0x11, 0x11};
958-
959- memcpy(sta->addr, addr, ETH_ALEN);
960- }
961+ if (td->bf_en)
962+ memcpy(sta->addr, td->addr[0], ETH_ALEN);
963
964 if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT)
965 memcpy(&sta->deflink.ht_cap, &sband->ht_cap, sizeof(sta->deflink.ht_cap));
966@@ -382,6 +419,14 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
967 list_add_tail(&msta->wcid.list, &td->tm_entry_list);
968 td->entry_num++;
969
970+ mt7915_mcu_add_bss_info(phy, phy->monitor_vif, true);
971+
972+ if (td->bf_en) {
973+ mt7915_tm_set_ipg_params(phy, td->tx_ipg, td->tx_rate_mode, true);
974+ mt7915_tm_set_tam_arb(phy, td->bf_en, 0);
975+ mt7915_tm_txbf_set_rate(phy, &msta->wcid);
976+ }
977+
978 return 0;
979 }
980
981@@ -451,7 +496,7 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
982 struct mt76_testmode_entry_data *ed, tmp;
983 struct mt76_wcid *wcid, *last;
984
985- if (!td->aid || phy->test.bf_en)
986+ if (!td->aid || td->bf_en)
987 return;
988
989 memcpy(&tmp, &td->ed, sizeof(tmp));
990@@ -472,20 +517,30 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
991 static int
992 mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
993 {
994+#define EBF_BBP_RX_OFFSET 0x10280
995+#define EBF_BBP_RX_ENABLE (BIT(0) | BIT(15))
developerdad04b12022-12-22 16:47:31 +0800996+#define WF1 1
997+#define WF2 2
developerc5ce7502022-12-19 11:33:22 +0800998 struct mt76_testmode_data *td = &phy->mt76->test;
999 struct mt7915_dev *dev = phy->dev;
1000+ struct mt76_phy *mphy = phy->mt76;
1001 bool enable = val[0];
1002 void *phase_cal, *pfmu_data, *pfmu_tag;
1003- u8 addr[ETH_ALEN] = {0x00, 0x22, 0x22, 0x22, 0x22, 0x22};
1004+ u8 sub_addr = td->is_txbf_dut ? TXBF_DUT_MAC_SUBADDR : TXBF_GOLDEN_MAC_SUBADDR;
1005+ u8 peer_addr = td->is_txbf_dut ? TXBF_GOLDEN_MAC_SUBADDR : TXBF_DUT_MAC_SUBADDR;
1006+ u8 bss_addr = TXBF_DUT_MAC_SUBADDR;
1007+ u8 addr[ETH_ALEN] = {0x00, sub_addr, sub_addr, sub_addr, sub_addr, sub_addr};
1008+ u8 bssid[ETH_ALEN] = {0x00, bss_addr, bss_addr, bss_addr, bss_addr, bss_addr};
1009+ u8 peer_addrs[ETH_ALEN] = {0x00, peer_addr, peer_addr, peer_addr, peer_addr, peer_addr};
1010
1011 if (!enable) {
1012- phy->test.bf_en = 0;
1013+ td->bf_en = 0;
1014 return 0;
1015 }
1016
1017 if (!dev->test.txbf_phase_cal) {
1018 phase_cal = devm_kzalloc(dev->mt76.dev,
1019- sizeof(struct mt7915_tm_txbf_phase) *
1020+ sizeof(struct mt7915_txbf_phase) *
1021 MAX_PHASE_GROUP_NUM,
1022 GFP_KERNEL);
1023 if (!phase_cal)
1024@@ -495,7 +550,10 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
1025 }
1026
1027 if (!dev->test.txbf_pfmu_data) {
1028- pfmu_data = devm_kzalloc(dev->mt76.dev, 512, GFP_KERNEL);
1029+ pfmu_data = devm_kzalloc(dev->mt76.dev,
1030+ sizeof(struct mt7915_pfmu_data) *
1031+ MT7915_TXBF_SUBCAR_NUM,
1032+ GFP_KERNEL);
1033 if (!pfmu_data)
1034 return -ENOMEM;
1035
1036@@ -504,21 +562,77 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
1037
1038 if (!dev->test.txbf_pfmu_tag) {
1039 pfmu_tag = devm_kzalloc(dev->mt76.dev,
1040- sizeof(struct mt7915_tm_pfmu_tag), GFP_KERNEL);
1041+ sizeof(struct mt7915_pfmu_tag), GFP_KERNEL);
1042 if (!pfmu_tag)
1043 return -ENOMEM;
1044
1045 dev->test.txbf_pfmu_tag = pfmu_tag;
1046 }
1047
1048+ td->bf_en = 1;
1049+ memcpy(td->addr[0], peer_addrs, ETH_ALEN);
1050+ memcpy(td->addr[1], addr, ETH_ALEN);
1051+ memcpy(td->addr[2], bssid, ETH_ALEN);
1052 memcpy(phy->monitor_vif->addr, addr, ETH_ALEN);
1053 mt7915_mcu_add_dev_info(phy, phy->monitor_vif, true);
1054
1055- td->tx_rate_mode = MT76_TM_TX_MODE_HT;
1056- td->tx_mpdu_len = 1024;
1057- td->tx_rate_sgi = 0;
1058- td->tx_ipg = 100;
1059- phy->test.bf_en = 1;
1060+ /* Add second interface in wtbl for using TXCMD to transmit sounding */
1061+ td->second_vif = kzalloc(sizeof(*td->second_vif) + sizeof(struct mt7915_vif), GFP_KERNEL);
1062+ memcpy(td->second_vif, phy->monitor_vif, sizeof(*td->second_vif));
1063+ mt7915_init_vif(phy, td->second_vif, td->bf_en);
1064+
1065+ if (td->ebf && !td->is_txbf_dut) {
developerdad04b12022-12-22 16:47:31 +08001066+ u8 is_160hz = val[1];
developerc5ce7502022-12-19 11:33:22 +08001067+
1068+ /* Turn On BBP CR for RX */
1069+ mt76_set(dev, EBF_BBP_RX_OFFSET, EBF_BBP_RX_ENABLE);
1070+ dev_info(dev->mt76.dev, "Set BBP RX CR = %x\n", mt76_rr(dev, EBF_BBP_RX_OFFSET));
1071+
1072+ /* Set TX antenna mask of golden: default use WF0 only */
1073+ td->tx_antenna_mask = 1;
1074+ if (is_mt7915(&dev->mt76)) {
1075+ /* Add WF1/WF2 for dbdc/single band in BW 160 */
developerdad04b12022-12-22 16:47:31 +08001076+ td->tx_antenna_mask |= is_160hz << (dev->dbdc_support ? WF1 : WF2);
developerc5ce7502022-12-19 11:33:22 +08001077+ /* Shift to WF2/WF3 for dbdc band 1 */
1078+ td->tx_antenna_mask <<= 2 * phy->mt76->band_idx;
1079+ }
1080+ } else if (td->ebf && td->is_txbf_dut) {
1081+ /* Enable ETxBF Capability */
1082+ dev->ibf = false;
1083+ mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
1084+ /* Set TX antenna mask of DUT */
1085+ td->tx_antenna_mask = mphy->chainmask >> (dev->chainshift * phy->mt76->band_idx);
1086+ td->tx_spe_idx = phy->mt76->band_idx ? 25 : 24;
1087+ /* Shift to WF2/WF3 for dbdc band 1, Nss = 2 */
1088+ if ((hweight8(td->tx_antenna_mask) == 2) && phy->mt76->band_idx)
1089+ td->tx_antenna_mask <<= 2;
1090+ } else {
1091+ if (td->is_txbf_dut) {
1092+ int nss;
1093+
1094+ /* Enable ITxBF Capability */
1095+ dev->ibf = true;
1096+ mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
1097+ td->tx_antenna_mask = mphy->chainmask >> (dev->chainshift *
1098+ phy->mt76->band_idx);
1099+ nss = hweight8(td->tx_antenna_mask);
1100+ if (nss > 1 && nss <= 4)
1101+ td->tx_rate_idx = 15 + 8 * (nss - 2);
1102+ else
1103+ td->tx_rate_idx = 31;
1104+ } else {
1105+ td->tx_antenna_mask = 1;
1106+ mt76_set(dev, EBF_BBP_RX_OFFSET, EBF_BBP_RX_ENABLE);
1107+ dev_info(dev->mt76.dev, "Set BBP RX CR = %x\n",
1108+ mt76_rr(dev, EBF_BBP_RX_OFFSET));
1109+ }
1110+ td->tx_rate_mode = MT76_TM_TX_MODE_HT;
1111+ td->tx_mpdu_len = 1024;
1112+ td->tx_rate_sgi = 0;
1113+ td->tx_ipg = 100;
1114+ }
1115+
1116+ mt7915_mcu_add_bss_info(phy, phy->monitor_vif, true);
1117
1118 return mt7915_tm_set_trx(phy, TM_MAC_TX, true);
1119 }
1120@@ -545,8 +659,7 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
1121 .read_from_e2p = val[3],
1122 .disable = val[4],
1123 };
1124- struct mt7915_tm_txbf_phase *phase =
1125- (struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
1126+ struct mt7915_txbf_phase *phase = (struct mt7915_txbf_phase *)dev->test.txbf_phase_cal;
1127
1128 wait_event_timeout(dev->mt76.tx_wait, phase[val[2]].status != 0, HZ);
1129 memcpy(req.buf, &phase[val[2]].phase, sizeof(req.buf));
1130@@ -559,32 +672,9 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
1131 sizeof(req), true);
1132 }
1133
1134-static int
1135-mt7915_tm_txbf_profile_tag_read(struct mt7915_phy *phy, u8 pfmu_idx)
1136-{
1137- struct mt7915_dev *dev = phy->dev;
1138- struct {
1139- u8 format_id;
1140- u8 pfmu_idx;
1141- bool bfer;
1142- u8 dbdc_idx;
1143- } __packed req = {
1144- .format_id = MT_BF_PFMU_TAG_READ,
1145- .pfmu_idx = pfmu_idx,
1146- .bfer = 1,
1147- .dbdc_idx = phy != &dev->phy,
1148- };
1149- struct mt7915_tm_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
1150-
1151- tag->t1.pfmu_idx = 0;
1152-
1153- return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
1154- sizeof(req), true);
1155-}
1156-
1157 static int
1158 mt7915_tm_txbf_profile_tag_write(struct mt7915_phy *phy, u8 pfmu_idx,
1159- struct mt7915_tm_pfmu_tag *tag)
1160+ struct mt7915_pfmu_tag *tag)
1161 {
1162 struct mt7915_dev *dev = phy->dev;
1163 struct {
1164@@ -611,8 +701,6 @@ static int
1165 mt7915_tm_txbf_apply_tx(struct mt7915_phy *phy, u16 wlan_idx, bool ebf,
1166 bool ibf, bool phase_cal)
1167 {
1168-#define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id)
1169-#define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id)
1170 struct mt7915_dev *dev = phy->dev;
1171 struct {
1172 u8 category;
1173@@ -641,14 +729,15 @@ static int mt7915_tm_txbf_set_rate(struct mt7915_phy *phy,
1174 {
1175 struct mt7915_dev *dev = phy->dev;
1176 struct mt76_testmode_entry_data *ed = mt76_testmode_entry_data(phy->mt76, wcid);
1177+ struct mt76_testmode_data *td = &phy->mt76->test;
1178 struct ieee80211_sta *sta = wcid_to_sta(wcid);
1179 struct sta_phy rate = {};
1180
1181 if (!sta)
1182 return 0;
1183
1184- rate.type = MT_PHY_TYPE_HT;
1185- rate.bw = mt7915_tm_chan_bw(phy->mt76->chandef.width);
1186+ rate.type = mt7915_tm_rate_to_phy(td->tx_rate_mode);
developerdad04b12022-12-22 16:47:31 +08001187+ rate.bw = mt76_connac_chan_bw(&phy->mt76->chandef);
developerc5ce7502022-12-19 11:33:22 +08001188 rate.nss = ed->tx_rate_nss;
1189 rate.mcs = ed->tx_rate_idx;
1190 rate.ldpc = (rate.bw || ed->tx_rate_ldpc) * GENMASK(2, 0);
1191@@ -662,13 +751,14 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
1192 {
1193 bool bf_on = val[0], update = val[3];
1194 /* u16 wlan_idx = val[2]; */
1195- struct mt7915_tm_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
1196+ struct mt7915_dev *dev = phy->dev;
1197+ struct mt7915_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
1198 struct mt76_testmode_data *td = &phy->mt76->test;
1199 struct mt76_wcid *wcid;
1200
1201 if (bf_on) {
1202 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
1203- mt7915_tm_txbf_profile_tag_read(phy, 2);
1204+ mt7915_mcu_txbf_profile_tag_read(phy, 2, true);
1205 tag->t1.invalid_prof = false;
1206 mt7915_tm_txbf_profile_tag_write(phy, 2, tag);
1207
1208@@ -683,7 +773,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
1209 } else {
1210 phy->test.bf_ever_en = false;
1211
1212- mt7915_tm_txbf_profile_tag_read(phy, 2);
1213+ mt7915_mcu_txbf_profile_tag_read(phy, 2, true);
1214 tag->t1.invalid_prof = true;
1215 mt7915_tm_txbf_profile_tag_write(phy, 2, tag);
1216 }
1217@@ -698,6 +788,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
1218 static int
1219 mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
1220 {
1221+#define MT_ARB_IBF_ENABLE (BIT(0) | GENMASK(9, 8))
1222 static const u8 mode_to_lm[] = {
1223 [MT76_TM_TX_MODE_CCK] = 0,
1224 [MT76_TM_TX_MODE_OFDM] = 0,
1225@@ -711,7 +802,8 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
1226 struct mt76_testmode_data *td = &phy->mt76->test;
1227 struct mt76_wcid *wcid;
1228 struct ieee80211_vif *vif = phy->monitor_vif;
1229- struct mt7915_tm_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
1230+ struct mt7915_dev *dev = phy->dev;
1231+ struct mt7915_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
1232 u8 pfmu_idx = val[0], nc = val[2], nr;
1233 bool is_atenl = val[6];
1234 int ret;
developerdad04b12022-12-22 16:47:31 +08001235@@ -729,18 +821,22 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
developerc5ce7502022-12-19 11:33:22 +08001236 tag->t1.nr = nr;
1237 tag->t1.nc = nc;
1238 tag->t1.invalid_prof = true;
1239-
1240- tag->t1.snr_sts4 = 0xc0;
1241- tag->t1.snr_sts5 = 0xff;
1242- tag->t1.snr_sts6 = 0xff;
1243- tag->t1.snr_sts7 = 0xff;
developerdad04b12022-12-22 16:47:31 +08001244+ tag->t1.data_bw = mt76_connac_chan_bw(&phy->mt76->chandef);
developerc5ce7502022-12-19 11:33:22 +08001245+ tag->t2.se_idx = td->tx_spe_idx;
1246+
1247+ if (is_atenl) {
1248+ tag->t1.snr_sts4 = 0xc0;
1249+ tag->t1.snr_sts5 = 0xff;
1250+ tag->t1.snr_sts6 = 0xff;
1251+ tag->t1.snr_sts7 = 0xff;
1252+ }
1253
1254 if (ebf) {
1255 tag->t1.row_id1 = 0;
developerdad04b12022-12-22 16:47:31 +08001256 tag->t1.row_id2 = 1;
1257 tag->t1.row_id3 = 2;
1258 tag->t1.row_id4 = 3;
1259- tag->t1.lm = mode_to_lm[MT76_TM_TX_MODE_HT];
1260+ tag->t1.lm = mode_to_lm[td->tx_rate_mode];
1261 } else {
1262 tag->t1.row_id1 = 4;
1263 tag->t1.row_id2 = 5;
developerc5ce7502022-12-19 11:33:22 +08001264@@ -761,6 +857,19 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
1265 if (ret)
1266 return ret;
1267
1268+ if (td->ebf) {
1269+ mt76_set(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx), MT_ARB_TQSAXM_ALTX_START_MASK);
1270+ dev_info(dev->mt76.dev, "Set TX queue start CR for AX management (0x%x) = 0x%x\n",
1271+ MT_ARB_TQSAXM0(phy->mt76->band_idx),
1272+ mt76_rr(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx)));
1273+ } else if (!td->ebf && ebf) {
1274+ /* iBF's ebf profile update */
1275+ mt76_set(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx), MT_ARB_IBF_ENABLE);
1276+ dev_info(dev->mt76.dev, "Set TX queue start CR for AX management (0x%x) = 0x%x\n",
1277+ MT_ARB_TQSAXM0(phy->mt76->band_idx),
1278+ mt76_rr(dev, MT_ARB_TQSAXM0(phy->mt76->band_idx)));
1279+ }
1280+
1281 if (!ebf && is_atenl)
1282 return mt7915_tm_txbf_apply_tx(phy, 1, false, true, true);
1283
1284@@ -778,7 +887,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
1285 u8 category;
1286 u8 group_l_m_n;
1287 u8 group;
1288- bool sx2;
1289+ bool dbdc_idx;
1290 u8 cal_type;
1291 u8 lna_gain_level;
1292 u8 _rsv[2];
1293@@ -786,12 +895,12 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
1294 .category = MT_BF_PHASE_CAL,
1295 .group = val[0],
1296 .group_l_m_n = val[1],
1297- .sx2 = val[2],
1298+ .dbdc_idx = phy->mt76->band_idx,
1299 .cal_type = val[3],
1300 .lna_gain_level = val[4],
1301 };
1302- struct mt7915_tm_txbf_phase *phase =
1303- (struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
1304+ struct mt7915_txbf_phase *phase =
1305+ (struct mt7915_txbf_phase *)dev->test.txbf_phase_cal;
1306
1307 phase[req.group].status = 0;
1308
1309@@ -799,53 +908,10 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
1310 sizeof(req), true);
1311 }
1312
1313-int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
1314-{
1315-#define BF_PFMU_TAG 16
1316-#define BF_CAL_PHASE 21
1317- u8 format_id;
1318-
1319- skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
1320- format_id = *(u8 *)skb->data;
1321-
1322- if (format_id == BF_PFMU_TAG) {
1323- struct mt7915_tm_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
1324-
1325- skb_pull(skb, 8);
1326- memcpy(tag, skb->data, sizeof(struct mt7915_tm_pfmu_tag));
1327- } else if (format_id == BF_CAL_PHASE) {
1328- struct mt7915_tm_ibf_cal_info *cal;
1329- struct mt7915_tm_txbf_phase *phase =
1330- (struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
1331-
1332- cal = (struct mt7915_tm_ibf_cal_info *)skb->data;
1333- switch (cal->cal_type) {
1334- case IBF_PHASE_CAL_NORMAL:
1335- case IBF_PHASE_CAL_NORMAL_INSTRUMENT:
1336- if (cal->group_l_m_n != GROUP_M)
1337- break;
1338- phase = &phase[cal->group];
1339- memcpy(&phase->phase, cal->buf + 16, sizeof(phase->phase));
1340- phase->status = cal->status;
1341- /* for passing iTest script */
1342- dev_info(dev->mt76.dev, "Calibrated result = %d\n", phase->status);
1343- break;
1344- case IBF_PHASE_CAL_VERIFY:
1345- case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
1346- break;
1347- default:
1348- break;
1349- }
1350- }
1351-
1352- wake_up(&dev->mt76.tx_wait);
1353-
1354- return 0;
1355-}
1356-
1357 static int
1358 mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
1359 {
1360+#define MT7915_TXBF_PFMU_DATA_LEN (MT7915_TXBF_SUBCAR_NUM * sizeof(struct mt7915_pfmu_data))
1361 struct mt76_testmode_data *td = &phy->mt76->test;
1362 u16 pfmu_idx = val[0];
1363 u16 subc_id = val[1];
1364@@ -854,9 +920,9 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
1365 u16 angle31 = val[4];
1366 u16 angle41 = val[5];
1367 s16 phi11 = 0, phi21 = 0, phi31 = 0;
1368- struct mt7915_tm_pfmu_data *pfmu_data;
1369+ struct mt7915_pfmu_data *pfmu_data;
1370
1371- if (subc_id > 63)
1372+ if (subc_id > MT7915_TXBF_SUBCAR_NUM - 1)
1373 return -EINVAL;
1374
1375 if (td->tx_antenna_mask == 2) {
1376@@ -870,7 +936,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
1377 phi31 = (s16)(angle41 - angle31);
1378 }
1379
1380- pfmu_data = (struct mt7915_tm_pfmu_data *)phy->dev->test.txbf_pfmu_data;
1381+ pfmu_data = (struct mt7915_pfmu_data *)phy->dev->test.txbf_pfmu_data;
1382 pfmu_data = &pfmu_data[subc_id];
1383
1384 if (subc_id < 32)
1385@@ -880,21 +946,21 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
1386 pfmu_data->phi11 = cpu_to_le16(phi11);
1387 pfmu_data->phi21 = cpu_to_le16(phi21);
1388 pfmu_data->phi31 = cpu_to_le16(phi31);
1389- if (subc_id == 63) {
1390+ if (subc_id == MT7915_TXBF_SUBCAR_NUM - 1) {
1391 struct mt7915_dev *dev = phy->dev;
1392 struct {
1393 u8 format_id;
1394 u8 pfmu_idx;
1395 u8 dbdc_idx;
1396 u8 _rsv;
1397- u8 buf[512];
1398+ u8 buf[MT7915_TXBF_PFMU_DATA_LEN];
1399 } __packed req = {
1400 .format_id = MT_BF_PROFILE_WRITE_ALL,
1401 .pfmu_idx = pfmu_idx,
1402 .dbdc_idx = phy != &dev->phy,
1403 };
1404
1405- memcpy(req.buf, dev->test.txbf_pfmu_data, 512);
1406+ memcpy(req.buf, dev->test.txbf_pfmu_data, MT7915_TXBF_PFMU_DATA_LEN);
1407
1408 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
1409 &req, sizeof(req), true);
1410@@ -906,7 +972,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
1411 static int
1412 mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
1413 {
1414- struct mt7915_tm_txbf_phase *phase, *p;
1415+ struct mt7915_txbf_phase *phase, *p;
1416 struct mt7915_dev *dev = phy->dev;
1417 u8 *eeprom = dev->mt76.eeprom.data;
1418 u16 offset;
1419@@ -916,7 +982,7 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
1420 is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
1421 offset = is_7976 ? 0x60a : 0x651;
1422
1423- phase = (struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
1424+ phase = (struct mt7915_txbf_phase *)dev->test.txbf_phase_cal;
1425 for (i = 0; i < MAX_PHASE_GROUP_NUM; i++) {
1426 p = &phase[i];
1427
1428@@ -931,17 +997,75 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
1429 return 0;
1430 }
1431
1432+static int
1433+mt7915_tm_trigger_sounding(struct mt7915_phy *phy, u16 *val, bool en)
1434+{
1435+ struct mt7915_dev *dev = phy->dev;
1436+ u8 sounding_mode = val[0];
1437+ u8 MU_num = val[1];
1438+ u32 sounding_interval = (u32)val[2] << 2; /* input unit: 4ms */
1439+ enum sounding_mode {
1440+ SU_SOUNDING,
1441+ MU_SOUNDING,
1442+ SU_PERIODIC_SOUNDING,
1443+ MU_PERIODIC_SOUNDING,
1444+ BF_PROCESSING,
1445+ TXCMD_NONTB_SU_SOUNDING,
1446+ TXCMD_VHT_MU_SOUNDING,
1447+ TXCMD_TB_PER_BRP_SOUNDING,
1448+ TXCMD_TB_SOUNDING,
1449+
1450+ /* keep last */
1451+ NUM_SOUNDING_MODE,
1452+ SOUNDING_MODE_MAX = NUM_SOUNDING_MODE - 1,
1453+ };
1454+ struct {
1455+ u8 cmd_category_id;
1456+ u8 sounding_mode;
1457+ u8 MU_num;
1458+ u8 rsv;
1459+ u8 wlan_idx[4];
1460+ u32 sounding_interval; /* unit: ms */
1461+ } __packed req = {
1462+ .cmd_category_id = en ? MT_BF_SOUNDING_ON : MT_BF_SOUNDING_OFF,
1463+ .sounding_mode = sounding_mode,
1464+ .MU_num = MU_num,
1465+ .sounding_interval = cpu_to_le32(sounding_interval),
1466+ .wlan_idx[0] = val[3],
1467+ .wlan_idx[1] = val[4],
1468+ .wlan_idx[2] = val[5],
1469+ .wlan_idx[3] = val[6],
1470+ };
1471+
1472+ if (sounding_mode > SOUNDING_MODE_MAX)
1473+ return -EINVAL;
1474+
1475+ /* Enable Tx MAC HW before trigger sounding */
1476+ if (en)
1477+ mt7915_tm_set_trx(phy, TM_MAC_TX, true);
1478+
1479+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
1480+ &req, sizeof(req), true);
1481+}
1482+
1483 static int
1484 mt7915_tm_set_txbf(struct mt7915_phy *phy)
1485 {
1486+#define TXBF_IS_DUT_MASK BIT(0)
1487+#define TXBF_EBF_MASK BIT(1)
1488 struct mt76_testmode_data *td = &phy->mt76->test;
1489 u16 *val = td->txbf_param;
1490
1491- pr_info("ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u\n",
1492- td->txbf_act, val[0], val[1], val[2], val[3], val[4], val[5]);
1493+ dev_info(phy->dev->mt76.dev, "ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u\n",
1494+ td->txbf_act, val[0], val[1], val[2], val[3], val[4], val[5], val[6]);
1495
1496 switch (td->txbf_act) {
1497+ case MT76_TM_TXBF_ACT_GOLDEN_INIT:
1498 case MT76_TM_TXBF_ACT_INIT:
1499+ case MT76_TM_TX_EBF_ACT_GOLDEN_INIT:
1500+ case MT76_TM_TX_EBF_ACT_INIT:
1501+ td->ebf = !!u32_get_bits(td->txbf_act, TXBF_EBF_MASK);
1502+ td->is_txbf_dut = !!u32_get_bits(td->txbf_act, TXBF_IS_DUT_MASK);
1503 return mt7915_tm_txbf_init(phy, val);
1504 case MT76_TM_TXBF_ACT_UPDATE_CH:
1505 mt7915_tm_update_channel(phy);
1506@@ -967,6 +1091,36 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
1507
1508 return mt7915_tm_txbf_apply_tx(phy, wlan_idx, ebf, ibf, phase_cal);
1509 }
1510+ case MT76_TM_TXBF_ACT_TRIGGER_SOUNDING:
1511+ return mt7915_tm_trigger_sounding(phy, val, true);
1512+ case MT76_TM_TXBF_ACT_STOP_SOUNDING:
1513+ memset(val, 0, sizeof(td->txbf_param));
1514+ return mt7915_tm_trigger_sounding(phy, val, false);
1515+ case MT76_TM_TXBF_ACT_PROFILE_TAG_READ:
1516+ case MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE:
1517+ case MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID: {
1518+ u8 pfmu_idx = val[0];
1519+ bool bfer = !!val[1];
1520+ struct mt7915_dev *dev = phy->dev;
1521+ struct mt7915_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
1522+
1523+ if (!tag) {
1524+ dev_err(dev->mt76.dev,
1525+ "pfmu tag is not initialized!\n");
1526+ return 0;
1527+ }
1528+
1529+ if (td->txbf_act == MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE)
1530+ return mt7915_tm_txbf_profile_tag_write(phy, pfmu_idx, tag);
1531+ else if (td->txbf_act == MT76_TM_TXBF_ACT_PROFILE_TAG_READ)
1532+ return mt7915_mcu_txbf_profile_tag_read(phy, pfmu_idx, bfer);
1533+
1534+ tag->t1.invalid_prof = !!val[0];
1535+
1536+ return 0;
1537+ }
1538+ case MT76_TM_TXBF_ACT_STA_REC_READ:
1539+ return mt7915_mcu_txbf_sta_rec_read(phy->dev, val[0]);
1540 default:
1541 break;
1542 };
1543@@ -1186,9 +1340,10 @@ mt7915_tm_set_ipi(struct mt7915_phy *phy)
1544
1545 static int
1546 mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
1547- u16 cw_max, u16 txop, u8 tx_cmd)
1548+ u16 cw_max, u16 txop, u8 tx_cmd, bool bf_sounding)
1549 {
1550- struct mt7915_vif *mvif = (struct mt7915_vif *)phy->monitor_vif->drv_priv;
1551+ struct mt76_testmode_data *td = &phy->mt76->test;
1552+ struct mt7915_vif *mvif;
1553 struct mt7915_mcu_tx req = {
1554 .valid = true,
1555 .mode = tx_cmd,
1556@@ -1196,6 +1351,9 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
1557 };
1558 struct edca *e = &req.edca[0];
1559
1560+ mvif = bf_sounding ? (struct mt7915_vif *)td->second_vif->drv_priv :
1561+ (struct mt7915_vif *)phy->monitor_vif->drv_priv;
1562+
1563 e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
1564 e->set = WMM_PARAM_SET;
1565
1566@@ -1208,17 +1366,19 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
1567 }
1568
1569 static int
1570-mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
1571+mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode, bool bf_sounding)
1572 {
1573 #define TM_DEFAULT_SIFS 10
1574 #define TM_MAX_SIFS 127
1575 #define TM_MAX_AIFSN 0xf
1576 #define TM_MIN_AIFSN 0x1
1577 #define BBP_PROC_TIME 1500
1578+#define TM_DEFAULT_CW 1
1579 struct mt7915_dev *dev = phy->dev;
1580 u8 sig_ext = (mode == MT76_TM_TX_MODE_CCK) ? 0 : 6;
1581 u8 slot_time = 9, sifs = TM_DEFAULT_SIFS;
1582 u8 aifsn = TM_MIN_AIFSN;
1583+ bool tx_cmd;
1584 u8 band = phy->mt76->band_idx;
1585 u32 i2t_time, tr2t_time, txv_time;
1586 u16 cw = 0;
1587@@ -1232,6 +1392,7 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
1588 ipg -= sig_ext;
1589
1590 if (ipg <= (TM_MAX_SIFS + slot_time)) {
1591+ cw = TM_DEFAULT_CW;
1592 sifs = ipg - slot_time;
1593 } else {
1594 u32 val = (ipg + slot_time) / slot_time;
1595@@ -1267,10 +1428,12 @@ done:
1596
1597 mt7915_tm_set_slot_time(phy, slot_time, sifs);
1598
1599+ /* HE MU data and iBF/eBF sounding packet use TXCMD */
1600+ tx_cmd = (mode == MT76_TM_TX_MODE_HE_MU) || bf_sounding;
1601+
1602 return mt7915_tm_set_wmm_qid(phy,
1603 mt76_connac_lmac_mapping(IEEE80211_AC_BE),
1604- aifsn, cw, cw, 0,
1605- mode == MT76_TM_TX_MODE_HE_MU);
1606+ aifsn, cw, cw, 0, tx_cmd, bf_sounding);
1607 }
1608
1609 static int
1610@@ -1469,7 +1632,7 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
1611
1612 phy->mt76->test.aid = 0;
1613 phy->mt76->test.tx_mpdu_len = 0;
1614- phy->test.bf_en = 0;
1615+ phy->mt76->test.bf_en = 0;
1616 mt7915_tm_set_entry(phy);
1617 } else {
1618 INIT_DELAYED_WORK(&phy->ipi_work, mt7915_tm_ipi_work);
1619@@ -1654,7 +1817,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
1620 u32 tx_time = td->tx_time, ipg = td->tx_ipg;
1621 u8 duty_cycle = td->tx_duty_cycle;
1622
1623- if (!phy->test.bf_en)
1624+ if (!td->bf_en)
1625 mt7915_tm_update_channel(phy);
1626
1627 if (td->tx_spe_idx)
1628@@ -1669,7 +1832,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
1629 if (duty_cycle < 100)
1630 tx_time = duty_cycle * ipg / (100 - duty_cycle);
1631 }
1632- mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
1633+ mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode, false);
1634 mt7915_tm_set_tx_len(phy, tx_time);
1635
1636 if (ipg)
1637@@ -1688,6 +1851,9 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
1638 mt7915_tm_tx_frames_mu(phy, en);
1639
1640 mt7915_tm_set_trx(phy, TM_MAC_TX, en);
1641+
1642+ if (td->bf_en)
1643+ mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
1644 }
1645
1646 static int
1647@@ -1779,7 +1945,7 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
1648 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
1649
1650 if (en) {
1651- if (!phy->test.bf_en)
1652+ if (!td->bf_en || !td->is_txbf_dut)
1653 mt7915_tm_update_channel(phy);
1654 if (td->aid)
1655 mt7915_tm_set_rx_user_idx(phy, td->aid);
1656@@ -1796,6 +1962,9 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
1657 mt7915_tm_set_muru_aid(phy, en ? td->aid : 0xf800);
1658
1659 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
1660+
1661+ if (td->bf_en)
1662+ mt7915_tm_set_trx(phy, TM_MAC_TX, en);
1663 }
1664
1665 static int
1666@@ -1855,34 +2024,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
1667 rate_idx = sband->bitrates[idx].hw_value & 0xff;
1668 }
1669
1670- switch (td->tx_rate_mode) {
1671- case MT76_TM_TX_MODE_CCK:
1672- mode = MT_PHY_TYPE_CCK;
1673- break;
1674- case MT76_TM_TX_MODE_OFDM:
1675- mode = MT_PHY_TYPE_OFDM;
1676- break;
1677- case MT76_TM_TX_MODE_HT:
1678- mode = MT_PHY_TYPE_HT;
1679- break;
1680- case MT76_TM_TX_MODE_VHT:
1681- mode = MT_PHY_TYPE_VHT;
1682- break;
1683- case MT76_TM_TX_MODE_HE_SU:
1684- mode = MT_PHY_TYPE_HE_SU;
1685- break;
1686- case MT76_TM_TX_MODE_HE_EXT_SU:
1687- mode = MT_PHY_TYPE_HE_EXT_SU;
1688- break;
1689- case MT76_TM_TX_MODE_HE_TB:
1690- mode = MT_PHY_TYPE_HE_TB;
1691- break;
1692- case MT76_TM_TX_MODE_HE_MU:
1693- mode = MT_PHY_TYPE_HE_MU;
1694- break;
1695- default:
1696- return -EINVAL;
1697- }
1698+ mode = mt7915_tm_rate_to_phy(td->tx_rate_mode);
1699
1700 rateval = mode << 6 | rate_idx;
1701 tx_cont->rateval = cpu_to_le16(rateval);
1702diff --git a/mt7915/testmode.h b/mt7915/testmode.h
1703index d500987..1982369 100644
1704--- a/mt7915/testmode.h
1705+++ b/mt7915/testmode.h
1706@@ -311,137 +311,7 @@ struct mt7915_tm_muru {
1707
1708 #define MAX_PHASE_GROUP_NUM 9
1709
1710-struct mt7915_tm_txbf_phase {
1711- u8 status;
1712- struct {
1713- u8 r0_uh;
1714- u8 r0_h;
1715- u8 r0_m;
1716- u8 r0_l;
1717- u8 r0_ul;
1718- u8 r1_uh;
1719- u8 r1_h;
1720- u8 r1_m;
1721- u8 r1_l;
1722- u8 r1_ul;
1723- u8 r2_uh;
1724- u8 r2_h;
1725- u8 r2_m;
1726- u8 r2_l;
1727- u8 r2_ul;
1728- u8 r3_uh;
1729- u8 r3_h;
1730- u8 r3_m;
1731- u8 r3_l;
1732- u8 r3_ul;
1733- u8 r2_uh_sx2;
1734- u8 r2_h_sx2;
1735- u8 r2_m_sx2;
1736- u8 r2_l_sx2;
1737- u8 r2_ul_sx2;
1738- u8 r3_uh_sx2;
1739- u8 r3_h_sx2;
1740- u8 r3_m_sx2;
1741- u8 r3_l_sx2;
1742- u8 r3_ul_sx2;
1743- u8 m_t0_h;
1744- u8 m_t1_h;
1745- u8 m_t2_h;
1746- u8 m_t2_h_sx2;
1747- u8 r0_reserved;
1748- u8 r1_reserved;
1749- u8 r2_reserved;
1750- u8 r3_reserved;
1751- u8 r2_sx2_reserved;
1752- u8 r3_sx2_reserved;
1753- } phase;
1754-};
1755-
1756-struct mt7915_tm_pfmu_tag1 {
1757- __le32 pfmu_idx:10;
1758- __le32 ebf:1;
1759- __le32 data_bw:2;
1760- __le32 lm:2;
1761- __le32 is_mu:1;
1762- __le32 nr:3, nc:3;
1763- __le32 codebook:2;
1764- __le32 ngroup:2;
1765- __le32 _rsv:2;
1766- __le32 invalid_prof:1;
1767- __le32 rmsd:3;
1768-
1769- __le32 col_id1:6, row_id1:10;
1770- __le32 col_id2:6, row_id2:10;
1771- __le32 col_id3:6, row_id3:10;
1772- __le32 col_id4:6, row_id4:10;
1773-
1774- __le32 ru_start_id:7;
1775- __le32 _rsv1:1;
1776- __le32 ru_end_id:7;
1777- __le32 _rsv2:1;
1778- __le32 mob_cal_en:1;
1779- __le32 _rsv3:15;
1780-
1781- __le32 snr_sts0:8, snr_sts1:8, snr_sts2:8, snr_sts3:8;
1782- __le32 snr_sts4:8, snr_sts5:8, snr_sts6:8, snr_sts7:8;
1783-
1784- __le32 _rsv4;
1785-} __packed;
1786-
1787-struct mt7915_tm_pfmu_tag2 {
1788- __le32 smart_ant:24;
1789- __le32 se_idx:5;
1790- __le32 _rsv:3;
1791-
1792- __le32 _rsv1:8;
1793- __le32 rmsd_thres:3;
1794- __le32 _rsv2:5;
1795- __le32 ibf_timeout:8;
1796- __le32 _rsv3:8;
1797-
1798- __le32 _rsv4:16;
1799- __le32 ibf_data_bw:2;
1800- __le32 ibf_nc:3;
1801- __le32 ibf_nr:3;
1802- __le32 ibf_ru:8;
1803-
1804- __le32 mob_delta_t:8;
1805- __le32 mob_lq_result:7;
1806- __le32 _rsv5:1;
1807- __le32 _rsv6:16;
1808-
1809- __le32 _rsv7;
1810-} __packed;
1811-
1812-struct mt7915_tm_pfmu_tag {
1813- struct mt7915_tm_pfmu_tag1 t1;
1814- struct mt7915_tm_pfmu_tag2 t2;
1815-};
1816-
1817-struct mt7915_tm_pfmu_data {
1818- __le16 subc_idx;
1819- __le16 phi11;
1820- __le16 phi21;
1821- __le16 phi31;
1822-};
1823-
1824-struct mt7915_tm_ibf_cal_info {
1825- u8 format_id;
1826- u8 group_l_m_n;
1827- u8 group;
1828- bool sx2;
1829- u8 status;
1830- u8 cal_type;
1831- u8 _rsv[2];
1832- u8 buf[1000];
1833-} __packed;
1834-
1835-enum {
1836- IBF_PHASE_CAL_UNSPEC,
1837- IBF_PHASE_CAL_NORMAL,
1838- IBF_PHASE_CAL_VERIFY,
1839- IBF_PHASE_CAL_NORMAL_INSTRUMENT,
1840- IBF_PHASE_CAL_VERIFY_INSTRUMENT,
1841-};
1842+#define TXBF_DUT_MAC_SUBADDR 0x22
1843+#define TXBF_GOLDEN_MAC_SUBADDR 0x11
1844
1845 #endif
1846diff --git a/testmode.c b/testmode.c
1847index b19b872..ed5ceee 100644
1848--- a/testmode.c
1849+++ b/testmode.c
1850@@ -191,6 +191,7 @@ mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len,
1851
1852 hdr = __skb_put_zero(head, sizeof(*hdr));
1853 hdr->frame_control = cpu_to_le16(fc);
1854+
1855 memcpy(hdr->addr1, addr[0], ETH_ALEN);
1856 memcpy(hdr->addr2, addr[1], ETH_ALEN);
1857 memcpy(hdr->addr3, addr[2], ETH_ALEN);
1858diff --git a/testmode.h b/testmode.h
1859index 27a0095..e1ebbd5 100644
1860--- a/testmode.h
1861+++ b/testmode.h
1862@@ -299,7 +299,10 @@ enum mt76_testmode_cfg {
1863 };
1864
1865 enum mt76_testmode_txbf_act {
1866+ MT76_TM_TXBF_ACT_GOLDEN_INIT,
1867 MT76_TM_TXBF_ACT_INIT,
1868+ MT76_TM_TX_EBF_ACT_GOLDEN_INIT,
1869+ MT76_TM_TX_EBF_ACT_INIT,
1870 MT76_TM_TXBF_ACT_UPDATE_CH,
1871 MT76_TM_TXBF_ACT_PHASE_COMP,
1872 MT76_TM_TXBF_ACT_TX_PREP,
1873@@ -310,6 +313,12 @@ enum mt76_testmode_txbf_act {
1874 MT76_TM_TXBF_ACT_PROF_UPDATE_ALL,
1875 MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD,
1876 MT76_TM_TXBF_ACT_E2P_UPDATE,
1877+ MT76_TM_TXBF_ACT_TRIGGER_SOUNDING,
1878+ MT76_TM_TXBF_ACT_STOP_SOUNDING,
1879+ MT76_TM_TXBF_ACT_PROFILE_TAG_READ,
1880+ MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE,
1881+ MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID,
1882+ MT76_TM_TXBF_ACT_STA_REC_READ,
1883
1884 /* keep last */
1885 NUM_MT76_TM_TXBF_ACT,
1886diff --git a/tools/fields.c b/tools/fields.c
1887index 6f07eed..7211ec5 100644
1888--- a/tools/fields.c
1889+++ b/tools/fields.c
1890@@ -33,7 +33,10 @@ static const char * const testmode_tx_mode[] = {
1891 };
1892
1893 static const char * const testmode_txbf_act[] = {
1894+ [MT76_TM_TXBF_ACT_GOLDEN_INIT] = "golden_init",
1895 [MT76_TM_TXBF_ACT_INIT] = "init",
1896+ [MT76_TM_TX_EBF_ACT_GOLDEN_INIT] = "ebf_golden_init",
1897+ [MT76_TM_TX_EBF_ACT_INIT] = "ebf_init",
1898 [MT76_TM_TXBF_ACT_UPDATE_CH] = "update_ch",
1899 [MT76_TM_TXBF_ACT_PHASE_COMP] = "phase_comp",
1900 [MT76_TM_TXBF_ACT_TX_PREP] = "tx_prep",
1901@@ -44,6 +47,12 @@ static const char * const testmode_txbf_act[] = {
1902 [MT76_TM_TXBF_ACT_PROF_UPDATE_ALL] = "prof_update",
1903 [MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD] = "prof_update_all",
1904 [MT76_TM_TXBF_ACT_E2P_UPDATE] = "e2p_update",
1905+ [MT76_TM_TXBF_ACT_TRIGGER_SOUNDING] = "trigger_sounding",
1906+ [MT76_TM_TXBF_ACT_STOP_SOUNDING] = "stop_sounding",
1907+ [MT76_TM_TXBF_ACT_PROFILE_TAG_READ] = "pfmu_tag_read",
1908+ [MT76_TM_TXBF_ACT_PROFILE_TAG_WRITE] = "pfmu_tag_write",
1909+ [MT76_TM_TXBF_ACT_PROFILE_TAG_INVALID] = "set_invalid_prof",
1910+ [MT76_TM_TXBF_ACT_STA_REC_READ] = "sta_rec_read",
1911 };
1912
1913 static const char * const testmode_offchan_bw[] = {
1914--
developerdad04b12022-12-22 16:47:31 +080019152.18.0
developerc5ce7502022-12-19 11:33:22 +08001916