blob: 40e7ee18dc951f565f124b261098e4753203796e [file] [log] [blame]
From 04a4a2672095e1b0162153655874ba194370ffc2 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 3 Jun 2024 16:40:38 +0800
Subject: [PATCH 132/223] mtk: mt76: mt7996: update testmode bf support
Fix bssid & omac idx to band idx when testmode is enabled
Add support for per-packet bw & primary channel selection index configuration
This is used for ibf calibaration of group 9 ~ 13 in Kite
Change-Id: Ib993f75d331b1fa22b7c07197321f91c8dae46ec
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
mt76.h | 3 +++
mt7996/main.c | 29 +++++++++++++++-------
mt7996/testmode.c | 63 ++++++++++++++++++++++++++++++++---------------
testmode.c | 15 ++++++++---
testmode.h | 6 +++++
tools/fields.c | 16 ++++++++++--
6 files changed, 98 insertions(+), 34 deletions(-)
diff --git a/mt76.h b/mt76.h
index bc263bd4..526b6298 100644
--- a/mt76.h
+++ b/mt76.h
@@ -796,6 +796,9 @@ struct mt76_testmode_data {
bool ibf;
bool ebf;
+ u8 tx_pkt_bw;
+ u8 tx_pri_sel;
+
u32 freq_offset;
u8 tx_power[4];
diff --git a/mt7996/main.c b/mt7996/main.c
index 485c87f9..f67e1b5d 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -349,16 +349,27 @@ static int mt7996_add_bss_conf(struct mt7996_phy *phy,
mconf = &mvif->deflink;
}
- mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
- if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
- ret = -ENOSPC;
- goto error;
- }
+ if (!dev->testmode_enable) {
+ mconf->mt76.idx = __ffs64(~dev->mt76.vif_mask);
+ if (mconf->mt76.idx >= mt7996_max_interface_num(dev)) {
+ ret = -ENOSPC;
+ goto error;
+ }
- idx = get_omac_idx(vif->type, phy->omac_mask);
- if (idx < 0) {
- ret = -ENOSPC;
- goto error;
+ idx = get_omac_idx(vif->type, phy->omac_mask);
+ if (idx < 0) {
+ ret = -ENOSPC;
+ goto error;
+ }
+ } else {
+ /* bss idx & omac idx should be set to band idx for ibf cal */
+ if (dev->mt76.vif_mask & BIT_ULL(band_idx) ||
+ phy->omac_mask & BIT_ULL(band_idx)) {
+ ret = -ENOSPC;
+ goto error;
+ }
+ mconf->mt76.idx = band_idx;
+ idx = band_idx;
}
mconf->own_mld_id = get_own_mld_idx(dev->mld_id_mask, false);
diff --git a/mt7996/testmode.c b/mt7996/testmode.c
index c68619cb..240227a9 100644
--- a/mt7996/testmode.c
+++ b/mt7996/testmode.c
@@ -241,8 +241,10 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
mt7996_tm_rf_switch_mode(dev, rf_test_mode);
- mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, &mvif->sta.deflink, en);
- mt7996_mcu_add_sta(dev, &phy->monitor_vif->bss_conf, &mvif->deflink, NULL, &mvif->sta.deflink, en, false);
+ mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf,
+ &mvif->deflink, &mvif->sta.deflink, en);
+ mt7996_mcu_add_sta(dev, &phy->monitor_vif->bss_conf, &mvif->deflink,
+ NULL, &mvif->sta.deflink, en, false);
mt7996_tm_set(dev, SET_ID(BAND_IDX), phy->mt76->band_idx);
@@ -258,9 +260,11 @@ mt7996_tm_update_channel(struct mt7996_phy *phy)
{
#define CHAN_FREQ_BW_80P80_TAG (SET_ID(CHAN_FREQ) | BIT(16))
struct mt7996_dev *dev = phy->dev;
+ struct mt76_testmode_data *td = &phy->mt76->test;
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
struct ieee80211_channel *chan = chandef->chan;
- u8 width = chandef->width;
+ u8 dbw, width = chandef->width, pri_sel = 0;
+ int width_mhz;
static const u8 ch_band[] = {
[NL80211_BAND_2GHZ] = 0,
[NL80211_BAND_5GHZ] = 1,
@@ -280,18 +284,37 @@ mt7996_tm_update_channel(struct mt7996_phy *phy)
mt7996_tm_set(dev, CHAN_FREQ_BW_80P80_TAG, chandef->center_freq2 * 1000);
}
- /* TODO: define per-packet bw */
- /* per-packet bw */
- mt7996_tm_set(dev, SET_ID(DBW), mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_FW));
+ width_mhz = mt7996_tm_bw_mapping(width, BW_MAP_NL_TO_MHZ);
+
+ /* data (per-packet) bw */
+ dbw = width;
+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW)) {
+ int pkt_bw_mhz = mt7996_tm_bw_mapping(td->tx_pkt_bw, BW_MAP_NL_TO_MHZ);
+
+ if (pkt_bw_mhz > width_mhz) {
+ dev_info(dev->mt76.dev,
+ "per-packet bw cannot exceed system bw, use %d MHz instead\n",
+ width_mhz);
+ td->tx_pkt_bw = width;
+ }
+ dbw = td->tx_pkt_bw;
+ }
+ mt7996_tm_set(dev, SET_ID(DBW), mt7996_tm_bw_mapping(dbw, BW_MAP_NL_TO_FW));
/* control channel selection index */
- mt7996_tm_set(dev, SET_ID(PRIMARY_CH), 0);
+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PRI_SEL)) {
+ if (td->tx_pri_sel > width_mhz / 20 - 1) {
+ dev_info(dev->mt76.dev,
+ "Invalid primary channel selection index, use 0 instead\n");
+ td->tx_pri_sel = 0;
+ }
+ pri_sel = td->tx_pri_sel;
+ }
+ mt7996_tm_set(dev, SET_ID(PRIMARY_CH), pri_sel);
mt7996_tm_set(dev, SET_ID(BAND), ch_band[chan->band]);
/* trigger switch channel calibration */
mt7996_tm_set(dev, SET_ID(CHAN_FREQ), chandef->center_freq1 * 1000);
-
- // TODO: update power limit table
}
static void
@@ -1185,14 +1208,9 @@ mt7996_tm_txbf_init(struct mt7996_phy *phy, u16 *val)
mt7996_tm_set_mac_addr(dev, td->addr[1], SET_ID(SA));
mt7996_tm_set_mac_addr(dev, td->addr[2], SET_ID(BSSID));
- /* bss idx & omac idx should be set to band idx for ibf cal */
- mvif->deflink.mt76.idx = band_idx;
- dev->mt76.vif_mask |= BIT_ULL(mvif->deflink.mt76.idx);
- mvif->deflink.mt76.omac_idx = band_idx;
- phy->omac_mask |= BIT_ULL(mvif->deflink.mt76.omac_idx);
-
mt7996_mcu_add_dev_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, true);
- mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf, &mvif->deflink, &mvif->sta.deflink, true);
+ mt7996_mcu_add_bss_info(phy, &phy->monitor_vif->bss_conf,
+ &mvif->deflink, &mvif->sta.deflink, true);
if (td->ibf) {
if (td->is_txbf_dut) {
@@ -1367,7 +1385,8 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
.tx_mode = mt7996_tm_rate_mapping(td->tx_rate_mode, RATE_MODE_TO_PHY),
},
};
- u8 ndp_rate, ndpa_rate, rept_poll_rate, bf_bw;
+ u8 ndp_rate, ndpa_rate, rept_poll_rate;
+ u8 bf_bw = phy->mt76->chandef.width;
if ((td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU ||
td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) && !td->ibf) {
@@ -1397,11 +1416,12 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
}
}
- bf_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
req.bf.ndp_rate = ndp_rate;
req.bf.ndpa_rate = ndpa_rate;
req.bf.rept_poll_rate = rept_poll_rate;
- req.bf.bw = bf_bw;
+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW))
+ bf_bw = td->tx_pkt_bw;
+ req.bf.bw = mt7996_tm_bw_mapping(bf_bw, BW_MAP_NL_TO_BF);
req.bf.tx_mode = (td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) ? 0xf : req.bf.tx_mode;
if (ebf) {
@@ -1428,6 +1448,7 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
struct mt7996_dev *dev = phy->dev;
struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
u8 rate, pfmu_idx = val[0], nc = val[2], nr;
+ u8 dbw = phy->mt76->chandef.width;
int ret;
bool is_atenl = val[5];
@@ -1446,7 +1467,9 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
tag->t1.nr = nr;
tag->t1.nc = nc;
tag->t1.invalid_prof = true;
- tag->t1.data_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
+ if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW))
+ dbw = td->tx_pkt_bw;
+ tag->t1.data_bw = mt7996_tm_bw_mapping(dbw, BW_MAP_NL_TO_BF);
tag->t2.se_idx = td->tx_spe_idx;
if (ebf) {
diff --git a/testmode.c b/testmode.c
index a1744755..2834400f 100644
--- a/testmode.c
+++ b/testmode.c
@@ -25,6 +25,8 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
[MT76_TM_ATTR_TX_DUTY_CYCLE] = { .type = NLA_U8 },
[MT76_TM_ATTR_TX_IPG] = { .type = NLA_U32 },
[MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
+ [MT76_TM_ATTR_TX_PKT_BW] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_PRI_SEL] = { .type = NLA_U8 },
[MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
[MT76_TM_ATTR_DRV_DATA] = { .type = NLA_NESTED },
[MT76_TM_ATTR_OFF_CH_SCAN_CH] = { .type = NLA_U8 },
@@ -567,12 +569,15 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
&td->tx_duty_cycle, 0, 99) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
&td->tx_power_control, 0, 1) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_PKT_BW], &td->tx_pkt_bw,
+ NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_320) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_PRI_SEL], &td->tx_pri_sel, 0, 15) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CH], &td->offchan_ch, 36, 196) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH], &td->offchan_center_ch,
36, 196) ||
- mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW],
- &td->offchan_bw, NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_160) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW], &td->offchan_bw,
+ NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_160) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_THRESHOLD], &td->ipi_threshold, 0, 10) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_RESET], &td->ipi_reset, 0, 1))
goto out;
@@ -616,7 +621,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
err = mt76_tm_get_u8(cur, &td->tx_power[idx++], 0, 63);
if (err)
- return err;
+ goto out;
}
}
@@ -823,6 +828,10 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
nla_put_u32(msg, MT76_TM_ATTR_TX_TIME, td->tx_time)) ||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PKT_BW) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_PKT_BW, td->tx_pkt_bw)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_PRI_SEL) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_PRI_SEL, td->tx_pri_sel)) ||
(mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
nla_put_u32(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
goto out;
diff --git a/testmode.h b/testmode.h
index 794a74f9..44f9984c 100644
--- a/testmode.h
+++ b/testmode.h
@@ -37,6 +37,9 @@
* @MT76_TM_ATTR_TX_POWER_CONTROL: enable tx power control (u8)
* @MT76_TM_ATTR_TX_POWER: per-antenna tx power array (nested, u8 attrs)
*
+ * @MT76_TM_ATTR_TX_PKT_BW: per-packet data bandwidth (u8)
+ * @MT76_TM_ATTR_TX_PRI_SEL: primary channel selection index (u8)
+ *
* @MT76_TM_ATTR_FREQ_OFFSET: RF frequency offset (u32)
*
* @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
@@ -104,6 +107,9 @@ enum mt76_testmode_attr {
MT76_TM_ATTR_TX_POWER_CONTROL,
MT76_TM_ATTR_TX_POWER,
+ MT76_TM_ATTR_TX_PKT_BW,
+ MT76_TM_ATTR_TX_PRI_SEL,
+
MT76_TM_ATTR_FREQ_OFFSET,
MT76_TM_ATTR_STATS,
diff --git a/tools/fields.c b/tools/fields.c
index f793d1a5..8b372602 100644
--- a/tools/fields.c
+++ b/tools/fields.c
@@ -35,13 +35,21 @@ static const char * const testmode_tx_mode[] = {
[MT76_TM_TX_MODE_EHT_MU] = "eht_mu",
};
-static const char * const testmode_offchan_bw[] = {
+static const char * const testmode_bw[] = {
[NL80211_CHAN_WIDTH_20_NOHT] = "NOHT",
[NL80211_CHAN_WIDTH_20] = "20",
[NL80211_CHAN_WIDTH_40] = "40",
[NL80211_CHAN_WIDTH_80] = "80",
[NL80211_CHAN_WIDTH_80P80] = "80p80",
[NL80211_CHAN_WIDTH_160] = "160",
+ [NL80211_CHAN_WIDTH_5] = "5",
+ [NL80211_CHAN_WIDTH_10] = "10",
+ [NL80211_CHAN_WIDTH_1] = "1",
+ [NL80211_CHAN_WIDTH_2] = "2",
+ [NL80211_CHAN_WIDTH_4] = "4",
+ [NL80211_CHAN_WIDTH_8] = "8",
+ [NL80211_CHAN_WIDTH_16] = "16",
+ [NL80211_CHAN_WIDTH_320] = "320",
};
static const char * const testmode_txbf_act[] = {
@@ -430,6 +438,8 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
FIELD(u8, TX_POWER_CONTROL, "tx_power_control"),
FIELD_ARRAY(u8, TX_POWER, "tx_power"),
FIELD(u8, TX_ANTENNA, "tx_antenna"),
+ FIELD_ENUM(TX_PKT_BW, "tx_pkt_bw", testmode_bw),
+ FIELD(u8, TX_PRI_SEL, "tx_pri_sel"),
FIELD(u32, FREQ_OFFSET, "freq_offset"),
FIELD(u8, AID, "aid"),
FIELD(u8, RU_ALLOC, "ru_alloc"),
@@ -438,7 +448,7 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
FIELD_ARRAY(u16_hex, TXBF_PARAM, "txbf_param"),
FIELD(u8, OFF_CH_SCAN_CH, "offchan_ch"),
FIELD(u8, OFF_CH_SCAN_CENTER_CH, "offchan_center_ch"),
- FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_offchan_bw),
+ FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_bw),
FIELD(u8, IPI_THRESHOLD, "ipi_threshold"),
FIELD(u32, IPI_PERIOD, "ipi_period"),
FIELD(u8, IPI_RESET, "ipi_reset"),
@@ -469,6 +479,8 @@ static struct nla_policy testdata_policy[NUM_MT76_TM_ATTRS] = {
[MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 },
[MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 },
[MT76_TM_ATTR_TX_SPE_IDX] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_PKT_BW] = { .type = NLA_U8 },
+ [MT76_TM_ATTR_TX_PRI_SEL] = { .type = NLA_U8 },
[MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
[MT76_TM_ATTR_AID] = { .type = NLA_U8 },
[MT76_TM_ATTR_RU_ALLOC] = { .type = NLA_U8 },
--
2.45.2