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