blob: 40e7ee18dc951f565f124b261098e4753203796e [file] [log] [blame]
developerd0c89452024-10-11 16:53:27 +08001From 04a4a2672095e1b0162153655874ba194370ffc2 Mon Sep 17 00:00:00 2001
developer05f3b2b2024-08-19 19:17:34 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Mon, 3 Jun 2024 16:40:38 +0800
developerd0c89452024-10-11 16:53:27 +08004Subject: [PATCH 132/223] mtk: mt76: mt7996: update testmode bf support
developer05f3b2b2024-08-19 19:17:34 +08005
6Fix bssid & omac idx to band idx when testmode is enabled
7
8Add support for per-packet bw & primary channel selection index configuration
9This is used for ibf calibaration of group 9 ~ 13 in Kite
10
developerd0c89452024-10-11 16:53:27 +080011Change-Id: Ib993f75d331b1fa22b7c07197321f91c8dae46ec
developer05f3b2b2024-08-19 19:17:34 +080012Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
13---
14 mt76.h | 3 +++
15 mt7996/main.c | 29 +++++++++++++++-------
16 mt7996/testmode.c | 63 ++++++++++++++++++++++++++++++++---------------
17 testmode.c | 15 ++++++++---
18 testmode.h | 6 +++++
19 tools/fields.c | 16 ++++++++++--
20 6 files changed, 98 insertions(+), 34 deletions(-)
21
22diff --git a/mt76.h b/mt76.h
developerd0c89452024-10-11 16:53:27 +080023index bc263bd4..526b6298 100644
developer05f3b2b2024-08-19 19:17:34 +080024--- a/mt76.h
25+++ b/mt76.h
developerd0c89452024-10-11 16:53:27 +080026@@ -796,6 +796,9 @@ struct mt76_testmode_data {
developer05f3b2b2024-08-19 19:17:34 +080027 bool ibf;
28 bool ebf;
29
30+ u8 tx_pkt_bw;
31+ u8 tx_pri_sel;
32+
33 u32 freq_offset;
34
35 u8 tx_power[4];
36diff --git a/mt7996/main.c b/mt7996/main.c
developerd0c89452024-10-11 16:53:27 +080037index 485c87f9..f67e1b5d 100644
developer05f3b2b2024-08-19 19:17:34 +080038--- a/mt7996/main.c
39+++ b/mt7996/main.c
40@@ -349,16 +349,27 @@ static int mt7996_add_bss_conf(struct mt7996_phy *phy,
41 mconf = &mvif->deflink;
42 }
43
44- mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
45- if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
46- ret = -ENOSPC;
47- goto error;
48- }
49+ if (!dev->testmode_enable) {
50+ mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
51+ if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
52+ ret = -ENOSPC;
53+ goto error;
54+ }
55
56- idx = get_omac_idx(vif->type, phy->omac_mask);
57- if (idx < 0) {
58- ret = -ENOSPC;
59- goto error;
60+ idx = get_omac_idx(vif->type, phy->omac_mask);
61+ if (idx < 0) {
62+ ret = -ENOSPC;
63+ goto error;
64+ }
65+ } else {
66+ /* bss idx & omac idx should be set to band idx for ibf cal */
67+ if (dev->mt76.vif_mask & BIT_ULL(band_idx) ||
68+ phy->omac_mask & BIT_ULL(band_idx)) {
69+ ret = -ENOSPC;
70+ goto error;
71+ }
72+ mconf->mt76.idx = band_idx;
73+ idx = band_idx;
74 }
75
76 mconf->own_mld_id = get_own_mld_idx(dev->mld_id_mask, false);
77diff --git a/mt7996/testmode.c b/mt7996/testmode.c
developerd0c89452024-10-11 16:53:27 +080078index c68619cb..240227a9 100644
developer05f3b2b2024-08-19 19:17:34 +080079--- a/mt7996/testmode.c
80+++ b/mt7996/testmode.c
developerd0c89452024-10-11 16:53:27 +080081@@ -241,8 +241,10 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
developer05f3b2b2024-08-19 19:17:34 +080082
83 mt7996_tm_rf_switch_mode(dev, rf_test_mode);
84
85- mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, &mvif->sta.deflink, en);
86- mt7996_mcu_add_sta(dev, &phy->monitor_vif->bss_conf, &mvif->deflink, NULL, &mvif->sta.deflink, en, false);
87+ mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf,
88+ &mvif->deflink, &mvif->sta.deflink, en);
89+ mt7996_mcu_add_sta(dev, &phy->monitor_vif->bss_conf, &mvif->deflink,
90+ NULL, &mvif->sta.deflink, en, false);
91
92 mt7996_tm_set(dev, SET_ID(BAND_IDX), phy->mt76->band_idx);
93
developerd0c89452024-10-11 16:53:27 +080094@@ -258,9 +260,11 @@ mt7996_tm_update_channel(struct mt7996_phy *phy)
developer05f3b2b2024-08-19 19:17:34 +080095 {
96 #define CHAN_FREQ_BW_80P80_TAG (SET_ID(CHAN_FREQ) | BIT(16))
97 struct mt7996_dev *dev = phy->dev;
98+ struct mt76_testmode_data *td = &phy->mt76->test;
99 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
100 struct ieee80211_channel *chan = chandef->chan;
101- u8 width = chandef->width;
102+ u8 dbw, width = chandef->width, pri_sel = 0;
103+ int width_mhz;
104 static const u8 ch_band[] = {
105 [NL80211_BAND_2GHZ] = 0,
106 [NL80211_BAND_5GHZ] = 1,
developerd0c89452024-10-11 16:53:27 +0800107@@ -280,18 +284,37 @@ mt7996_tm_update_channel(struct mt7996_phy *phy)
developer05f3b2b2024-08-19 19:17:34 +0800108 mt7996_tm_set(dev, CHAN_FREQ_BW_80P80_TAG, chandef->center_freq2 * 1000);
109 }
110
111- /* TODO: define per-packet bw */
112- /* per-packet bw */
113- mt7996_tm_set(dev, SET_ID(DBW), mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_FW));
114+ width_mhz = mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_MHZ);
115+
116+ /* data (per-packet) bw */
117+ dbw = width;
118+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW)) {
119+ int pkt_bw_mhz = mt7996_tm_bw_mapping(td->tx_pkt_bw, BW_MAP_NL_TO_MHZ);
120+
121+ if (pkt_bw_mhz > width_mhz) {
122+ dev_info(dev->mt76.dev,
123+ "per-packet bw cannot exceed system bw, use %d MHz instead\n",
124+ width_mhz);
125+ td->tx_pkt_bw = width;
126+ }
127+ dbw = td->tx_pkt_bw;
128+ }
129+ mt7996_tm_set(dev, SET_ID(DBW), mt7996_tm_bw_mapping(dbw, BW_MAP_NL_TO_FW));
130
131 /* control channel selection index */
132- mt7996_tm_set(dev, SET_ID(PRIMARY_CH), 0);
133+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PRI_SEL)) {
134+ if (td->tx_pri_sel > width_mhz / 20 - 1) {
135+ dev_info(dev->mt76.dev,
136+ "Invalid primary channel selection index, use 0 instead\n");
137+ td->tx_pri_sel = 0;
138+ }
139+ pri_sel = td->tx_pri_sel;
140+ }
141+ mt7996_tm_set(dev, SET_ID(PRIMARY_CH), pri_sel);
142 mt7996_tm_set(dev, SET_ID(BAND), ch_band[chan->band]);
143
144 /* trigger switch channel calibration */
145 mt7996_tm_set(dev, SET_ID(CHAN_FREQ), chandef->center_freq1 * 1000);
146-
147- // TODO: update power limit table
148 }
149
150 static void
developerd0c89452024-10-11 16:53:27 +0800151@@ -1185,14 +1208,9 @@ mt7996_tm_txbf_init(struct mt7996_phy *phy, u16 *val)
developer05f3b2b2024-08-19 19:17:34 +0800152 mt7996_tm_set_mac_addr(dev, td->addr[1], SET_ID(SA));
153 mt7996_tm_set_mac_addr(dev, td->addr[2], SET_ID(BSSID));
154
155- /* bss idx & omac idx should be set to band idx for ibf cal */
156- mvif->deflink.mt76.idx = band_idx;
157- dev->mt76.vif_mask |= BIT_ULL(mvif->deflink.mt76.idx);
158- mvif->deflink.mt76.omac_idx = band_idx;
159- phy->omac_mask |= BIT_ULL(mvif->deflink.mt76.omac_idx);
160-
161 mt7996_mcu_add_dev_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, true);
162- mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, &mvif->sta.deflink, true);
163+ mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf,
164+ &mvif->deflink, &mvif->sta.deflink, true);
165
166 if (td->ibf) {
167 if (td->is_txbf_dut) {
developerd0c89452024-10-11 16:53:27 +0800168@@ -1367,7 +1385,8 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
developer05f3b2b2024-08-19 19:17:34 +0800169 .tx_mode = mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY),
170 },
171 };
172- u8 ndp_rate, ndpa_rate, rept_poll_rate, bf_bw;
173+ u8 ndp_rate, ndpa_rate, rept_poll_rate;
174+ u8 bf_bw = phy->mt76->chandef.width;
175
176 if ((td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU ||
177 td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) && !td->ibf) {
developerd0c89452024-10-11 16:53:27 +0800178@@ -1397,11 +1416,12 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
developer05f3b2b2024-08-19 19:17:34 +0800179 }
180 }
181
182- bf_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
183 req.bf.ndp_rate = ndp_rate;
184 req.bf.ndpa_rate = ndpa_rate;
185 req.bf.rept_poll_rate = rept_poll_rate;
186- req.bf.bw = bf_bw;
187+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW))
188+ bf_bw = td->tx_pkt_bw;
189+ req.bf.bw = mt7996_tm_bw_mapping(bf_bw, BW_MAP_NL_TO_BF);
190 req.bf.tx_mode = (td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) ? 0xf : req.bf.tx_mode;
191
192 if (ebf) {
developerd0c89452024-10-11 16:53:27 +0800193@@ -1428,6 +1448,7 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
developer05f3b2b2024-08-19 19:17:34 +0800194 struct mt7996_dev *dev = phy->dev;
195 struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
196 u8 rate, pfmu_idx = val[0], nc = val[2], nr;
197+ u8 dbw = phy->mt76->chandef.width;
198 int ret;
199 bool is_atenl = val[5];
200
developerd0c89452024-10-11 16:53:27 +0800201@@ -1446,7 +1467,9 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
developer05f3b2b2024-08-19 19:17:34 +0800202 tag->t1.nr = nr;
203 tag->t1.nc = nc;
204 tag->t1.invalid_prof = true;
205- tag->t1.data_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
206+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW))
207+ dbw = td->tx_pkt_bw;
208+ tag->t1.data_bw = mt7996_tm_bw_mapping(dbw, BW_MAP_NL_TO_BF);
209 tag->t2.se_idx = td->tx_spe_idx;
210
211 if (ebf) {
212diff --git a/testmode.c b/testmode.c
developerd0c89452024-10-11 16:53:27 +0800213index a1744755..2834400f 100644
developer05f3b2b2024-08-19 19:17:34 +0800214--- a/testmode.c
215+++ b/testmode.c
216@@ -25,6 +25,8 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
217 [MT76_TM_ATTR_TX_DUTY_CYCLE] = { .type = NLA_U8 },
218 [MT76_TM_ATTR_TX_IPG] = { .type = NLA_U32 },
219 [MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
220+ [MT76_TM_ATTR_TX_PKT_BW] = { .type = NLA_U8 },
221+ [MT76_TM_ATTR_TX_PRI_SEL] = { .type = NLA_U8 },
222 [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
223 [MT76_TM_ATTR_DRV_DATA] = { .type = NLA_NESTED },
224 [MT76_TM_ATTR_OFF_CH_SCAN_CH] = { .type = NLA_U8 },
225@@ -567,12 +569,15 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
226 &td->tx_duty_cycle, 0, 99) ||
227 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
228 &td->tx_power_control, 0, 1) ||
229+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_PKT_BW], &td->tx_pkt_bw,
230+ NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_320) ||
231+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_PRI_SEL], &td->tx_pri_sel, 0, 15) ||
232 mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
233 mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CH], &td->offchan_ch, 36, 196) ||
234 mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH], &td->offchan_center_ch,
235 36, 196) ||
236- mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW],
237- &td->offchan_bw, NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_160) ||
238+ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW], &td->offchan_bw,
239+ NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_160) ||
240 mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_THRESHOLD], &td->ipi_threshold, 0, 10) ||
241 mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_RESET], &td->ipi_reset, 0, 1))
242 goto out;
243@@ -616,7 +621,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
244
245 err = mt76_tm_get_u8(cur, &td->tx_power[idx++], 0, 63);
246 if (err)
247- return err;
248+ goto out;
249 }
250 }
251
252@@ -823,6 +828,10 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
253 nla_put_u32(msg, MT76_TM_ATTR_TX_TIME, td->tx_time)) ||
254 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
255 nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
256+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW) &&
257+ nla_put_u8(msg, MT76_TM_ATTR_TX_PKT_BW, td->tx_pkt_bw)) ||
258+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PRI_SEL) &&
259+ nla_put_u8(msg, MT76_TM_ATTR_TX_PRI_SEL, td->tx_pri_sel)) ||
260 (mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
261 nla_put_u32(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
262 goto out;
263diff --git a/testmode.h b/testmode.h
developerd0c89452024-10-11 16:53:27 +0800264index 794a74f9..44f9984c 100644
developer05f3b2b2024-08-19 19:17:34 +0800265--- a/testmode.h
266+++ b/testmode.h
267@@ -37,6 +37,9 @@
268 * @MT76_TM_ATTR_TX_POWER_CONTROL: enable tx power control (u8)
269 * @MT76_TM_ATTR_TX_POWER: per-antenna tx power array (nested, u8 attrs)
270 *
271+ * @MT76_TM_ATTR_TX_PKT_BW: per-packet data bandwidth (u8)
272+ * @MT76_TM_ATTR_TX_PRI_SEL: primary channel selection index (u8)
273+ *
274 * @MT76_TM_ATTR_FREQ_OFFSET: RF frequency offset (u32)
275 *
276 * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
277@@ -104,6 +107,9 @@ enum mt76_testmode_attr {
278 MT76_TM_ATTR_TX_POWER_CONTROL,
279 MT76_TM_ATTR_TX_POWER,
280
281+ MT76_TM_ATTR_TX_PKT_BW,
282+ MT76_TM_ATTR_TX_PRI_SEL,
283+
284 MT76_TM_ATTR_FREQ_OFFSET,
285
286 MT76_TM_ATTR_STATS,
287diff --git a/tools/fields.c b/tools/fields.c
288index f793d1a5..8b372602 100644
289--- a/tools/fields.c
290+++ b/tools/fields.c
291@@ -35,13 +35,21 @@ static const char * const testmode_tx_mode[] = {
292 [MT76_TM_TX_MODE_EHT_MU] = "eht_mu",
293 };
294
295-static const char * const testmode_offchan_bw[] = {
296+static const char * const testmode_bw[] = {
297 [NL80211_CHAN_WIDTH_20_NOHT] = "NOHT",
298 [NL80211_CHAN_WIDTH_20] = "20",
299 [NL80211_CHAN_WIDTH_40] = "40",
300 [NL80211_CHAN_WIDTH_80] = "80",
301 [NL80211_CHAN_WIDTH_80P80] = "80p80",
302 [NL80211_CHAN_WIDTH_160] = "160",
303+ [NL80211_CHAN_WIDTH_5] = "5",
304+ [NL80211_CHAN_WIDTH_10] = "10",
305+ [NL80211_CHAN_WIDTH_1] = "1",
306+ [NL80211_CHAN_WIDTH_2] = "2",
307+ [NL80211_CHAN_WIDTH_4] = "4",
308+ [NL80211_CHAN_WIDTH_8] = "8",
309+ [NL80211_CHAN_WIDTH_16] = "16",
310+ [NL80211_CHAN_WIDTH_320] = "320",
311 };
312
313 static const char * const testmode_txbf_act[] = {
314@@ -430,6 +438,8 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
315 FIELD(u8, TX_POWER_CONTROL, "tx_power_control"),
316 FIELD_ARRAY(u8, TX_POWER, "tx_power"),
317 FIELD(u8, TX_ANTENNA, "tx_antenna"),
318+ FIELD_ENUM(TX_PKT_BW, "tx_pkt_bw", testmode_bw),
319+ FIELD(u8, TX_PRI_SEL, "tx_pri_sel"),
320 FIELD(u32, FREQ_OFFSET, "freq_offset"),
321 FIELD(u8, AID, "aid"),
322 FIELD(u8, RU_ALLOC, "ru_alloc"),
323@@ -438,7 +448,7 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
324 FIELD_ARRAY(u16_hex, TXBF_PARAM, "txbf_param"),
325 FIELD(u8, OFF_CH_SCAN_CH, "offchan_ch"),
326 FIELD(u8, OFF_CH_SCAN_CENTER_CH, "offchan_center_ch"),
327- FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_offchan_bw),
328+ FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_bw),
329 FIELD(u8, IPI_THRESHOLD, "ipi_threshold"),
330 FIELD(u32, IPI_PERIOD, "ipi_period"),
331 FIELD(u8, IPI_RESET, "ipi_reset"),
332@@ -469,6 +479,8 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
333 [MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 },
334 [MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 },
335 [MT76_TM_ATTR_TX_SPE_IDX] = { .type = NLA_U8 },
336+ [MT76_TM_ATTR_TX_PKT_BW] = { .type = NLA_U8 },
337+ [MT76_TM_ATTR_TX_PRI_SEL] = { .type = NLA_U8 },
338 [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
339 [MT76_TM_ATTR_AID] = { .type = NLA_U8 },
340 [MT76_TM_ATTR_RU_ALLOC] = { .type = NLA_U8 },
341--
developerd0c89452024-10-11 16:53:27 +08003422.45.2
developer05f3b2b2024-08-19 19:17:34 +0800343