| 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 |
| |