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