16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC
26c92544dSBjoern A. Zeeb /* Copyright (C) 2019 MediaTek Inc.
36c92544dSBjoern A. Zeeb *
46c92544dSBjoern A. Zeeb * Author: Ryder Lee <ryder.lee@mediatek.com>
56c92544dSBjoern A. Zeeb * Felix Fietkau <nbd@nbd.name>
66c92544dSBjoern A. Zeeb */
76c92544dSBjoern A. Zeeb
86c92544dSBjoern A. Zeeb #include <linux/of.h>
9*77285868SBjoern A. Zeeb #if defined(__FreeBSD__)
10*77285868SBjoern A. Zeeb #include <linux/delay.h>
11*77285868SBjoern A. Zeeb #endif
126c92544dSBjoern A. Zeeb #include "mt7615.h"
136c92544dSBjoern A. Zeeb #include "eeprom.h"
146c92544dSBjoern A. Zeeb
mt7615_efuse_read(struct mt7615_dev * dev,u32 base,u16 addr,u8 * data)156c92544dSBjoern A. Zeeb static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
166c92544dSBjoern A. Zeeb u16 addr, u8 *data)
176c92544dSBjoern A. Zeeb {
186c92544dSBjoern A. Zeeb u32 val;
196c92544dSBjoern A. Zeeb int i;
206c92544dSBjoern A. Zeeb
216c92544dSBjoern A. Zeeb val = mt76_rr(dev, base + MT_EFUSE_CTRL);
226c92544dSBjoern A. Zeeb val &= ~(MT_EFUSE_CTRL_AIN | MT_EFUSE_CTRL_MODE);
236c92544dSBjoern A. Zeeb val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
246c92544dSBjoern A. Zeeb val |= MT_EFUSE_CTRL_KICK;
256c92544dSBjoern A. Zeeb mt76_wr(dev, base + MT_EFUSE_CTRL, val);
266c92544dSBjoern A. Zeeb
276c92544dSBjoern A. Zeeb if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
286c92544dSBjoern A. Zeeb return -ETIMEDOUT;
296c92544dSBjoern A. Zeeb
306c92544dSBjoern A. Zeeb udelay(2);
316c92544dSBjoern A. Zeeb
326c92544dSBjoern A. Zeeb val = mt76_rr(dev, base + MT_EFUSE_CTRL);
336c92544dSBjoern A. Zeeb if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
346c92544dSBjoern A. Zeeb WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
356c92544dSBjoern A. Zeeb memset(data, 0x0, 16);
366c92544dSBjoern A. Zeeb return 0;
376c92544dSBjoern A. Zeeb }
386c92544dSBjoern A. Zeeb
396c92544dSBjoern A. Zeeb for (i = 0; i < 4; i++) {
406c92544dSBjoern A. Zeeb val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
416c92544dSBjoern A. Zeeb put_unaligned_le32(val, data + 4 * i);
426c92544dSBjoern A. Zeeb }
436c92544dSBjoern A. Zeeb
446c92544dSBjoern A. Zeeb return 0;
456c92544dSBjoern A. Zeeb }
466c92544dSBjoern A. Zeeb
mt7615_efuse_init(struct mt7615_dev * dev,u32 base)476c92544dSBjoern A. Zeeb static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)
486c92544dSBjoern A. Zeeb {
496c92544dSBjoern A. Zeeb int i, len = MT7615_EEPROM_SIZE;
506c92544dSBjoern A. Zeeb void *buf;
516c92544dSBjoern A. Zeeb u32 val;
526c92544dSBjoern A. Zeeb
53cbb3ec25SBjoern A. Zeeb if (is_mt7663(&dev->mt76))
54cbb3ec25SBjoern A. Zeeb len = MT7663_EEPROM_SIZE;
55cbb3ec25SBjoern A. Zeeb
566c92544dSBjoern A. Zeeb val = mt76_rr(dev, base + MT_EFUSE_BASE_CTRL);
576c92544dSBjoern A. Zeeb if (val & MT_EFUSE_BASE_CTRL_EMPTY)
586c92544dSBjoern A. Zeeb return 0;
596c92544dSBjoern A. Zeeb
606c92544dSBjoern A. Zeeb dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
616c92544dSBjoern A. Zeeb dev->mt76.otp.size = len;
626c92544dSBjoern A. Zeeb if (!dev->mt76.otp.data)
636c92544dSBjoern A. Zeeb return -ENOMEM;
646c92544dSBjoern A. Zeeb
656c92544dSBjoern A. Zeeb buf = dev->mt76.otp.data;
666c92544dSBjoern A. Zeeb for (i = 0; i + 16 <= len; i += 16) {
676c92544dSBjoern A. Zeeb int ret;
686c92544dSBjoern A. Zeeb
69*77285868SBjoern A. Zeeb #if defined(__linux__)
706c92544dSBjoern A. Zeeb ret = mt7615_efuse_read(dev, base, i, buf + i);
71*77285868SBjoern A. Zeeb #elif defined(__FreeBSD__)
72*77285868SBjoern A. Zeeb ret = mt7615_efuse_read(dev, base, i, (u8 *)buf + i);
73*77285868SBjoern A. Zeeb #endif
746c92544dSBjoern A. Zeeb if (ret)
756c92544dSBjoern A. Zeeb return ret;
766c92544dSBjoern A. Zeeb }
776c92544dSBjoern A. Zeeb
786c92544dSBjoern A. Zeeb return 0;
796c92544dSBjoern A. Zeeb }
806c92544dSBjoern A. Zeeb
mt7615_eeprom_load(struct mt7615_dev * dev,u32 addr)816c92544dSBjoern A. Zeeb static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
826c92544dSBjoern A. Zeeb {
836c92544dSBjoern A. Zeeb int ret;
846c92544dSBjoern A. Zeeb
85cbb3ec25SBjoern A. Zeeb BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE < MT7663_EEPROM_SIZE);
86cbb3ec25SBjoern A. Zeeb
876c92544dSBjoern A. Zeeb ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE);
886c92544dSBjoern A. Zeeb if (ret < 0)
896c92544dSBjoern A. Zeeb return ret;
906c92544dSBjoern A. Zeeb
916c92544dSBjoern A. Zeeb return mt7615_efuse_init(dev, addr);
926c92544dSBjoern A. Zeeb }
936c92544dSBjoern A. Zeeb
mt7615_check_eeprom(struct mt76_dev * dev)946c92544dSBjoern A. Zeeb static int mt7615_check_eeprom(struct mt76_dev *dev)
956c92544dSBjoern A. Zeeb {
966c92544dSBjoern A. Zeeb u16 val = get_unaligned_le16(dev->eeprom.data);
976c92544dSBjoern A. Zeeb
986c92544dSBjoern A. Zeeb switch (val) {
996c92544dSBjoern A. Zeeb case 0x7615:
1006c92544dSBjoern A. Zeeb case 0x7622:
1016c92544dSBjoern A. Zeeb case 0x7663:
1026c92544dSBjoern A. Zeeb return 0;
1036c92544dSBjoern A. Zeeb default:
1046c92544dSBjoern A. Zeeb return -EINVAL;
1056c92544dSBjoern A. Zeeb }
1066c92544dSBjoern A. Zeeb }
1076c92544dSBjoern A. Zeeb
1086c92544dSBjoern A. Zeeb static void
mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev * dev)1096c92544dSBjoern A. Zeeb mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
1106c92544dSBjoern A. Zeeb {
1116c92544dSBjoern A. Zeeb u8 val, *eeprom = dev->mt76.eeprom.data;
1126c92544dSBjoern A. Zeeb
1136c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76)) {
1146c92544dSBjoern A. Zeeb /* dual band */
1156c92544dSBjoern A. Zeeb dev->mphy.cap.has_2ghz = true;
1166c92544dSBjoern A. Zeeb dev->mphy.cap.has_5ghz = true;
1176c92544dSBjoern A. Zeeb return;
1186c92544dSBjoern A. Zeeb }
1196c92544dSBjoern A. Zeeb
1206c92544dSBjoern A. Zeeb if (is_mt7622(&dev->mt76)) {
1216c92544dSBjoern A. Zeeb /* 2GHz only */
1226c92544dSBjoern A. Zeeb dev->mphy.cap.has_2ghz = true;
1236c92544dSBjoern A. Zeeb return;
1246c92544dSBjoern A. Zeeb }
1256c92544dSBjoern A. Zeeb
1266c92544dSBjoern A. Zeeb if (is_mt7611(&dev->mt76)) {
1276c92544dSBjoern A. Zeeb /* 5GHz only */
1286c92544dSBjoern A. Zeeb dev->mphy.cap.has_5ghz = true;
1296c92544dSBjoern A. Zeeb return;
1306c92544dSBjoern A. Zeeb }
1316c92544dSBjoern A. Zeeb
1326c92544dSBjoern A. Zeeb val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
1336c92544dSBjoern A. Zeeb eeprom[MT_EE_WIFI_CONF]);
1346c92544dSBjoern A. Zeeb switch (val) {
1356c92544dSBjoern A. Zeeb case MT_EE_5GHZ:
1366c92544dSBjoern A. Zeeb dev->mphy.cap.has_5ghz = true;
1376c92544dSBjoern A. Zeeb break;
1386c92544dSBjoern A. Zeeb case MT_EE_DBDC:
1396c92544dSBjoern A. Zeeb dev->dbdc_support = true;
1406c92544dSBjoern A. Zeeb fallthrough;
141cbb3ec25SBjoern A. Zeeb case MT_EE_2GHZ:
142cbb3ec25SBjoern A. Zeeb dev->mphy.cap.has_2ghz = true;
143cbb3ec25SBjoern A. Zeeb break;
1446c92544dSBjoern A. Zeeb default:
1456c92544dSBjoern A. Zeeb dev->mphy.cap.has_2ghz = true;
1466c92544dSBjoern A. Zeeb dev->mphy.cap.has_5ghz = true;
1476c92544dSBjoern A. Zeeb break;
1486c92544dSBjoern A. Zeeb }
1496c92544dSBjoern A. Zeeb }
1506c92544dSBjoern A. Zeeb
mt7615_eeprom_parse_hw_cap(struct mt7615_dev * dev)1516c92544dSBjoern A. Zeeb static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
1526c92544dSBjoern A. Zeeb {
1536c92544dSBjoern A. Zeeb u8 *eeprom = dev->mt76.eeprom.data;
1546c92544dSBjoern A. Zeeb u8 tx_mask, max_nss;
1556c92544dSBjoern A. Zeeb
1566c92544dSBjoern A. Zeeb mt7615_eeprom_parse_hw_band_cap(dev);
1576c92544dSBjoern A. Zeeb
1586c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76)) {
1596c92544dSBjoern A. Zeeb max_nss = 2;
1606c92544dSBjoern A. Zeeb tx_mask = FIELD_GET(MT_EE_HW_CONF1_TX_MASK,
1616c92544dSBjoern A. Zeeb eeprom[MT7663_EE_HW_CONF1]);
1626c92544dSBjoern A. Zeeb } else {
1636c92544dSBjoern A. Zeeb u32 val;
1646c92544dSBjoern A. Zeeb
1656c92544dSBjoern A. Zeeb /* read tx-rx mask from eeprom */
1666c92544dSBjoern A. Zeeb val = mt76_rr(dev, MT_TOP_STRAP_STA);
1676c92544dSBjoern A. Zeeb max_nss = val & MT_TOP_3NSS ? 3 : 4;
1686c92544dSBjoern A. Zeeb
1696c92544dSBjoern A. Zeeb tx_mask = FIELD_GET(MT_EE_NIC_CONF_TX_MASK,
1706c92544dSBjoern A. Zeeb eeprom[MT_EE_NIC_CONF_0]);
1716c92544dSBjoern A. Zeeb }
1726c92544dSBjoern A. Zeeb if (!tx_mask || tx_mask > max_nss)
1736c92544dSBjoern A. Zeeb tx_mask = max_nss;
1746c92544dSBjoern A. Zeeb
1756c92544dSBjoern A. Zeeb dev->chainmask = BIT(tx_mask) - 1;
1766c92544dSBjoern A. Zeeb dev->mphy.antenna_mask = dev->chainmask;
1776c92544dSBjoern A. Zeeb dev->mphy.chainmask = dev->chainmask;
1786c92544dSBjoern A. Zeeb }
1796c92544dSBjoern A. Zeeb
mt7663_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)1806c92544dSBjoern A. Zeeb static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,
1816c92544dSBjoern A. Zeeb struct ieee80211_channel *chan,
1826c92544dSBjoern A. Zeeb u8 chain_idx)
1836c92544dSBjoern A. Zeeb {
1846c92544dSBjoern A. Zeeb int index, group;
1856c92544dSBjoern A. Zeeb
1866c92544dSBjoern A. Zeeb if (chain_idx > 1)
1876c92544dSBjoern A. Zeeb return -EINVAL;
1886c92544dSBjoern A. Zeeb
1896c92544dSBjoern A. Zeeb if (chan->band == NL80211_BAND_2GHZ)
1906c92544dSBjoern A. Zeeb return MT7663_EE_TX0_2G_TARGET_POWER + (chain_idx << 4);
1916c92544dSBjoern A. Zeeb
1926c92544dSBjoern A. Zeeb group = mt7615_get_channel_group(chan->hw_value);
1936c92544dSBjoern A. Zeeb if (chain_idx == 1)
1946c92544dSBjoern A. Zeeb index = MT7663_EE_TX1_5G_G0_TARGET_POWER;
1956c92544dSBjoern A. Zeeb else
1966c92544dSBjoern A. Zeeb index = MT7663_EE_TX0_5G_G0_TARGET_POWER;
1976c92544dSBjoern A. Zeeb
1986c92544dSBjoern A. Zeeb return index + group * 3;
1996c92544dSBjoern A. Zeeb }
2006c92544dSBjoern A. Zeeb
mt7615_eeprom_get_target_power_index(struct mt7615_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)2016c92544dSBjoern A. Zeeb int mt7615_eeprom_get_target_power_index(struct mt7615_dev *dev,
2026c92544dSBjoern A. Zeeb struct ieee80211_channel *chan,
2036c92544dSBjoern A. Zeeb u8 chain_idx)
2046c92544dSBjoern A. Zeeb {
2056c92544dSBjoern A. Zeeb int index;
2066c92544dSBjoern A. Zeeb
2076c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76))
2086c92544dSBjoern A. Zeeb return mt7663_eeprom_get_target_power_index(dev, chan,
2096c92544dSBjoern A. Zeeb chain_idx);
2106c92544dSBjoern A. Zeeb
2116c92544dSBjoern A. Zeeb if (chain_idx > 3)
2126c92544dSBjoern A. Zeeb return -EINVAL;
2136c92544dSBjoern A. Zeeb
2146c92544dSBjoern A. Zeeb /* TSSI disabled */
2156c92544dSBjoern A. Zeeb if (mt7615_ext_pa_enabled(dev, chan->band)) {
2166c92544dSBjoern A. Zeeb if (chan->band == NL80211_BAND_2GHZ)
2176c92544dSBjoern A. Zeeb return MT_EE_EXT_PA_2G_TARGET_POWER;
2186c92544dSBjoern A. Zeeb else
2196c92544dSBjoern A. Zeeb return MT_EE_EXT_PA_5G_TARGET_POWER;
2206c92544dSBjoern A. Zeeb }
2216c92544dSBjoern A. Zeeb
2226c92544dSBjoern A. Zeeb /* TSSI enabled */
2236c92544dSBjoern A. Zeeb if (chan->band == NL80211_BAND_2GHZ) {
2246c92544dSBjoern A. Zeeb index = MT_EE_TX0_2G_TARGET_POWER + chain_idx * 6;
2256c92544dSBjoern A. Zeeb } else {
2266c92544dSBjoern A. Zeeb int group = mt7615_get_channel_group(chan->hw_value);
2276c92544dSBjoern A. Zeeb
2286c92544dSBjoern A. Zeeb switch (chain_idx) {
2296c92544dSBjoern A. Zeeb case 1:
2306c92544dSBjoern A. Zeeb index = MT_EE_TX1_5G_G0_TARGET_POWER;
2316c92544dSBjoern A. Zeeb break;
2326c92544dSBjoern A. Zeeb case 2:
2336c92544dSBjoern A. Zeeb index = MT_EE_TX2_5G_G0_TARGET_POWER;
2346c92544dSBjoern A. Zeeb break;
2356c92544dSBjoern A. Zeeb case 3:
2366c92544dSBjoern A. Zeeb index = MT_EE_TX3_5G_G0_TARGET_POWER;
2376c92544dSBjoern A. Zeeb break;
2386c92544dSBjoern A. Zeeb case 0:
2396c92544dSBjoern A. Zeeb default:
2406c92544dSBjoern A. Zeeb index = MT_EE_TX0_5G_G0_TARGET_POWER;
2416c92544dSBjoern A. Zeeb break;
2426c92544dSBjoern A. Zeeb }
2436c92544dSBjoern A. Zeeb index += 5 * group;
2446c92544dSBjoern A. Zeeb }
2456c92544dSBjoern A. Zeeb
2466c92544dSBjoern A. Zeeb return index;
2476c92544dSBjoern A. Zeeb }
2486c92544dSBjoern A. Zeeb
mt7615_eeprom_get_power_delta_index(struct mt7615_dev * dev,enum nl80211_band band)2496c92544dSBjoern A. Zeeb int mt7615_eeprom_get_power_delta_index(struct mt7615_dev *dev,
2506c92544dSBjoern A. Zeeb enum nl80211_band band)
2516c92544dSBjoern A. Zeeb {
2526c92544dSBjoern A. Zeeb /* assume the first rate has the highest power offset */
2536c92544dSBjoern A. Zeeb if (is_mt7663(&dev->mt76)) {
2546c92544dSBjoern A. Zeeb if (band == NL80211_BAND_2GHZ)
2556c92544dSBjoern A. Zeeb return MT_EE_TX0_5G_G0_TARGET_POWER;
2566c92544dSBjoern A. Zeeb else
2576c92544dSBjoern A. Zeeb return MT7663_EE_5G_RATE_POWER;
2586c92544dSBjoern A. Zeeb }
2596c92544dSBjoern A. Zeeb
2606c92544dSBjoern A. Zeeb if (band == NL80211_BAND_2GHZ)
2616c92544dSBjoern A. Zeeb return MT_EE_2G_RATE_POWER;
2626c92544dSBjoern A. Zeeb else
2636c92544dSBjoern A. Zeeb return MT_EE_5G_RATE_POWER;
2646c92544dSBjoern A. Zeeb }
2656c92544dSBjoern A. Zeeb
266*77285868SBjoern A. Zeeb #if defined(__linux__)
mt7615_apply_cal_free_data(struct mt7615_dev * dev)2676c92544dSBjoern A. Zeeb static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
2686c92544dSBjoern A. Zeeb {
2696c92544dSBjoern A. Zeeb static const u16 ical[] = {
2706c92544dSBjoern A. Zeeb 0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
2716c92544dSBjoern A. Zeeb 0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
2726c92544dSBjoern A. Zeeb 0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
2736c92544dSBjoern A. Zeeb 0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
2746c92544dSBjoern A. Zeeb 0xf7, 0xff,
2756c92544dSBjoern A. Zeeb 0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
2766c92544dSBjoern A. Zeeb 0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
2776c92544dSBjoern A. Zeeb 0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
2786c92544dSBjoern A. Zeeb 0x18c
2796c92544dSBjoern A. Zeeb };
2806c92544dSBjoern A. Zeeb static const u16 ical_nocheck[] = {
2816c92544dSBjoern A. Zeeb 0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
2826c92544dSBjoern A. Zeeb 0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
2836c92544dSBjoern A. Zeeb 0x3b2
2846c92544dSBjoern A. Zeeb };
2856c92544dSBjoern A. Zeeb u8 *eeprom = dev->mt76.eeprom.data;
2866c92544dSBjoern A. Zeeb u8 *otp = dev->mt76.otp.data;
2876c92544dSBjoern A. Zeeb int i;
2886c92544dSBjoern A. Zeeb
2896c92544dSBjoern A. Zeeb if (!otp)
2906c92544dSBjoern A. Zeeb return;
2916c92544dSBjoern A. Zeeb
2926c92544dSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(ical); i++)
2936c92544dSBjoern A. Zeeb if (!otp[ical[i]])
2946c92544dSBjoern A. Zeeb return;
2956c92544dSBjoern A. Zeeb
2966c92544dSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(ical); i++)
2976c92544dSBjoern A. Zeeb eeprom[ical[i]] = otp[ical[i]];
2986c92544dSBjoern A. Zeeb
2996c92544dSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
3006c92544dSBjoern A. Zeeb eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
3016c92544dSBjoern A. Zeeb }
3026c92544dSBjoern A. Zeeb
mt7622_apply_cal_free_data(struct mt7615_dev * dev)3036c92544dSBjoern A. Zeeb static void mt7622_apply_cal_free_data(struct mt7615_dev *dev)
3046c92544dSBjoern A. Zeeb {
3056c92544dSBjoern A. Zeeb static const u16 ical[] = {
3066c92544dSBjoern A. Zeeb 0x53, 0x54, 0x55, 0x56, 0xf4, 0xf7, 0x144, 0x156, 0x15b
3076c92544dSBjoern A. Zeeb };
3086c92544dSBjoern A. Zeeb u8 *eeprom = dev->mt76.eeprom.data;
3096c92544dSBjoern A. Zeeb u8 *otp = dev->mt76.otp.data;
3106c92544dSBjoern A. Zeeb int i;
3116c92544dSBjoern A. Zeeb
3126c92544dSBjoern A. Zeeb if (!otp)
3136c92544dSBjoern A. Zeeb return;
3146c92544dSBjoern A. Zeeb
3156c92544dSBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(ical); i++) {
3166c92544dSBjoern A. Zeeb if (!otp[ical[i]])
3176c92544dSBjoern A. Zeeb continue;
3186c92544dSBjoern A. Zeeb
3196c92544dSBjoern A. Zeeb eeprom[ical[i]] = otp[ical[i]];
3206c92544dSBjoern A. Zeeb }
3216c92544dSBjoern A. Zeeb }
322*77285868SBjoern A. Zeeb #endif
3236c92544dSBjoern A. Zeeb
mt7615_cal_free_data(struct mt7615_dev * dev)3246c92544dSBjoern A. Zeeb static void mt7615_cal_free_data(struct mt7615_dev *dev)
3256c92544dSBjoern A. Zeeb {
326*77285868SBjoern A. Zeeb #if defined(__linux__)
3276c92544dSBjoern A. Zeeb struct device_node *np = dev->mt76.dev->of_node;
3286c92544dSBjoern A. Zeeb
3296c92544dSBjoern A. Zeeb if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
3306c92544dSBjoern A. Zeeb return;
3316c92544dSBjoern A. Zeeb
3326c92544dSBjoern A. Zeeb switch (mt76_chip(&dev->mt76)) {
3336c92544dSBjoern A. Zeeb case 0x7622:
3346c92544dSBjoern A. Zeeb mt7622_apply_cal_free_data(dev);
3356c92544dSBjoern A. Zeeb break;
3366c92544dSBjoern A. Zeeb case 0x7615:
3376c92544dSBjoern A. Zeeb case 0x7611:
3386c92544dSBjoern A. Zeeb mt7615_apply_cal_free_data(dev);
3396c92544dSBjoern A. Zeeb break;
3406c92544dSBjoern A. Zeeb }
341*77285868SBjoern A. Zeeb #endif
3426c92544dSBjoern A. Zeeb }
3436c92544dSBjoern A. Zeeb
mt7615_eeprom_init(struct mt7615_dev * dev,u32 addr)3446c92544dSBjoern A. Zeeb int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
3456c92544dSBjoern A. Zeeb {
3466c92544dSBjoern A. Zeeb int ret;
3476c92544dSBjoern A. Zeeb
3486c92544dSBjoern A. Zeeb ret = mt7615_eeprom_load(dev, addr);
3496c92544dSBjoern A. Zeeb if (ret < 0)
3506c92544dSBjoern A. Zeeb return ret;
3516c92544dSBjoern A. Zeeb
3526c92544dSBjoern A. Zeeb ret = mt7615_check_eeprom(&dev->mt76);
3536c92544dSBjoern A. Zeeb if (ret && dev->mt76.otp.data) {
3546c92544dSBjoern A. Zeeb memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
355cbb3ec25SBjoern A. Zeeb dev->mt76.otp.size);
3566c92544dSBjoern A. Zeeb } else {
3576c92544dSBjoern A. Zeeb dev->flash_eeprom = true;
3586c92544dSBjoern A. Zeeb mt7615_cal_free_data(dev);
3596c92544dSBjoern A. Zeeb }
3606c92544dSBjoern A. Zeeb
3616c92544dSBjoern A. Zeeb mt7615_eeprom_parse_hw_cap(dev);
362*77285868SBjoern A. Zeeb #if defined(__linux__)
3636c92544dSBjoern A. Zeeb memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
364*77285868SBjoern A. Zeeb #elif defined(__FreeBSD__)
365*77285868SBjoern A. Zeeb memcpy(dev->mphy.macaddr, (u8 *)dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
366*77285868SBjoern A. Zeeb #endif
3676c92544dSBjoern A. Zeeb ETH_ALEN);
3686c92544dSBjoern A. Zeeb
3696c92544dSBjoern A. Zeeb mt76_eeprom_override(&dev->mphy);
3706c92544dSBjoern A. Zeeb
3716c92544dSBjoern A. Zeeb return 0;
3726c92544dSBjoern A. Zeeb }
3736c92544dSBjoern A. Zeeb EXPORT_SYMBOL_GPL(mt7615_eeprom_init);
374