blob: fd1c9f7577c44a3d9830ddd4cddbcc8f3e50da1f [file] [log] [blame]
From d04f6dbcf9838918fe2f08b384eb6d65be8c7173 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 8 Jan 2024 10:09:40 +0800
Subject: [PATCH 071/120] mtk: wifi: mt76: testmode: add testmode ibf 5T5R
support
Add testmode ibf 5T5R support for Kite BE7200 2i5i
CR-Id: WCNCR00274293
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
mt7996/mcu.h | 1 +
mt7996/mtk_mcu.h | 11 ++++++++
mt7996/testmode.c | 71 ++++++++++++++++++++++++++++++++++-------------
testmode.c | 10 ++++---
4 files changed, 70 insertions(+), 23 deletions(-)
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
index 398bf3d27..67777a639 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -756,6 +756,7 @@ enum {
BF_TXSND_INFO = 24,
BF_CMD_TXCMD = 27,
BF_CFG_PHY = 28,
+ BF_PROFILE_WRITE_20M_ALL_5X5 = 30,
};
struct ra_rate {
diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
index 7bfb5920d..58d61c517 100644
--- a/mt7996/mtk_mcu.h
+++ b/mt7996/mtk_mcu.h
@@ -763,6 +763,14 @@ struct mt7996_pfmu_data {
__le16 phi31;
};
+struct mt7996_pfmu_data_5x5 {
+ __le16 subc_idx;
+ __le16 phi11;
+ __le16 phi21;
+ __le16 phi31;
+ __le16 phi41;
+};
+
struct mt7996_ibf_cal_info {
struct mt7996_mcu_bf_basic_event event;
@@ -818,6 +826,9 @@ static inline int get_ibf_version(struct mt7996_dev *dev)
}
#define MT7996_TXBF_SUBCAR_NUM 64
+#define MT7996_TXBF_PFMU_DATA_LEN (MT7996_TXBF_SUBCAR_NUM * sizeof(struct mt7996_pfmu_data))
+#define MT7996_TXBF_PFMU_DATA_LEN_5X5 (MT7996_TXBF_SUBCAR_NUM * \
+ sizeof(struct mt7996_pfmu_data_5x5))
enum {
UNI_EVENT_BF_PFMU_TAG = 0x5,
diff --git a/mt7996/testmode.c b/mt7996/testmode.c
index 4188cb35a..9fa4edcd6 100644
--- a/mt7996/testmode.c
+++ b/mt7996/testmode.c
@@ -1149,9 +1149,9 @@ mt7996_tm_txbf_init(struct mt7996_phy *phy, u16 *val)
}
if (!dev->test.txbf_pfmu_data) {
+ /* allocate max size for 5x5 pfmu data */
pfmu_data = devm_kzalloc(dev->mt76.dev,
- sizeof(struct mt7996_pfmu_data) *
- MT7996_TXBF_SUBCAR_NUM,
+ MT7996_TXBF_PFMU_DATA_LEN_5X5,
GFP_KERNEL);
if (!pfmu_data)
return -ENOMEM;
@@ -1212,6 +1212,11 @@ mt7996_tm_txbf_init(struct mt7996_phy *phy, u16 *val)
td->tx_rate_mode = MT76_TM_TX_MODE_HT;
td->tx_rate_sgi = 0;
+ /* 5T5R ibf */
+ if (nss == 5) {
+ td->tx_rate_mode = MT76_TM_TX_MODE_VHT;
+ td->tx_rate_idx = 7;
+ }
} else {
if (td->is_txbf_dut) {
/* Enable ETxBF Capability */
@@ -1356,12 +1361,12 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
};
u8 ndp_rate, ndpa_rate, rept_poll_rate, bf_bw;
- if (td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU ||
- td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) {
+ if ((td->tx_rate_mode == MT76_TM_TX_MODE_HE_SU ||
+ td->tx_rate_mode == MT76_TM_TX_MODE_EHT_SU) && !td->ibf) {
rept_poll_rate = 0x49;
ndpa_rate = 0x49;
ndp_rate = 0;
- } else if (td->tx_rate_mode == MT76_TM_TX_MODE_VHT) {
+ } else if (td->tx_rate_mode == MT76_TM_TX_MODE_VHT && !td->ibf) {
rept_poll_rate = 0x9;
ndpa_rate = 0x9;
ndp_rate = 0;
@@ -1372,8 +1377,16 @@ mt7996_tm_add_txbf_sta(struct mt7996_phy *phy, u8 pfmu_idx, u8 nr, u8 nc, bool e
ndp_rate = 8;
else if (nr == 2)
ndp_rate = 16;
+ else if (nr == 4)
+ ndp_rate = 32;
else
ndp_rate = 24;
+
+ /* 5T5R ebf profile for ibf cal */
+ if (nr == 4 && td->ibf && ebf) {
+ ndp_rate = 0;
+ ndpa_rate = 11;
+ }
}
bf_bw = mt7996_tm_bw_mapping(phy->mt76->chandef.width, BW_MAP_NL_TO_BF);
@@ -1406,7 +1419,7 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
struct mt76_testmode_data *td = &phy->mt76->test;
struct mt7996_dev *dev = phy->dev;
struct mt7996_pfmu_tag *tag = dev->test.txbf_pfmu_tag;
- u8 pfmu_idx = val[0], nc = val[2], nr;
+ u8 rate, pfmu_idx = val[0], nc = val[2], nr;
int ret;
bool is_atenl = val[5];
@@ -1414,6 +1427,8 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
nr = 1;
else if (td->tx_antenna_mask == 7)
nr = 2;
+ else if (td->tx_antenna_mask == 31)
+ nr = 4;
else
nr = 3;
@@ -1437,7 +1452,8 @@ mt7996_tm_txbf_profile_update(struct mt7996_phy *phy, u16 *val, bool ebf)
tag->t1.row_id2 = 5;
tag->t1.row_id3 = 6;
tag->t1.row_id4 = 7;
- tag->t1.lm = mt7996_tm_rate_mapping(MT76_TM_TX_MODE_OFDM, RATE_MODE_TO_LM);
+ rate = nr == 4 ? td->tx_rate_mode : MT76_TM_TX_MODE_OFDM;
+ tag->t1.lm = mt7996_tm_rate_mapping(rate, RATE_MODE_TO_LM);
tag->t2.ibf_timeout = 0xff;
tag->t2.ibf_nr = nr;
@@ -1500,7 +1516,6 @@ mt7996_tm_txbf_phase_cal(struct mt7996_phy *phy, u16 *val)
static int
mt7996_tm_txbf_profile_update_all(struct mt7996_phy *phy, u16 *val)
{
-#define MT7996_TXBF_PFMU_DATA_LEN (MT7996_TXBF_SUBCAR_NUM * sizeof(struct mt7996_pfmu_data))
struct mt76_testmode_data *td = &phy->mt76->test;
u8 nss = hweight8(td->tx_antenna_mask);
u16 pfmu_idx = val[0];
@@ -1509,8 +1524,10 @@ mt7996_tm_txbf_profile_update_all(struct mt7996_phy *phy, u16 *val)
u16 angle21 = val[3];
u16 angle31 = val[4];
u16 angle41 = val[5];
- s16 phi11 = 0, phi21 = 0, phi31 = 0;
- struct mt7996_pfmu_data *pfmu_data;
+ u16 angle51 = val[6];
+ s16 phi11 = 0, phi21 = 0, phi31 = 0, phi41 = 0;
+ s16 *pfmu_data;
+ int offs = subc_id * sizeof(struct mt7996_pfmu_data) / sizeof(*pfmu_data);
if (subc_id > MT7996_TXBF_SUBCAR_NUM - 1)
return -EINVAL;
@@ -1520,35 +1537,51 @@ mt7996_tm_txbf_profile_update_all(struct mt7996_phy *phy, u16 *val)
} else if (nss == 3) {
phi11 = (s16)(angle31 - angle11);
phi21 = (s16)(angle31 - angle21);
+ } else if (nss == 5) {
+ phi11 = (s16)(angle51 - angle11);
+ phi21 = (s16)(angle51 - angle21);
+ phi31 = (s16)(angle51 - angle31);
+ phi41 = (s16)(angle51 - angle41);
+ offs = subc_id * sizeof(struct mt7996_pfmu_data_5x5) / sizeof(*pfmu_data);
} else {
phi11 = (s16)(angle41 - angle11);
phi21 = (s16)(angle41 - angle21);
phi31 = (s16)(angle41 - angle31);
}
- pfmu_data = (struct mt7996_pfmu_data *)phy->dev->test.txbf_pfmu_data;
- pfmu_data = &pfmu_data[subc_id];
+ pfmu_data = (s16 *)phy->dev->test.txbf_pfmu_data;
+ pfmu_data += offs;
if (subc_id < 32)
- pfmu_data->subc_idx = cpu_to_le16(subc_id + 224);
+ pfmu_data[0] = cpu_to_le16(subc_id + 224);
else
- pfmu_data->subc_idx = cpu_to_le16(subc_id - 32);
+ pfmu_data[0] = cpu_to_le16(subc_id - 32);
+
+ pfmu_data[1] = cpu_to_le16(phi11);
+ pfmu_data[2] = cpu_to_le16(phi21);
+ pfmu_data[3] = cpu_to_le16(phi31);
+ if (nss == 5)
+ pfmu_data[4] = cpu_to_le16(phi41);
- pfmu_data->phi11 = cpu_to_le16(phi11);
- pfmu_data->phi21 = cpu_to_le16(phi21);
- pfmu_data->phi31 = cpu_to_le16(phi31);
if (subc_id == MT7996_TXBF_SUBCAR_NUM - 1) {
struct mt7996_dev *dev = phy->dev;
struct mt7996_tm_bf_req req = {
.pfmu_data_all = {
- .tag = cpu_to_le16(BF_PROFILE_WRITE_20M_ALL),
+ .tag = cpu_to_le16(BF_PROFILE_WRITE_20M_ALL_5X5),
.len = cpu_to_le16(sizeof(req.pfmu_data_all)),
.pfmu_id = pfmu_idx,
.band_idx = phy->mt76->band_idx,
},
};
+ int size = MT7996_TXBF_PFMU_DATA_LEN_5X5;
- memcpy(req.pfmu_data_all.buf, dev->test.txbf_pfmu_data, MT7996_TXBF_PFMU_DATA_LEN);
+ if (nss != 5) {
+ size = MT7996_TXBF_PFMU_DATA_LEN;
+ req.pfmu_data_all.tag = cpu_to_le16(BF_PROFILE_WRITE_20M_ALL);
+ req.pfmu_data_all.len = cpu_to_le16(sizeof(req.pfmu_data_all) -
+ MT7996_TXBF_PFMU_DATA_LEN_5X5 + size);
+ }
+ memcpy(req.pfmu_data_all.buf, dev->test.txbf_pfmu_data, size);
return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(BF),
&req, sizeof(req), true);
diff --git a/testmode.c b/testmode.c
index 09ab68ce4..2dd184e48 100644
--- a/testmode.c
+++ b/testmode.c
@@ -471,26 +471,28 @@ static int
mt76_testmode_txbf_profile_update_all_cmd(struct mt76_phy *phy, struct nlattr **tb, u32 state)
{
#define PARAM_UNIT 5
+#define PARAM_UNIT_5X5 6
static u8 pfmu_idx;
struct mt76_testmode_data *td = &phy->test;
struct mt76_dev *dev = phy->dev;
struct nlattr *cur;
- u16 tmp_val[PARAM_UNIT], *val = td->txbf_param;
+ u16 tmp_val[PARAM_UNIT_5X5], *val = td->txbf_param;
int idx, rem, ret, i = 0;
+ int param_len = td->tx_antenna_mask == 31 ? PARAM_UNIT_5X5 : PARAM_UNIT;
memset(td->txbf_param, 0, sizeof(td->txbf_param));
nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) {
if (nla_len(cur) != 2)
return -EINVAL;
- idx = i % PARAM_UNIT;
+ idx = i % param_len;
tmp_val[idx] = nla_get_u16(cur);
if (idx == 1 && (tmp_val[idx] == 0xf0 || tmp_val[idx] == 0xff)) {
pfmu_idx = tmp_val[0];
return 0;
}
- if (idx == PARAM_UNIT - 1) {
+ if (idx == param_len - 1) {
val[0] = pfmu_idx;
- memcpy(val + 1, tmp_val, sizeof(tmp_val));
+ memcpy(val + 1, tmp_val, param_len * sizeof(u16));
if (dev->test_ops->set_params) {
ret = dev->test_ops->set_params(phy, tb, state);
if (ret)
--
2.39.2