developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 1 | From 2d4b4838473a1a02b793b9ba214f03640419f5ba Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 3 | Date: Wed, 1 Mar 2023 12:12:51 +0800 |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 4 | Subject: [PATCH 017/223] mtk: mt76: mt7996: add normal mode pre-calibration |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 5 | support |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 6 | |
| 7 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 8 | --- |
| 9 | mt76_connac_mcu.h | 1 + |
| 10 | mt7996/eeprom.c | 4 ++ |
| 11 | mt7996/eeprom.h | 2 + |
| 12 | mt7996/init.c | 6 ++ |
| 13 | mt7996/main.c | 6 ++ |
| 14 | mt7996/mcu.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++ |
| 15 | mt7996/mt7996.h | 3 + |
| 16 | 7 files changed, 188 insertions(+) |
| 17 | |
| 18 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 19 | index c7fa7b26..a7d7ecce 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 20 | --- a/mt76_connac_mcu.h |
| 21 | +++ b/mt76_connac_mcu.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 22 | @@ -1294,6 +1294,7 @@ enum { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 23 | MCU_UNI_CMD_PP = 0x38, |
| 24 | MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40, |
| 25 | MCU_UNI_CMD_TESTMODE_CTRL = 0x46, |
| 26 | + MCU_UNI_CMD_PRECAL_RESULT = 0x47, |
| 27 | MCU_UNI_CMD_RRO = 0x57, |
| 28 | MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58, |
| 29 | MCU_UNI_CMD_PER_STA_INFO = 0x6d, |
| 30 | diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 31 | index 31b8fd1a..5ff52577 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 32 | --- a/mt7996/eeprom.c |
| 33 | +++ b/mt7996/eeprom.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 34 | @@ -489,6 +489,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev) |
| 35 | if (ret < 0) |
| 36 | return ret; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 37 | |
| 38 | + ret = mt7996_eeprom_load_precal(dev); |
| 39 | + if (ret) |
| 40 | + return ret; |
| 41 | + |
| 42 | ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy); |
| 43 | if (ret < 0) |
| 44 | return ret; |
| 45 | diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 46 | index c1cad4f9..b3b9b854 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 47 | --- a/mt7996/eeprom.h |
| 48 | +++ b/mt7996/eeprom.h |
| 49 | @@ -25,6 +25,8 @@ enum mt7996_eeprom_field { |
| 50 | MT_EE_TX0_POWER_6G = 0x1310, |
| 51 | |
| 52 | __MT_EE_MAX = 0x1dff, |
| 53 | + /* 0x1e10 ~ 0x2d644 used to save group cal data */ |
| 54 | + MT_EE_PRECAL = 0x1e10, |
| 55 | }; |
| 56 | |
| 57 | #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0) |
| 58 | diff --git a/mt7996/init.c b/mt7996/init.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 59 | index dc736a2d..a34e034d 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 60 | --- a/mt7996/init.c |
| 61 | +++ b/mt7996/init.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 62 | @@ -1003,6 +1003,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 63 | if (ret < 0) |
| 64 | return ret; |
| 65 | |
| 66 | + if (dev->flash_mode) { |
| 67 | + ret = mt7996_mcu_apply_group_cal(dev); |
| 68 | + if (ret) |
| 69 | + return ret; |
| 70 | + } |
| 71 | + |
| 72 | /* Beacon and mgmt frames should occupy wcid 0 */ |
| 73 | idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA); |
| 74 | if (idx) |
| 75 | diff --git a/mt7996/main.c b/mt7996/main.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 76 | index b7ae6e1a..9ff9ae0e 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 77 | --- a/mt7996/main.c |
| 78 | +++ b/mt7996/main.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 79 | @@ -310,6 +310,12 @@ int mt7996_set_channel(struct mt76_phy *mphy) |
| 80 | struct mt7996_phy *phy = mphy->priv; |
| 81 | int ret; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 82 | |
| 83 | + if (dev->flash_mode) { |
| 84 | + ret = mt7996_mcu_apply_tx_dpd(phy); |
| 85 | + if (ret) |
| 86 | + goto out; |
| 87 | + } |
| 88 | + |
| 89 | if (mt76_testmode_enabled(phy->mt76) || phy->mt76->test.bf_en) { |
| 90 | mt7996_tm_update_channel(phy); |
| 91 | goto out; |
| 92 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 93 | index 08534fec..b15075ab 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 94 | --- a/mt7996/mcu.c |
| 95 | +++ b/mt7996/mcu.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 96 | @@ -3650,6 +3650,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 97 | return 0; |
| 98 | } |
| 99 | |
| 100 | +static int mt7996_mcu_set_pre_cal(struct mt7996_dev *dev, u32 idx, |
| 101 | + u8 *cal, u32 len, u32 cal_id) |
| 102 | +{ |
| 103 | +#define PRECAL_CMD_PRE_CAL_RESULT 0x0 |
| 104 | + struct { |
| 105 | + /* fixed field */ |
| 106 | + u8 action; |
| 107 | + u8 dest; |
| 108 | + u8 attribute; |
| 109 | + u8 tag_num; |
| 110 | + |
| 111 | + __le16 tag; |
| 112 | + __le16 len; |
| 113 | + |
| 114 | + __le32 cal_id; |
| 115 | + s8 precal; |
| 116 | + u8 band; |
| 117 | + u8 rsv[2]; |
| 118 | + __le32 idx; |
| 119 | + __le32 cal_len; |
| 120 | + } req = { |
| 121 | + .tag = cpu_to_le16(PRECAL_CMD_PRE_CAL_RESULT), |
| 122 | + .len = cpu_to_le16(sizeof(req) - 4 + len), |
| 123 | + .cal_id = cpu_to_le32(cal_id), |
| 124 | + .idx = cpu_to_le32(idx), |
| 125 | + .cal_len = cpu_to_le32(len), |
| 126 | + }; |
| 127 | + struct sk_buff *skb; |
| 128 | + |
| 129 | + if (!len) |
| 130 | + return 0; |
| 131 | + |
| 132 | + skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req) + len); |
| 133 | + if (!skb) |
| 134 | + return -ENOMEM; |
| 135 | + |
| 136 | + skb_put_data(skb, &req, sizeof(req)); |
| 137 | + skb_put_data(skb, cal, len); |
| 138 | + |
| 139 | + return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WM_UNI_CMD(PRECAL_RESULT), false); |
| 140 | +} |
| 141 | + |
| 142 | +int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev) |
| 143 | +{ |
| 144 | + u8 *cal = dev->cal, *eeprom = dev->mt76.eeprom.data; |
| 145 | + u32 idx = 0, total_idx = MT_EE_CAL_GROUP_SIZE / MT_EE_CAL_UNIT; |
| 146 | + u32 offs = MT_EE_DO_PRE_CAL; |
| 147 | + int ret = 0; |
| 148 | + |
| 149 | + if (!(eeprom[offs] & MT_EE_WIFI_CAL_GROUP)) |
| 150 | + return 0; |
| 151 | + |
| 152 | + for (idx = 0; idx < total_idx; idx++, cal += MT_EE_CAL_UNIT) { |
| 153 | + ret = mt7996_mcu_set_pre_cal(dev, idx, cal, MT_EE_CAL_UNIT, RF_PRE_CAL); |
| 154 | + if (ret) |
| 155 | + goto out; |
| 156 | + } |
| 157 | + |
| 158 | + ret = mt7996_mcu_set_pre_cal(dev, total_idx, cal, |
| 159 | + MT_EE_CAL_GROUP_SIZE % MT_EE_CAL_UNIT, RF_PRE_CAL); |
| 160 | + |
| 161 | +out: |
| 162 | + return ret; |
| 163 | +} |
| 164 | + |
| 165 | +int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy) |
| 166 | +{ |
| 167 | + struct mt7996_dev *dev = phy->dev; |
| 168 | + struct mt76_phy *mphy = phy->mt76; |
| 169 | + struct cfg80211_chan_def *chandef = &phy->mt76->chandef; |
| 170 | + enum nl80211_band band = chandef->chan->band; |
| 171 | + enum nl80211_chan_width bw = chandef->width; |
| 172 | + const struct ieee80211_channel *chan_list; |
| 173 | + u32 cal_id, chan_list_size, base_offset = 0, offs = MT_EE_DO_PRE_CAL; |
| 174 | + u32 dpd_size_2g, dpd_size_5g, per_chan_size = DPD_PER_CH_BW20_SIZE; |
| 175 | + u16 channel = ieee80211_frequency_to_channel(chandef->center_freq1); |
| 176 | + u8 dpd_mask, *cal = dev->cal, *eeprom = dev->mt76.eeprom.data; |
| 177 | + int idx, i, ret; |
| 178 | + |
| 179 | + dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ); |
| 180 | + dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ); |
| 181 | + |
| 182 | + switch (band) { |
| 183 | + case NL80211_BAND_2GHZ: |
| 184 | + dpd_mask = MT_EE_WIFI_CAL_DPD_2G; |
| 185 | + /* channel 14 don't need DPD cal */ |
| 186 | + if (channel >= 1 && channel <= 4) |
| 187 | + channel = 3; |
| 188 | + else if (channel >= 5 && channel <= 9) |
| 189 | + channel = 7; |
| 190 | + else if (channel >= 10 && channel <= 13) |
| 191 | + channel = 11; |
| 192 | + else |
| 193 | + return 0; |
| 194 | + cal_id = RF_DPD_FLAT_CAL; |
| 195 | + chan_list = dpd_2g_ch_list_bw20; |
| 196 | + chan_list_size = dpd_2g_bw20_ch_num; |
| 197 | + break; |
| 198 | + case NL80211_BAND_5GHZ: |
| 199 | + dpd_mask = MT_EE_WIFI_CAL_DPD_5G; |
| 200 | + cal_id = RF_DPD_FLAT_5G_CAL; |
| 201 | + chan_list = mphy->sband_5g.sband.channels; |
| 202 | + chan_list_size = mphy->sband_5g.sband.n_channels; |
| 203 | + base_offset += dpd_size_2g; |
| 204 | + if (bw == NL80211_CHAN_WIDTH_160) { |
| 205 | + base_offset += mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE; |
| 206 | + per_chan_size = DPD_PER_CH_GT_BW20_SIZE; |
| 207 | + cal_id = RF_DPD_FLAT_5G_MEM_CAL; |
| 208 | + chan_list = dpd_5g_ch_list_bw160; |
| 209 | + chan_list_size = dpd_5g_bw160_ch_num; |
| 210 | + } else if (bw > NL80211_CHAN_WIDTH_20) { |
| 211 | + /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */ |
| 212 | + channel -= 2; |
| 213 | + } |
| 214 | + break; |
| 215 | + case NL80211_BAND_6GHZ: |
| 216 | + dpd_mask = MT_EE_WIFI_CAL_DPD_6G; |
| 217 | + cal_id = RF_DPD_FLAT_6G_CAL; |
| 218 | + chan_list = mphy->sband_6g.sband.channels; |
| 219 | + chan_list_size = mphy->sband_6g.sband.n_channels; |
| 220 | + base_offset += dpd_size_2g + dpd_size_5g; |
| 221 | + if (bw == NL80211_CHAN_WIDTH_160) { |
| 222 | + base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE; |
| 223 | + per_chan_size = DPD_PER_CH_GT_BW20_SIZE; |
| 224 | + cal_id = RF_DPD_FLAT_6G_MEM_CAL; |
| 225 | + chan_list = dpd_6g_ch_list_bw160; |
| 226 | + chan_list_size = dpd_6g_bw160_ch_num; |
| 227 | + } else if (bw == NL80211_CHAN_WIDTH_320) { |
| 228 | + base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE + |
| 229 | + dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE; |
| 230 | + per_chan_size = DPD_PER_CH_GT_BW20_SIZE; |
| 231 | + cal_id = RF_DPD_FLAT_6G_MEM_CAL; |
| 232 | + chan_list = dpd_6g_ch_list_bw320; |
| 233 | + chan_list_size = dpd_6g_bw320_ch_num; |
| 234 | + } else if (bw > NL80211_CHAN_WIDTH_20) { |
| 235 | + /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */ |
| 236 | + channel -= 2; |
| 237 | + } |
| 238 | + break; |
| 239 | + default: |
| 240 | + dpd_mask = 0; |
| 241 | + break; |
| 242 | + } |
| 243 | + |
| 244 | + if (!(eeprom[offs] & dpd_mask)) |
| 245 | + return 0; |
| 246 | + |
| 247 | + for (idx = 0; idx < chan_list_size; idx++) |
| 248 | + if (channel == chan_list[idx].hw_value) |
| 249 | + break; |
| 250 | + if (idx == chan_list_size) |
| 251 | + return -EINVAL; |
| 252 | + |
| 253 | + cal += MT_EE_CAL_GROUP_SIZE + base_offset + idx * per_chan_size; |
| 254 | + |
| 255 | + for (i = 0; i < per_chan_size / MT_EE_CAL_UNIT; i++) { |
| 256 | + ret = mt7996_mcu_set_pre_cal(dev, i, cal, MT_EE_CAL_UNIT, cal_id); |
| 257 | + if (ret) |
| 258 | + return ret; |
| 259 | + |
| 260 | + cal += MT_EE_CAL_UNIT; |
| 261 | + } |
| 262 | + |
| 263 | + return ret; |
| 264 | +} |
| 265 | + |
| 266 | int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap) |
| 267 | { |
| 268 | #define NIC_CAP 3 |
| 269 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 270 | index 54b81c1e..8770839c 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 271 | --- a/mt7996/mt7996.h |
| 272 | +++ b/mt7996/mt7996.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 273 | @@ -629,6 +629,9 @@ void mt7996_mcu_exit(struct mt7996_dev *dev); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 274 | int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag); |
| 275 | int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id); |
| 276 | int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data); |
| 277 | +int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event); |
| 278 | +int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev); |
| 279 | +int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy); |
| 280 | #ifdef CONFIG_NL80211_TESTMODE |
| 281 | void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb); |
| 282 | #endif |
| 283 | -- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 284 | 2.45.2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 285 | |