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