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