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;
96 u8 tx_mask, rx_mask, max_nss;
98 val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
99 eeprom[MT_EE_WIFI_CONF]);
102 dev->mt76.cap.has_5ghz = true;
105 dev->mt76.cap.has_2ghz = true;
108 dev->mt76.cap.has_2ghz = true;
109 dev->mt76.cap.has_5ghz = true;
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;
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)
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)
127 dev->mt76.chainmask = tx_mask << 8 | rx_mask;
128 dev->mt76.antenna_mask = BIT(tx_mask) - 1;
131 int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
132 struct ieee80211_channel *chan,
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;
145 return MT_EE_EXT_PA_5G_TARGET_POWER;
149 if (chan->band == NL80211_BAND_2GHZ) {
150 index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
152 int group = mt7615_get_channel_group(chan->hw_value);
156 index = MT_EE_TX1_5G_G0_TARGET_POWER;
159 index = MT_EE_TX2_5G_G0_TARGET_POWER;
162 index = MT_EE_TX3_5G_G0_TARGET_POWER;
166 index = MT_EE_TX0_5G_G0_TARGET_POWER;
175 static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
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,
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,
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,
193 u8 *eeprom = dev->mt76.eeprom.data;
194 u8 *otp = dev->mt76.otp.data;
200 for (i = 0; i < ARRAY_SIZE(ical); i++)
204 for (i = 0; i < ARRAY_SIZE(ical); i++)
205 eeprom[ical[i]] = otp[ical[i]];
207 for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
208 eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
211 int mt7615_eeprom_init(struct mt7615_dev *dev)
215 ret = mt7615_eeprom_load(dev);
219 ret = mt7615_check_eeprom(&dev->mt76);
220 if (ret && dev->mt76.otp.data)
221 memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
224 mt7615_apply_cal_free_data(dev);
226 mt7615_eeprom_parse_hw_cap(dev);
227 memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
230 mt76_eeprom_override(&dev->mt76);