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