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 "mt7615.h" 9 #include "eeprom.h" 10 11 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base, 12 u16 addr, u8 *data) 13 { 14 u32 val; 15 int i; 16 17 val = mt76_rr(dev, base + MT_EFUSE_CTRL); 18 val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE); 19 val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf); 20 val |= MT_EFUSE_CTRL_KICK; 21 mt76_wr(dev, base + MT_EFUSE_CTRL, val); 22 23 if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000)) 24 return -ETIMEDOUT; 25 26 udelay(2); 27 28 val = mt76_rr(dev, base + MT_EFUSE_CTRL); 29 if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT || 30 WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) { 31 memset(data, 0x0, 16); 32 return 0; 33 } 34 35 for (i = 0; i < 4; i++) { 36 val = mt76_rr(dev, base + MT_EFUSE_RDATA(i)); 37 put_unaligned_le32(val, data + 4 * i); 38 } 39 40 return 0; 41 } 42 43 static int mt7615_efuse_init(struct mt7615_dev *dev) 44 { 45 u32 val, base = mt7615_reg_map(dev, MT_EFUSE_BASE); 46 int i, len = MT7615_EEPROM_SIZE; 47 void *buf; 48 49 val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL); 50 if (val & MT_EFUSE_BASE_CTRL_EMPTY) 51 return 0; 52 53 dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL); 54 dev->mt76.otp.size = len; 55 if (!dev->mt76.otp.data) 56 return -ENOMEM; 57 58 buf = dev->mt76.otp.data; 59 for (i = 0; i + 16 <= len; i += 16) { 60 int ret; 61 62 ret = mt7615_efuse_read(dev, base, i, buf + i); 63 if (ret) 64 return ret; 65 } 66 67 return 0; 68 } 69 70 static int mt7615_eeprom_load(struct mt7615_dev *dev) 71 { 72 int ret; 73 74 ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE); 75 if (ret < 0) 76 return ret; 77 78 return mt7615_efuse_init(dev); 79 } 80 81 static int mt7615_check_eeprom(struct mt76_dev *dev) 82 { 83 u16 val = get_unaligned_le16(dev->eeprom.data); 84 85 switch (val) { 86 case 0x7615: 87 case 0x7622: 88 return 0; 89 default: 90 return -EINVAL; 91 } 92 } 93 94 static void 95 mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) 96 { 97 u8 val, *eeprom = dev->mt76.eeprom.data; 98 99 if (is_mt7663(&dev->mt76)) { 100 /* dual band */ 101 dev->mt76.cap.has_2ghz = true; 102 dev->mt76.cap.has_5ghz = true; 103 return; 104 } 105 106 if (is_mt7622(&dev->mt76)) { 107 /* 2GHz only */ 108 dev->mt76.cap.has_2ghz = true; 109 return; 110 } 111 112 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL, 113 eeprom[MT_EE_WIFI_CONF]); 114 switch (val) { 115 case MT_EE_5GHZ: 116 dev->mt76.cap.has_5ghz = true; 117 break; 118 case MT_EE_2GHZ: 119 dev->mt76.cap.has_2ghz = true; 120 break; 121 default: 122 dev->mt76.cap.has_2ghz = true; 123 dev->mt76.cap.has_5ghz = true; 124 break; 125 } 126 } 127 128 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev) 129 { 130 u8 *eeprom = dev->mt76.eeprom.data; 131 u8 tx_mask; 132 133 mt7615_eeprom_parse_hw_band_cap(dev); 134 135 if (is_mt7663(&dev->mt76)) { 136 tx_mask = 2; 137 } else { 138 u8 max_nss; 139 u32 val; 140 141 /* read tx-rx mask from eeprom */ 142 val = mt76_rr(dev, MT_TOP_STRAP_STA); 143 max_nss = val & MT_TOP_3NSS ? 3 : 4; 144 145 tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK, 146 eeprom[MT_EE_NIC_CONF_0]); 147 if (!tx_mask || tx_mask > max_nss) 148 tx_mask = max_nss; 149 } 150 151 dev->chainmask = BIT(tx_mask) - 1; 152 dev->mphy.antenna_mask = dev->chainmask; 153 dev->phy.chainmask = dev->chainmask; 154 } 155 156 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev, 157 struct ieee80211_channel *chan, 158 u8 chain_idx) 159 { 160 int index; 161 162 if (chain_idx > 3) 163 return -EINVAL; 164 165 /* TSSI disabled */ 166 if (mt7615_ext_pa_enabled(dev, chan->band)) { 167 if (chan->band == NL80211_BAND_2GHZ) 168 return MT_EE_EXT_PA_2G_TARGET_POWER; 169 else 170 return MT_EE_EXT_PA_5G_TARGET_POWER; 171 } 172 173 /* TSSI enabled */ 174 if (chan->band == NL80211_BAND_2GHZ) { 175 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6; 176 } else { 177 int group = mt7615_get_channel_group(chan->hw_value); 178 179 switch (chain_idx) { 180 case 1: 181 index = MT_EE_TX1_5G_G0_TARGET_POWER; 182 break; 183 case 2: 184 index = MT_EE_TX2_5G_G0_TARGET_POWER; 185 break; 186 case 3: 187 index = MT_EE_TX3_5G_G0_TARGET_POWER; 188 break; 189 case 0: 190 default: 191 index = MT_EE_TX0_5G_G0_TARGET_POWER; 192 break; 193 } 194 index += 5 * group; 195 } 196 197 return index; 198 } 199 200 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev) 201 { 202 static const u16 ical[] = { 203 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 204 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87, 205 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0, 206 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4, 207 0xf7, 0xff, 208 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159, 209 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e, 210 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b, 211 0x18c 212 }; 213 static const u16 ical_nocheck[] = { 214 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 215 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1, 216 0x3b2 217 }; 218 u8 *eeprom = dev->mt76.eeprom.data; 219 u8 *otp = dev->mt76.otp.data; 220 int i; 221 222 if (!otp) 223 return; 224 225 for (i = 0; i < ARRAY_SIZE(ical); i++) 226 if (!otp[ical[i]]) 227 return; 228 229 for (i = 0; i < ARRAY_SIZE(ical); i++) 230 eeprom[ical[i]] = otp[ical[i]]; 231 232 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++) 233 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]]; 234 } 235 236 static void mt7622_apply_cal_free_data(struct mt7615_dev *dev) 237 { 238 static const u16 ical[] = { 239 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b 240 }; 241 u8 *eeprom = dev->mt76.eeprom.data; 242 u8 *otp = dev->mt76.otp.data; 243 int i; 244 245 if (!otp) 246 return; 247 248 for (i = 0; i < ARRAY_SIZE(ical); i++) { 249 if (!otp[ical[i]]) 250 continue; 251 252 eeprom[ical[i]] = otp[ical[i]]; 253 } 254 } 255 256 static void mt7615_cal_free_data(struct mt7615_dev *dev) 257 { 258 switch (mt76_chip(&dev->mt76)) { 259 case 0x7622: 260 mt7622_apply_cal_free_data(dev); 261 break; 262 case 0x7615: 263 mt7615_apply_cal_free_data(dev); 264 break; 265 } 266 } 267 268 int mt7615_eeprom_init(struct mt7615_dev *dev) 269 { 270 int ret; 271 272 ret = mt7615_eeprom_load(dev); 273 if (ret < 0) 274 return ret; 275 276 ret = mt7615_check_eeprom(&dev->mt76); 277 if (ret && dev->mt76.otp.data) 278 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data, 279 MT7615_EEPROM_SIZE); 280 else 281 mt7615_cal_free_data(dev); 282 283 mt7615_eeprom_parse_hw_cap(dev); 284 memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, 285 ETH_ALEN); 286 287 mt76_eeprom_override(&dev->mt76); 288 289 return 0; 290 } 291