1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2019 MediaTek Inc. 3 * 4 * Author: Ryder Lee <ryder.lee@mediatek.com> 5 * Felix Fietkau <nbd@nbd.name> 6 */ 7 8 #include <linux/of.h> 9 #include "mt7615.h" 10 #include "eeprom.h" 11 12 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base, 13 u16 addr, u8 *data) 14 { 15 u32 val; 16 int i; 17 18 val = mt76_rr(dev, base + MT_EFUSE_CTRL); 19 val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE); 20 val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf); 21 val |= MT_EFUSE_CTRL_KICK; 22 mt76_wr(dev, base + MT_EFUSE_CTRL, val); 23 24 if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000)) 25 return -ETIMEDOUT; 26 27 udelay(2); 28 29 val = mt76_rr(dev, base + MT_EFUSE_CTRL); 30 if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT || 31 WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) { 32 memset(data, 0x0, 16); 33 return 0; 34 } 35 36 for (i = 0; i < 4; i++) { 37 val = mt76_rr(dev, base + MT_EFUSE_RDATA(i)); 38 put_unaligned_le32(val, data + 4 * i); 39 } 40 41 return 0; 42 } 43 44 static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base) 45 { 46 int i, len = MT7615_EEPROM_SIZE; 47 void *buf; 48 u32 val; 49 50 if (is_mt7663(&dev->mt76)) 51 len = MT7663_EEPROM_SIZE; 52 53 val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL); 54 if (val & MT_EFUSE_BASE_CTRL_EMPTY) 55 return 0; 56 57 dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL); 58 dev->mt76.otp.size = len; 59 if (!dev->mt76.otp.data) 60 return -ENOMEM; 61 62 buf = dev->mt76.otp.data; 63 for (i = 0; i + 16 <= len; i += 16) { 64 int ret; 65 66 ret = mt7615_efuse_read(dev, base, i, buf + i); 67 if (ret) 68 return ret; 69 } 70 71 return 0; 72 } 73 74 static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr) 75 { 76 int ret; 77 78 BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE < MT7663_EEPROM_SIZE); 79 80 ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE); 81 if (ret < 0) 82 return ret; 83 84 return mt7615_efuse_init(dev, addr); 85 } 86 87 static int mt7615_check_eeprom(struct mt76_dev *dev) 88 { 89 u16 val = get_unaligned_le16(dev->eeprom.data); 90 91 switch (val) { 92 case 0x7615: 93 case 0x7622: 94 case 0x7663: 95 return 0; 96 default: 97 return -EINVAL; 98 } 99 } 100 101 static void 102 mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) 103 { 104 u8 val, *eeprom = dev->mt76.eeprom.data; 105 106 if (is_mt7663(&dev->mt76)) { 107 /* dual band */ 108 dev->mphy.cap.has_2ghz = true; 109 dev->mphy.cap.has_5ghz = true; 110 return; 111 } 112 113 if (is_mt7622(&dev->mt76)) { 114 /* 2GHz only */ 115 dev->mphy.cap.has_2ghz = true; 116 return; 117 } 118 119 if (is_mt7611(&dev->mt76)) { 120 /* 5GHz only */ 121 dev->mphy.cap.has_5ghz = true; 122 return; 123 } 124 125 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL, 126 eeprom[MT_EE_WIFI_CONF]); 127 switch (val) { 128 case MT_EE_5GHZ: 129 dev->mphy.cap.has_5ghz = true; 130 break; 131 case MT_EE_DBDC: 132 dev->dbdc_support = true; 133 fallthrough; 134 case MT_EE_2GHZ: 135 dev->mphy.cap.has_2ghz = true; 136 break; 137 default: 138 dev->mphy.cap.has_2ghz = true; 139 dev->mphy.cap.has_5ghz = true; 140 break; 141 } 142 } 143 144 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev) 145 { 146 u8 *eeprom = dev->mt76.eeprom.data; 147 u8 tx_mask, max_nss; 148 149 mt7615_eeprom_parse_hw_band_cap(dev); 150 151 if (is_mt7663(&dev->mt76)) { 152 max_nss = 2; 153 tx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK, 154 eeprom[MT7663_EE_HW_CONF1]); 155 } else { 156 u32 val; 157 158 /* read tx-rx mask from eeprom */ 159 val = mt76_rr(dev, MT_TOP_STRAP_STA); 160 max_nss = val & MT_TOP_3NSS ? 3 : 4; 161 162 tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK, 163 eeprom[MT_EE_NIC_CONF_0]); 164 } 165 if (!tx_mask || tx_mask > max_nss) 166 tx_mask = max_nss; 167 168 dev->chainmask = BIT(tx_mask) - 1; 169 dev->mphy.antenna_mask = dev->chainmask; 170 dev->mphy.chainmask = dev->chainmask; 171 } 172 173 static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev, 174 struct ieee80211_channel *chan, 175 u8 chain_idx) 176 { 177 int index, group; 178 179 if (chain_idx > 1) 180 return -EINVAL; 181 182 if (chan->band == NL80211_BAND_2GHZ) 183 return MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx << 4); 184 185 group = mt7615_get_channel_group(chan->hw_value); 186 if (chain_idx == 1) 187 index = MT7663_EE_TX1_5G_G0_TARGET_POWER; 188 else 189 index = MT7663_EE_TX0_5G_G0_TARGET_POWER; 190 191 return index + group * 3; 192 } 193 194 int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev, 195 struct ieee80211_channel *chan, 196 u8 chain_idx) 197 { 198 int index; 199 200 if (is_mt7663(&dev->mt76)) 201 return mt7663_eeprom_get_target_power_index(dev, chan, 202 chain_idx); 203 204 if (chain_idx > 3) 205 return -EINVAL; 206 207 /* TSSI disabled */ 208 if (mt7615_ext_pa_enabled(dev, chan->band)) { 209 if (chan->band == NL80211_BAND_2GHZ) 210 return MT_EE_EXT_PA_2G_TARGET_POWER; 211 else 212 return MT_EE_EXT_PA_5G_TARGET_POWER; 213 } 214 215 /* TSSI enabled */ 216 if (chan->band == NL80211_BAND_2GHZ) { 217 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6; 218 } else { 219 int group = mt7615_get_channel_group(chan->hw_value); 220 221 switch (chain_idx) { 222 case 1: 223 index = MT_EE_TX1_5G_G0_TARGET_POWER; 224 break; 225 case 2: 226 index = MT_EE_TX2_5G_G0_TARGET_POWER; 227 break; 228 case 3: 229 index = MT_EE_TX3_5G_G0_TARGET_POWER; 230 break; 231 case 0: 232 default: 233 index = MT_EE_TX0_5G_G0_TARGET_POWER; 234 break; 235 } 236 index += 5 * group; 237 } 238 239 return index; 240 } 241 242 int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev, 243 enum nl80211_band band) 244 { 245 /* assume the first rate has the highest power offset */ 246 if (is_mt7663(&dev->mt76)) { 247 if (band == NL80211_BAND_2GHZ) 248 return MT_EE_TX0_5G_G0_TARGET_POWER; 249 else 250 return MT7663_EE_5G_RATE_POWER; 251 } 252 253 if (band == NL80211_BAND_2GHZ) 254 return MT_EE_2G_RATE_POWER; 255 else 256 return MT_EE_5G_RATE_POWER; 257 } 258 259 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev) 260 { 261 static const u16 ical[] = { 262 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 263 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87, 264 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0, 265 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4, 266 0xf7, 0xff, 267 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159, 268 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e, 269 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b, 270 0x18c 271 }; 272 static const u16 ical_nocheck[] = { 273 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 274 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1, 275 0x3b2 276 }; 277 u8 *eeprom = dev->mt76.eeprom.data; 278 u8 *otp = dev->mt76.otp.data; 279 int i; 280 281 if (!otp) 282 return; 283 284 for (i = 0; i < ARRAY_SIZE(ical); i++) 285 if (!otp[ical[i]]) 286 return; 287 288 for (i = 0; i < ARRAY_SIZE(ical); i++) 289 eeprom[ical[i]] = otp[ical[i]]; 290 291 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++) 292 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]]; 293 } 294 295 static void mt7622_apply_cal_free_data(struct mt7615_dev *dev) 296 { 297 static const u16 ical[] = { 298 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b 299 }; 300 u8 *eeprom = dev->mt76.eeprom.data; 301 u8 *otp = dev->mt76.otp.data; 302 int i; 303 304 if (!otp) 305 return; 306 307 for (i = 0; i < ARRAY_SIZE(ical); i++) { 308 if (!otp[ical[i]]) 309 continue; 310 311 eeprom[ical[i]] = otp[ical[i]]; 312 } 313 } 314 315 static void mt7615_cal_free_data(struct mt7615_dev *dev) 316 { 317 struct device_node *np = dev->mt76.dev->of_node; 318 319 if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp")) 320 return; 321 322 switch (mt76_chip(&dev->mt76)) { 323 case 0x7622: 324 mt7622_apply_cal_free_data(dev); 325 break; 326 case 0x7615: 327 case 0x7611: 328 mt7615_apply_cal_free_data(dev); 329 break; 330 } 331 } 332 333 int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr) 334 { 335 int ret; 336 337 ret = mt7615_eeprom_load(dev, addr); 338 if (ret < 0) 339 return ret; 340 341 ret = mt7615_check_eeprom(&dev->mt76); 342 if (ret && dev->mt76.otp.data) { 343 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data, 344 dev->mt76.otp.size); 345 } else { 346 dev->flash_eeprom = true; 347 mt7615_cal_free_data(dev); 348 } 349 350 mt7615_eeprom_parse_hw_cap(dev); 351 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, 352 ETH_ALEN); 353 354 mt76_eeprom_override(&dev->mphy); 355 356 return 0; 357 } 358 EXPORT_SYMBOL_GPL(mt7615_eeprom_init); 359