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