1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 * Felix Fietkau <nbd@nbd.name>
11 static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
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);
23 if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
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);
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);
43 static int mt7615_efuse_init(struct mt7615_dev *dev)
45 u32 val, base = mt7615_reg_map(dev, MT_EFUSE_BASE);
46 int i, len = MT7615_EEPROM_SIZE;
49 val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
50 if (val & MT_EFUSE_BASE_CTRL_EMPTY)
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)
58 buf = dev->mt76.otp.data;
59 for (i = 0; i + 16 <= len; i += 16) {
62 ret = mt7615_efuse_read(dev, base, i, buf + i);
70 static int mt7615_eeprom_load(struct mt7615_dev *dev)
74 ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE);
78 return mt7615_efuse_init(dev);
81 static int mt7615_check_eeprom(struct mt76_dev *dev)
83 u16 val = get_unaligned_le16(dev->eeprom.data);
93 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
95 u8 val, *eeprom = dev->mt76.eeprom.data;
97 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
98 eeprom[MT_EE_WIFI_CONF]);
101 dev->mt76.cap.has_5ghz = true;
104 dev->mt76.cap.has_2ghz = true;
107 dev->mt76.cap.has_2ghz = true;
108 dev->mt76.cap.has_5ghz = true;
113 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
114 struct ieee80211_channel *chan,
123 if (mt7615_ext_pa_enabled(dev, chan->band)) {
124 if (chan->band == NL80211_BAND_2GHZ)
125 return MT_EE_EXT_PA_2G_TARGET_POWER;
127 return MT_EE_EXT_PA_5G_TARGET_POWER;
131 if (chan->band == NL80211_BAND_2GHZ) {
132 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
134 int group = mt7615_get_channel_group(chan->hw_value);
138 index = MT_EE_TX1_5G_G0_TARGET_POWER;
141 index = MT_EE_TX2_5G_G0_TARGET_POWER;
144 index = MT_EE_TX3_5G_G0_TARGET_POWER;
148 index = MT_EE_TX0_5G_G0_TARGET_POWER;
157 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
159 static const u16 ical[] = {
160 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
161 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
162 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
163 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
165 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
166 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
167 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
170 static const u16 ical_nocheck[] = {
171 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
172 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
175 u8 *eeprom = dev->mt76.eeprom.data;
176 u8 *otp = dev->mt76.otp.data;
182 for (i = 0; i < ARRAY_SIZE(ical); i++)
186 for (i = 0; i < ARRAY_SIZE(ical); i++)
187 eeprom[ical[i]] = otp[ical[i]];
189 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
190 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
193 int mt7615_eeprom_init(struct mt7615_dev *dev)
197 ret = mt7615_eeprom_load(dev);
201 ret = mt7615_check_eeprom(&dev->mt76);
202 if (ret && dev->mt76.otp.data)
203 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
206 mt7615_apply_cal_free_data(dev);
208 mt7615_eeprom_parse_hw_cap(dev);
209 memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
212 mt76_eeprom_override(&dev->mt76);