104b8e659SRyder Lee // SPDX-License-Identifier: ISC
204b8e659SRyder Lee /* Copyright (C) 2019 MediaTek Inc.
304b8e659SRyder Lee *
404b8e659SRyder Lee * Author: Ryder Lee <ryder.lee@mediatek.com>
504b8e659SRyder Lee * Felix Fietkau <nbd@nbd.name>
604b8e659SRyder Lee */
704b8e659SRyder Lee
8b90728f8SFelix Fietkau #include <linux/of.h>
904b8e659SRyder Lee #include "mt7615.h"
1004b8e659SRyder Lee #include "eeprom.h"
1104b8e659SRyder Lee
mt7615_efuse_read(struct mt7615_dev * dev,u32 base,u16 addr,u8 * data)1204b8e659SRyder Lee static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
1304b8e659SRyder Lee u16 addr, u8 *data)
1404b8e659SRyder Lee {
1504b8e659SRyder Lee u32 val;
1604b8e659SRyder Lee int i;
1704b8e659SRyder Lee
1804b8e659SRyder Lee val = mt76_rr(dev, base + MT_EFUSE_CTRL);
1904b8e659SRyder Lee val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE);
2004b8e659SRyder Lee val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
2104b8e659SRyder Lee val |= MT_EFUSE_CTRL_KICK;
2204b8e659SRyder Lee mt76_wr(dev, base + MT_EFUSE_CTRL, val);
2304b8e659SRyder Lee
2404b8e659SRyder Lee if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
2504b8e659SRyder Lee return -ETIMEDOUT;
2604b8e659SRyder Lee
2704b8e659SRyder Lee udelay(2);
2804b8e659SRyder Lee
2904b8e659SRyder Lee val = mt76_rr(dev, base + MT_EFUSE_CTRL);
3004b8e659SRyder Lee if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
3104b8e659SRyder Lee WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
3204b8e659SRyder Lee memset(data, 0x0, 16);
3304b8e659SRyder Lee return 0;
3404b8e659SRyder Lee }
3504b8e659SRyder Lee
3604b8e659SRyder Lee for (i = 0; i < 4; i++) {
3704b8e659SRyder Lee val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
3804b8e659SRyder Lee put_unaligned_le32(val, data + 4 * i);
3904b8e659SRyder Lee }
4004b8e659SRyder Lee
4104b8e659SRyder Lee return 0;
4204b8e659SRyder Lee }
4304b8e659SRyder Lee
mt7615_efuse_init(struct mt7615_dev * dev,u32 base)446e5d2099SLorenzo Bianconi static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)
4504b8e659SRyder Lee {
46f9461a68SLorenzo Bianconi int i, len = MT7615_EEPROM_SIZE;
4704b8e659SRyder Lee void *buf;
486e5d2099SLorenzo Bianconi u32 val;
4904b8e659SRyder Lee
50e12b2e99SFelix Fietkau if (is_mt7663(&dev->mt76))
51e12b2e99SFelix Fietkau len = MT7663_EEPROM_SIZE;
52e12b2e99SFelix Fietkau
53f9461a68SLorenzo Bianconi val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
54f9461a68SLorenzo Bianconi if (val & MT_EFUSE_BASE_CTRL_EMPTY)
55f9461a68SLorenzo Bianconi return 0;
5604b8e659SRyder Lee
5704b8e659SRyder Lee dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
5804b8e659SRyder Lee dev->mt76.otp.size = len;
5904b8e659SRyder Lee if (!dev->mt76.otp.data)
6004b8e659SRyder Lee return -ENOMEM;
6104b8e659SRyder Lee
6204b8e659SRyder Lee buf = dev->mt76.otp.data;
6304b8e659SRyder Lee for (i = 0; i + 16 <= len; i += 16) {
64f9461a68SLorenzo Bianconi int ret;
65f9461a68SLorenzo Bianconi
6604b8e659SRyder Lee ret = mt7615_efuse_read(dev, base, i, buf + i);
6704b8e659SRyder Lee if (ret)
6804b8e659SRyder Lee return ret;
6904b8e659SRyder Lee }
7004b8e659SRyder Lee
7104b8e659SRyder Lee return 0;
7204b8e659SRyder Lee }
7304b8e659SRyder Lee
mt7615_eeprom_load(struct mt7615_dev * dev,u32 addr)746e5d2099SLorenzo Bianconi static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
7504b8e659SRyder Lee {
7604b8e659SRyder Lee int ret;
7704b8e659SRyder Lee
78e12b2e99SFelix Fietkau BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE < MT7663_EEPROM_SIZE);
79e12b2e99SFelix Fietkau
80dc7bd30bSFelix Fietkau ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE);
8104b8e659SRyder Lee if (ret < 0)
8204b8e659SRyder Lee return ret;
8304b8e659SRyder Lee
846e5d2099SLorenzo Bianconi return mt7615_efuse_init(dev, addr);
8504b8e659SRyder Lee }
8604b8e659SRyder Lee
mt7615_check_eeprom(struct mt76_dev * dev)87f9461a68SLorenzo Bianconi static int mt7615_check_eeprom(struct mt76_dev *dev)
88f9461a68SLorenzo Bianconi {
89f9461a68SLorenzo Bianconi u16 val = get_unaligned_le16(dev->eeprom.data);
90f9461a68SLorenzo Bianconi
91f9461a68SLorenzo Bianconi switch (val) {
92f9461a68SLorenzo Bianconi case 0x7615:
935dff21eeSFelix Fietkau case 0x7622:
94858ebf44SSander Vanheule case 0x7663:
95f9461a68SLorenzo Bianconi return 0;
96f9461a68SLorenzo Bianconi default:
97f9461a68SLorenzo Bianconi return -EINVAL;
98f9461a68SLorenzo Bianconi }
99f9461a68SLorenzo Bianconi }
100f9461a68SLorenzo Bianconi
101b3d95f09SLorenzo Bianconi static void
mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev * dev)102b3d95f09SLorenzo Bianconi mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
103c988a77fSLorenzo Bianconi {
104b3d95f09SLorenzo Bianconi u8 val, *eeprom = dev->mt76.eeprom.data;
105b3d95f09SLorenzo Bianconi
106b3d95f09SLorenzo Bianconi if (is_mt7663(&dev->mt76)) {
107b3d95f09SLorenzo Bianconi /* dual band */
10848dbce5cSLorenzo Bianconi dev->mphy.cap.has_2ghz = true;
10948dbce5cSLorenzo Bianconi dev->mphy.cap.has_5ghz = true;
110b3d95f09SLorenzo Bianconi return;
111b3d95f09SLorenzo Bianconi }
112b3d95f09SLorenzo Bianconi
113b3d95f09SLorenzo Bianconi if (is_mt7622(&dev->mt76)) {
114b3d95f09SLorenzo Bianconi /* 2GHz only */
11548dbce5cSLorenzo Bianconi dev->mphy.cap.has_2ghz = true;
116b3d95f09SLorenzo Bianconi return;
117b3d95f09SLorenzo Bianconi }
118c988a77fSLorenzo Bianconi
119e47f2245SDENG Qingfang if (is_mt7611(&dev->mt76)) {
120e47f2245SDENG Qingfang /* 5GHz only */
12148dbce5cSLorenzo Bianconi dev->mphy.cap.has_5ghz = true;
122e47f2245SDENG Qingfang return;
123e47f2245SDENG Qingfang }
124e47f2245SDENG Qingfang
125c988a77fSLorenzo Bianconi val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
126c988a77fSLorenzo Bianconi eeprom[MT_EE_WIFI_CONF]);
127c988a77fSLorenzo Bianconi switch (val) {
128c988a77fSLorenzo Bianconi case MT_EE_5GHZ:
12948dbce5cSLorenzo Bianconi dev->mphy.cap.has_5ghz = true;
130c988a77fSLorenzo Bianconi break;
1317660a1bdSShayne Chen case MT_EE_DBDC:
1327660a1bdSShayne Chen dev->dbdc_support = true;
133f12758f6SGustavo A. R. Silva fallthrough;
134421033deSPaul Fertser case MT_EE_2GHZ:
135421033deSPaul Fertser dev->mphy.cap.has_2ghz = true;
136421033deSPaul Fertser break;
137c988a77fSLorenzo Bianconi default:
13848dbce5cSLorenzo Bianconi dev->mphy.cap.has_2ghz = true;
13948dbce5cSLorenzo Bianconi dev->mphy.cap.has_5ghz = true;
140c988a77fSLorenzo Bianconi break;
141c988a77fSLorenzo Bianconi }
142b3d95f09SLorenzo Bianconi }
143acf5457fSLorenzo Bianconi
mt7615_eeprom_parse_hw_cap(struct mt7615_dev * dev)144b3d95f09SLorenzo Bianconi static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
145b3d95f09SLorenzo Bianconi {
146b3d95f09SLorenzo Bianconi u8 *eeprom = dev->mt76.eeprom.data;
147eb7bd8d7SLorenzo Bianconi u8 tx_mask, max_nss;
148b3d95f09SLorenzo Bianconi
149b3d95f09SLorenzo Bianconi mt7615_eeprom_parse_hw_band_cap(dev);
150c3ad5e9dSFelix Fietkau
151f40ac0f3SLorenzo Bianconi if (is_mt7663(&dev->mt76)) {
152eb7bd8d7SLorenzo Bianconi max_nss = 2;
153eb7bd8d7SLorenzo Bianconi tx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK,
154eb7bd8d7SLorenzo Bianconi eeprom[MT7663_EE_HW_CONF1]);
155f40ac0f3SLorenzo Bianconi } else {
156f40ac0f3SLorenzo Bianconi u32 val;
157f40ac0f3SLorenzo Bianconi
158acf5457fSLorenzo Bianconi /* read tx-rx mask from eeprom */
159acf5457fSLorenzo Bianconi val = mt76_rr(dev, MT_TOP_STRAP_STA);
160acf5457fSLorenzo Bianconi max_nss = val & MT_TOP_3NSS ? 3 : 4;
161acf5457fSLorenzo Bianconi
162acf5457fSLorenzo Bianconi tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK,
163acf5457fSLorenzo Bianconi eeprom[MT_EE_NIC_CONF_0]);
164eb7bd8d7SLorenzo Bianconi }
165acf5457fSLorenzo Bianconi if (!tx_mask || tx_mask > max_nss)
166acf5457fSLorenzo Bianconi tx_mask = max_nss;
167acf5457fSLorenzo Bianconi
1680f2173f0SFelix Fietkau dev->chainmask = BIT(tx_mask) - 1;
1690f2173f0SFelix Fietkau dev->mphy.antenna_mask = dev->chainmask;
170b9027e08SLorenzo Bianconi dev->mphy.chainmask = dev->chainmask;
171c988a77fSLorenzo Bianconi }
172c988a77fSLorenzo Bianconi
mt7663_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)173e0ec633dSLorenzo Bianconi static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,
174e0ec633dSLorenzo Bianconi struct ieee80211_channel *chan,
175e0ec633dSLorenzo Bianconi u8 chain_idx)
176e0ec633dSLorenzo Bianconi {
177e0ec633dSLorenzo Bianconi int index, group;
178e0ec633dSLorenzo Bianconi
179e0ec633dSLorenzo Bianconi if (chain_idx > 1)
180e0ec633dSLorenzo Bianconi return -EINVAL;
181e0ec633dSLorenzo Bianconi
182e0ec633dSLorenzo Bianconi if (chan->band == NL80211_BAND_2GHZ)
183e0ec633dSLorenzo Bianconi return MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx << 4);
184e0ec633dSLorenzo Bianconi
185e0ec633dSLorenzo Bianconi group = mt7615_get_channel_group(chan->hw_value);
186e0ec633dSLorenzo Bianconi if (chain_idx == 1)
187e0ec633dSLorenzo Bianconi index = MT7663_EE_TX1_5G_G0_TARGET_POWER;
188e0ec633dSLorenzo Bianconi else
189e0ec633dSLorenzo Bianconi index = MT7663_EE_TX0_5G_G0_TARGET_POWER;
190e0ec633dSLorenzo Bianconi
191e0ec633dSLorenzo Bianconi return index + group * 3;
192e0ec633dSLorenzo Bianconi }
193e0ec633dSLorenzo Bianconi
mt7615_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)194e0ec633dSLorenzo Bianconi int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,
19516a2f8e2SLorenzo Bianconi struct ieee80211_channel *chan,
19661d36824SLorenzo Bianconi u8 chain_idx)
19761d36824SLorenzo Bianconi {
19861d36824SLorenzo Bianconi int index;
19961d36824SLorenzo Bianconi
200e0ec633dSLorenzo Bianconi if (is_mt7663(&dev->mt76))
201e0ec633dSLorenzo Bianconi return mt7663_eeprom_get_target_power_index(dev, chan,
202e0ec633dSLorenzo Bianconi chain_idx);
203e0ec633dSLorenzo Bianconi
20461d36824SLorenzo Bianconi if (chain_idx > 3)
20561d36824SLorenzo Bianconi return -EINVAL;
20661d36824SLorenzo Bianconi
20716a2f8e2SLorenzo Bianconi /* TSSI disabled */
20816a2f8e2SLorenzo Bianconi if (mt7615_ext_pa_enabled(dev, chan->band)) {
20916a2f8e2SLorenzo Bianconi if (chan->band == NL80211_BAND_2GHZ)
21016a2f8e2SLorenzo Bianconi return MT_EE_EXT_PA_2G_TARGET_POWER;
21116a2f8e2SLorenzo Bianconi else
21216a2f8e2SLorenzo Bianconi return MT_EE_EXT_PA_5G_TARGET_POWER;
21316a2f8e2SLorenzo Bianconi }
21416a2f8e2SLorenzo Bianconi
21516a2f8e2SLorenzo Bianconi /* TSSI enabled */
21661d36824SLorenzo Bianconi if (chan->band == NL80211_BAND_2GHZ) {
21761d36824SLorenzo Bianconi index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
21861d36824SLorenzo Bianconi } else {
21961d36824SLorenzo Bianconi int group = mt7615_get_channel_group(chan->hw_value);
22061d36824SLorenzo Bianconi
22161d36824SLorenzo Bianconi switch (chain_idx) {
22261d36824SLorenzo Bianconi case 1:
22361d36824SLorenzo Bianconi index = MT_EE_TX1_5G_G0_TARGET_POWER;
22461d36824SLorenzo Bianconi break;
22561d36824SLorenzo Bianconi case 2:
22661d36824SLorenzo Bianconi index = MT_EE_TX2_5G_G0_TARGET_POWER;
22761d36824SLorenzo Bianconi break;
22861d36824SLorenzo Bianconi case 3:
22961d36824SLorenzo Bianconi index = MT_EE_TX3_5G_G0_TARGET_POWER;
23061d36824SLorenzo Bianconi break;
23161d36824SLorenzo Bianconi case 0:
23261d36824SLorenzo Bianconi default:
23361d36824SLorenzo Bianconi index = MT_EE_TX0_5G_G0_TARGET_POWER;
23461d36824SLorenzo Bianconi break;
23561d36824SLorenzo Bianconi }
23661d36824SLorenzo Bianconi index += 5 * group;
23761d36824SLorenzo Bianconi }
23861d36824SLorenzo Bianconi
23961d36824SLorenzo Bianconi return index;
24061d36824SLorenzo Bianconi }
24161d36824SLorenzo Bianconi
mt7615_eeprom_get_power_delta_index(struct mt7615_dev * dev,enum nl80211_band band)242c88bf52bSLorenzo Bianconi int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev,
243c88bf52bSLorenzo Bianconi enum nl80211_band band)
244c88bf52bSLorenzo Bianconi {
245c88bf52bSLorenzo Bianconi /* assume the first rate has the highest power offset */
246c88bf52bSLorenzo Bianconi if (is_mt7663(&dev->mt76)) {
247c88bf52bSLorenzo Bianconi if (band == NL80211_BAND_2GHZ)
248c88bf52bSLorenzo Bianconi return MT_EE_TX0_5G_G0_TARGET_POWER;
249c88bf52bSLorenzo Bianconi else
250c88bf52bSLorenzo Bianconi return MT7663_EE_5G_RATE_POWER;
251c88bf52bSLorenzo Bianconi }
252c88bf52bSLorenzo Bianconi
253c88bf52bSLorenzo Bianconi if (band == NL80211_BAND_2GHZ)
254c88bf52bSLorenzo Bianconi return MT_EE_2G_RATE_POWER;
255c88bf52bSLorenzo Bianconi else
256c88bf52bSLorenzo Bianconi return MT_EE_5G_RATE_POWER;
257c88bf52bSLorenzo Bianconi }
258c88bf52bSLorenzo Bianconi
mt7615_apply_cal_free_data(struct mt7615_dev * dev)25955bbbefdSFelix Fietkau static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
26055bbbefdSFelix Fietkau {
26155bbbefdSFelix Fietkau static const u16 ical[] = {
26255bbbefdSFelix Fietkau 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
26355bbbefdSFelix Fietkau 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
26455bbbefdSFelix Fietkau 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
26555bbbefdSFelix Fietkau 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
26655bbbefdSFelix Fietkau 0xf7, 0xff,
26755bbbefdSFelix Fietkau 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
26855bbbefdSFelix Fietkau 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
26955bbbefdSFelix Fietkau 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
27055bbbefdSFelix Fietkau 0x18c
27155bbbefdSFelix Fietkau };
27255bbbefdSFelix Fietkau static const u16 ical_nocheck[] = {
27355bbbefdSFelix Fietkau 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
27455bbbefdSFelix Fietkau 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
27555bbbefdSFelix Fietkau 0x3b2
27655bbbefdSFelix Fietkau };
27755bbbefdSFelix Fietkau u8 *eeprom = dev->mt76.eeprom.data;
27855bbbefdSFelix Fietkau u8 *otp = dev->mt76.otp.data;
27955bbbefdSFelix Fietkau int i;
28055bbbefdSFelix Fietkau
28155bbbefdSFelix Fietkau if (!otp)
28255bbbefdSFelix Fietkau return;
28355bbbefdSFelix Fietkau
28455bbbefdSFelix Fietkau for (i = 0; i < ARRAY_SIZE(ical); i++)
28555bbbefdSFelix Fietkau if (!otp[ical[i]])
28655bbbefdSFelix Fietkau return;
28755bbbefdSFelix Fietkau
28855bbbefdSFelix Fietkau for (i = 0; i < ARRAY_SIZE(ical); i++)
28955bbbefdSFelix Fietkau eeprom[ical[i]] = otp[ical[i]];
29055bbbefdSFelix Fietkau
29155bbbefdSFelix Fietkau for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
29255bbbefdSFelix Fietkau eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
29355bbbefdSFelix Fietkau }
29455bbbefdSFelix Fietkau
mt7622_apply_cal_free_data(struct mt7615_dev * dev)2958acb7afcSFelix Fietkau static void mt7622_apply_cal_free_data(struct mt7615_dev *dev)
2968acb7afcSFelix Fietkau {
2978acb7afcSFelix Fietkau static const u16 ical[] = {
2988acb7afcSFelix Fietkau 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b
2998acb7afcSFelix Fietkau };
3008acb7afcSFelix Fietkau u8 *eeprom = dev->mt76.eeprom.data;
3018acb7afcSFelix Fietkau u8 *otp = dev->mt76.otp.data;
3028acb7afcSFelix Fietkau int i;
3038acb7afcSFelix Fietkau
3048acb7afcSFelix Fietkau if (!otp)
3058acb7afcSFelix Fietkau return;
3068acb7afcSFelix Fietkau
3078acb7afcSFelix Fietkau for (i = 0; i < ARRAY_SIZE(ical); i++) {
3088acb7afcSFelix Fietkau if (!otp[ical[i]])
3098acb7afcSFelix Fietkau continue;
3108acb7afcSFelix Fietkau
3118acb7afcSFelix Fietkau eeprom[ical[i]] = otp[ical[i]];
3128acb7afcSFelix Fietkau }
3138acb7afcSFelix Fietkau }
3148acb7afcSFelix Fietkau
mt7615_cal_free_data(struct mt7615_dev * dev)315f40ac0f3SLorenzo Bianconi static void mt7615_cal_free_data(struct mt7615_dev *dev)
316f40ac0f3SLorenzo Bianconi {
317b90728f8SFelix Fietkau struct device_node *np = dev->mt76.dev->of_node;
318b90728f8SFelix Fietkau
319b90728f8SFelix Fietkau if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
320b90728f8SFelix Fietkau return;
321b90728f8SFelix Fietkau
322f40ac0f3SLorenzo Bianconi switch (mt76_chip(&dev->mt76)) {
323f40ac0f3SLorenzo Bianconi case 0x7622:
324f40ac0f3SLorenzo Bianconi mt7622_apply_cal_free_data(dev);
325f40ac0f3SLorenzo Bianconi break;
326f40ac0f3SLorenzo Bianconi case 0x7615:
327e47f2245SDENG Qingfang case 0x7611:
328f40ac0f3SLorenzo Bianconi mt7615_apply_cal_free_data(dev);
329f40ac0f3SLorenzo Bianconi break;
330f40ac0f3SLorenzo Bianconi }
331f40ac0f3SLorenzo Bianconi }
332f40ac0f3SLorenzo Bianconi
mt7615_eeprom_init(struct mt7615_dev * dev,u32 addr)3336e5d2099SLorenzo Bianconi int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
33404b8e659SRyder Lee {
33504b8e659SRyder Lee int ret;
33604b8e659SRyder Lee
3376e5d2099SLorenzo Bianconi ret = mt7615_eeprom_load(dev, addr);
33804b8e659SRyder Lee if (ret < 0)
33904b8e659SRyder Lee return ret;
34004b8e659SRyder Lee
341f9461a68SLorenzo Bianconi ret = mt7615_check_eeprom(&dev->mt76);
342ad380ad1SFelix Fietkau if (ret && dev->mt76.otp.data) {
343f9461a68SLorenzo Bianconi memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
344e12b2e99SFelix Fietkau dev->mt76.otp.size);
345ad380ad1SFelix Fietkau } else {
346ad380ad1SFelix Fietkau dev->flash_eeprom = true;
347f40ac0f3SLorenzo Bianconi mt7615_cal_free_data(dev);
348ad380ad1SFelix Fietkau }
34904b8e659SRyder Lee
350c988a77fSLorenzo Bianconi mt7615_eeprom_parse_hw_cap(dev);
35198df2baeSLorenzo Bianconi memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
35204b8e659SRyder Lee ETH_ALEN);
35304b8e659SRyder Lee
35498df2baeSLorenzo Bianconi mt76_eeprom_override(&dev->mphy);
35504b8e659SRyder Lee
35604b8e659SRyder Lee return 0;
35704b8e659SRyder Lee }
358e90354e0SLorenzo Bianconi EXPORT_SYMBOL_GPL(mt7615_eeprom_init);
359