1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include <linux/firmware.h> 5 #include "mt7915.h" 6 #include "eeprom.h" 7 8 static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) 9 { 10 struct mt76_dev *mdev = &dev->mt76; 11 u8 *eeprom = mdev->eeprom.data; 12 u32 val = eeprom[MT_EE_DO_PRE_CAL]; 13 u32 offs; 14 15 if (!dev->flash_mode) 16 return 0; 17 18 if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP)) 19 return 0; 20 21 val = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE; 22 dev->cal = devm_kzalloc(mdev->dev, val, GFP_KERNEL); 23 if (!dev->cal) 24 return -ENOMEM; 25 26 offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2; 27 28 return mt76_get_of_eeprom(mdev, dev->cal, offs, val); 29 } 30 31 static int mt7915_check_eeprom(struct mt7915_dev *dev) 32 { 33 u8 *eeprom = dev->mt76.eeprom.data; 34 u16 val = get_unaligned_le16(eeprom); 35 36 #define CHECK_EEPROM_ERR(match) (match ? 0 : -EINVAL) 37 switch (val) { 38 case 0x7915: 39 return CHECK_EEPROM_ERR(is_mt7915(&dev->mt76)); 40 case 0x7916: 41 return CHECK_EEPROM_ERR(is_mt7916(&dev->mt76)); 42 case 0x7986: 43 return CHECK_EEPROM_ERR(is_mt7986(&dev->mt76)); 44 default: 45 return -EINVAL; 46 } 47 } 48 49 static char *mt7915_eeprom_name(struct mt7915_dev *dev) 50 { 51 switch (mt76_chip(&dev->mt76)) { 52 case 0x7915: 53 return dev->dbdc_support ? 54 MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT; 55 case 0x7986: 56 switch (mt7915_check_adie(dev, true)) { 57 case MT7976_ONE_ADIE_DBDC: 58 return MT7986_EEPROM_MT7976_DEFAULT_DBDC; 59 case MT7975_ONE_ADIE: 60 return MT7986_EEPROM_MT7975_DEFAULT; 61 case MT7976_ONE_ADIE: 62 return MT7986_EEPROM_MT7976_DEFAULT; 63 case MT7975_DUAL_ADIE: 64 return MT7986_EEPROM_MT7975_DUAL_DEFAULT; 65 case MT7976_DUAL_ADIE: 66 return MT7986_EEPROM_MT7976_DUAL_DEFAULT; 67 default: 68 break; 69 } 70 return NULL; 71 default: 72 return MT7916_EEPROM_DEFAULT; 73 } 74 } 75 76 static int 77 mt7915_eeprom_load_default(struct mt7915_dev *dev) 78 { 79 u8 *eeprom = dev->mt76.eeprom.data; 80 const struct firmware *fw = NULL; 81 int ret; 82 83 ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev); 84 if (ret) 85 return ret; 86 87 if (!fw || !fw->data) { 88 dev_err(dev->mt76.dev, "Invalid default bin\n"); 89 ret = -EINVAL; 90 goto out; 91 } 92 93 memcpy(eeprom, fw->data, mt7915_eeprom_size(dev)); 94 dev->flash_mode = true; 95 96 out: 97 release_firmware(fw); 98 99 return ret; 100 } 101 102 static int mt7915_eeprom_load(struct mt7915_dev *dev) 103 { 104 int ret; 105 u16 eeprom_size = mt7915_eeprom_size(dev); 106 107 ret = mt76_eeprom_init(&dev->mt76, eeprom_size); 108 if (ret < 0) 109 return ret; 110 111 if (ret) { 112 dev->flash_mode = true; 113 } else { 114 u8 free_block_num; 115 u32 block_num, i; 116 u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE; 117 118 ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num); 119 if (ret < 0) 120 return ret; 121 122 /* efuse info isn't enough */ 123 if (free_block_num >= 29) 124 return -EINVAL; 125 126 /* read eeprom data from efuse */ 127 block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size); 128 for (i = 0; i < block_num; i++) { 129 ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size); 130 if (ret < 0) 131 return ret; 132 } 133 } 134 135 return mt7915_check_eeprom(dev); 136 } 137 138 static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) 139 { 140 struct mt7915_dev *dev = phy->dev; 141 u8 *eeprom = dev->mt76.eeprom.data; 142 u8 band = phy->mt76->band_idx; 143 u32 val; 144 145 val = eeprom[MT_EE_WIFI_CONF + band]; 146 val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); 147 148 if (!is_mt7915(&dev->mt76)) { 149 switch (val) { 150 case MT_EE_V2_BAND_SEL_5GHZ: 151 phy->mt76->cap.has_5ghz = true; 152 return; 153 case MT_EE_V2_BAND_SEL_6GHZ: 154 phy->mt76->cap.has_6ghz = true; 155 return; 156 case MT_EE_V2_BAND_SEL_5GHZ_6GHZ: 157 phy->mt76->cap.has_5ghz = true; 158 phy->mt76->cap.has_6ghz = true; 159 return; 160 default: 161 phy->mt76->cap.has_2ghz = true; 162 return; 163 } 164 } else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) { 165 val = band ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; 166 } 167 168 switch (val) { 169 case MT_EE_BAND_SEL_5GHZ: 170 phy->mt76->cap.has_5ghz = true; 171 break; 172 case MT_EE_BAND_SEL_2GHZ: 173 phy->mt76->cap.has_2ghz = true; 174 break; 175 default: 176 phy->mt76->cap.has_2ghz = true; 177 phy->mt76->cap.has_5ghz = true; 178 break; 179 } 180 } 181 182 void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, 183 struct mt7915_phy *phy) 184 { 185 u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data; 186 struct mt76_phy *mphy = phy->mt76; 187 u8 band = phy->mt76->band_idx; 188 189 mt7915_eeprom_parse_band_config(phy); 190 191 /* read tx/rx path from eeprom */ 192 if (is_mt7915(&dev->mt76)) { 193 path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, 194 eeprom[MT_EE_WIFI_CONF]); 195 } else { 196 path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, 197 eeprom[MT_EE_WIFI_CONF + band]); 198 } 199 200 if (!path || path > 4) 201 path = 4; 202 203 /* read tx/rx stream */ 204 nss = path; 205 if (dev->dbdc_support) { 206 if (is_mt7915(&dev->mt76)) { 207 path = min_t(u8, path, 2); 208 nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0, 209 eeprom[MT_EE_WIFI_CONF + 3]); 210 if (band) 211 nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1, 212 eeprom[MT_EE_WIFI_CONF + 3]); 213 } else { 214 nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM, 215 eeprom[MT_EE_WIFI_CONF + 2 + band]); 216 } 217 218 if (!is_mt7986(&dev->mt76)) 219 nss_max = 2; 220 } 221 222 if (!nss) 223 nss = nss_max; 224 nss = min_t(u8, min_t(u8, nss_max, nss), path); 225 226 mphy->chainmask = BIT(path) - 1; 227 if (band) 228 mphy->chainmask <<= dev->chainshift; 229 mphy->antenna_mask = BIT(nss) - 1; 230 dev->chainmask |= mphy->chainmask; 231 dev->chainshift = hweight8(dev->mphy.chainmask); 232 } 233 234 int mt7915_eeprom_init(struct mt7915_dev *dev) 235 { 236 int ret; 237 238 ret = mt7915_eeprom_load(dev); 239 if (ret < 0) { 240 if (ret != -EINVAL) 241 return ret; 242 243 dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n"); 244 ret = mt7915_eeprom_load_default(dev); 245 if (ret) 246 return ret; 247 } 248 249 ret = mt7915_eeprom_load_precal(dev); 250 if (ret) 251 return ret; 252 253 mt7915_eeprom_parse_hw_cap(dev, &dev->phy); 254 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, 255 ETH_ALEN); 256 257 mt76_eeprom_override(&dev->mphy); 258 259 return 0; 260 } 261 262 int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, 263 struct ieee80211_channel *chan, 264 u8 chain_idx) 265 { 266 u8 *eeprom = dev->mt76.eeprom.data; 267 int index, target_power; 268 bool tssi_on, is_7976; 269 270 if (chain_idx > 3) 271 return -EINVAL; 272 273 tssi_on = mt7915_tssi_enabled(dev, chan->band); 274 is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76); 275 276 if (chan->band == NL80211_BAND_2GHZ) { 277 if (is_7976) { 278 index = MT_EE_TX0_POWER_2G_V2 + chain_idx; 279 target_power = eeprom[index]; 280 } else { 281 index = MT_EE_TX0_POWER_2G + chain_idx * 3; 282 target_power = eeprom[index]; 283 284 if (!tssi_on) 285 target_power += eeprom[index + 1]; 286 } 287 } else if (chan->band == NL80211_BAND_5GHZ) { 288 int group = mt7915_get_channel_group_5g(chan->hw_value, is_7976); 289 290 if (is_7976) { 291 index = MT_EE_TX0_POWER_5G_V2 + chain_idx * 5; 292 target_power = eeprom[index + group]; 293 } else { 294 index = MT_EE_TX0_POWER_5G + chain_idx * 12; 295 target_power = eeprom[index + group]; 296 297 if (!tssi_on) 298 target_power += eeprom[index + 8]; 299 } 300 } else { 301 int group = mt7915_get_channel_group_6g(chan->hw_value); 302 303 index = MT_EE_TX0_POWER_6G_V2 + chain_idx * 8; 304 target_power = is_7976 ? eeprom[index + group] : 0; 305 } 306 307 return target_power; 308 } 309 310 s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band) 311 { 312 u8 *eeprom = dev->mt76.eeprom.data; 313 u32 val, offs; 314 s8 delta; 315 bool is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76); 316 317 if (band == NL80211_BAND_2GHZ) 318 offs = is_7976 ? MT_EE_RATE_DELTA_2G_V2 : MT_EE_RATE_DELTA_2G; 319 else if (band == NL80211_BAND_5GHZ) 320 offs = is_7976 ? MT_EE_RATE_DELTA_5G_V2 : MT_EE_RATE_DELTA_5G; 321 else 322 offs = is_7976 ? MT_EE_RATE_DELTA_6G_V2 : 0; 323 324 val = eeprom[offs]; 325 326 if (!offs || !(val & MT_EE_RATE_DELTA_EN)) 327 return 0; 328 329 delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val); 330 331 return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta; 332 } 333 334 const u8 mt7915_sku_group_len[] = { 335 [SKU_CCK] = 4, 336 [SKU_OFDM] = 8, 337 [SKU_HT_BW20] = 8, 338 [SKU_HT_BW40] = 9, 339 [SKU_VHT_BW20] = 12, 340 [SKU_VHT_BW40] = 12, 341 [SKU_VHT_BW80] = 12, 342 [SKU_VHT_BW160] = 12, 343 [SKU_HE_RU26] = 12, 344 [SKU_HE_RU52] = 12, 345 [SKU_HE_RU106] = 12, 346 [SKU_HE_RU242] = 12, 347 [SKU_HE_RU484] = 12, 348 [SKU_HE_RU996] = 12, 349 [SKU_HE_RU2x996] = 12 350 }; 351