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 return 0; 88 default: 89 return -EINVAL; 90 } 91 } 92 93 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev) 94 { 95 u8 *eeprom = dev->mt76.eeprom.data; 96 u8 tx_mask, rx_mask, max_nss; 97 u32 val; 98 99 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL, 100 eeprom[MT_EE_WIFI_CONF]); 101 switch (val) { 102 case MT_EE_5GHZ: 103 dev->mt76.cap.has_5ghz = true; 104 break; 105 case MT_EE_2GHZ: 106 dev->mt76.cap.has_2ghz = true; 107 break; 108 default: 109 dev->mt76.cap.has_2ghz = true; 110 dev->mt76.cap.has_5ghz = true; 111 break; 112 } 113 114 /* read tx-rx mask from eeprom */ 115 val = mt76_rr(dev, MT_TOP_STRAP_STA); 116 max_nss = val & MT_TOP_3NSS ? 3 : 4; 117 118 rx_mask = FIELD_GET(MT_EE_NIC_CONF_RX_MASK, 119 eeprom[MT_EE_NIC_CONF_0]); 120 if (!rx_mask || rx_mask > max_nss) 121 rx_mask = max_nss; 122 123 tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK, 124 eeprom[MT_EE_NIC_CONF_0]); 125 if (!tx_mask || tx_mask > max_nss) 126 tx_mask = max_nss; 127 128 dev->mt76.chainmask = tx_mask << 8 | rx_mask; 129 dev->mt76.antenna_mask = BIT(tx_mask) - 1; 130 } 131 132 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev, 133 struct ieee80211_channel *chan, 134 u8 chain_idx) 135 { 136 int index; 137 138 if (chain_idx > 3) 139 return -EINVAL; 140 141 /* TSSI disabled */ 142 if (mt7615_ext_pa_enabled(dev, chan->band)) { 143 if (chan->band == NL80211_BAND_2GHZ) 144 return MT_EE_EXT_PA_2G_TARGET_POWER; 145 else 146 return MT_EE_EXT_PA_5G_TARGET_POWER; 147 } 148 149 /* TSSI enabled */ 150 if (chan->band == NL80211_BAND_2GHZ) { 151 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6; 152 } else { 153 int group = mt7615_get_channel_group(chan->hw_value); 154 155 switch (chain_idx) { 156 case 1: 157 index = MT_EE_TX1_5G_G0_TARGET_POWER; 158 break; 159 case 2: 160 index = MT_EE_TX2_5G_G0_TARGET_POWER; 161 break; 162 case 3: 163 index = MT_EE_TX3_5G_G0_TARGET_POWER; 164 break; 165 case 0: 166 default: 167 index = MT_EE_TX0_5G_G0_TARGET_POWER; 168 break; 169 } 170 index += 5 * group; 171 } 172 173 return index; 174 } 175 176 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev) 177 { 178 static const u16 ical[] = { 179 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68, 180 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87, 181 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0, 182 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4, 183 0xf7, 0xff, 184 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159, 185 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e, 186 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b, 187 0x18c 188 }; 189 static const u16 ical_nocheck[] = { 190 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 191 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1, 192 0x3b2 193 }; 194 u8 *eeprom = dev->mt76.eeprom.data; 195 u8 *otp = dev->mt76.otp.data; 196 int i; 197 198 if (!otp) 199 return; 200 201 for (i = 0; i < ARRAY_SIZE(ical); i++) 202 if (!otp[ical[i]]) 203 return; 204 205 for (i = 0; i < ARRAY_SIZE(ical); i++) 206 eeprom[ical[i]] = otp[ical[i]]; 207 208 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++) 209 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]]; 210 } 211 212 int mt7615_eeprom_init(struct mt7615_dev *dev) 213 { 214 int ret; 215 216 ret = mt7615_eeprom_load(dev); 217 if (ret < 0) 218 return ret; 219 220 ret = mt7615_check_eeprom(&dev->mt76); 221 if (ret && dev->mt76.otp.data) 222 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data, 223 MT7615_EEPROM_SIZE); 224 else 225 mt7615_apply_cal_free_data(dev); 226 227 mt7615_eeprom_parse_hw_cap(dev); 228 memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, 229 ETH_ALEN); 230 231 mt76_eeprom_override(&dev->mt76); 232 233 return 0; 234 } 235