xref: /freebsd/sys/contrib/dev/mediatek/mt76/mt7915/eeprom.c (revision cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf)
16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC
26c92544dSBjoern A. Zeeb /* Copyright (C) 2020 MediaTek Inc. */
36c92544dSBjoern A. Zeeb 
46c92544dSBjoern A. Zeeb #include <linux/firmware.h>
56c92544dSBjoern A. Zeeb #include "mt7915.h"
66c92544dSBjoern A. Zeeb #include "eeprom.h"
76c92544dSBjoern A. Zeeb 
mt7915_eeprom_load_precal(struct mt7915_dev * dev)86c92544dSBjoern A. Zeeb static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
96c92544dSBjoern A. Zeeb {
106c92544dSBjoern A. Zeeb 	struct mt76_dev *mdev = &dev->mt76;
116c92544dSBjoern A. Zeeb 	u8 *eeprom = mdev->eeprom.data;
126c92544dSBjoern A. Zeeb 	u32 val = eeprom[MT_EE_DO_PRE_CAL];
136c92544dSBjoern A. Zeeb 	u32 offs;
146c92544dSBjoern A. Zeeb 
156c92544dSBjoern A. Zeeb 	if (!dev->flash_mode)
166c92544dSBjoern A. Zeeb 		return 0;
176c92544dSBjoern A. Zeeb 
186c92544dSBjoern A. Zeeb 	if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
196c92544dSBjoern A. Zeeb 		return 0;
206c92544dSBjoern A. Zeeb 
216c92544dSBjoern A. Zeeb 	val = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
226c92544dSBjoern A. Zeeb 	dev->cal = devm_kzalloc(mdev->dev, val, GFP_KERNEL);
236c92544dSBjoern A. Zeeb 	if (!dev->cal)
246c92544dSBjoern A. Zeeb 		return -ENOMEM;
256c92544dSBjoern A. Zeeb 
266c92544dSBjoern A. Zeeb 	offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
276c92544dSBjoern A. Zeeb 
286c92544dSBjoern A. Zeeb 	return mt76_get_of_eeprom(mdev, dev->cal, offs, val);
296c92544dSBjoern A. Zeeb }
306c92544dSBjoern A. Zeeb 
mt7915_check_eeprom(struct mt7915_dev * dev)316c92544dSBjoern A. Zeeb static int mt7915_check_eeprom(struct mt7915_dev *dev)
326c92544dSBjoern A. Zeeb {
336c92544dSBjoern A. Zeeb 	u8 *eeprom = dev->mt76.eeprom.data;
346c92544dSBjoern A. Zeeb 	u16 val = get_unaligned_le16(eeprom);
356c92544dSBjoern A. Zeeb 
36*cbb3ec25SBjoern A. Zeeb #define CHECK_EEPROM_ERR(match)	(match ? 0 : -EINVAL)
376c92544dSBjoern A. Zeeb 	switch (val) {
386c92544dSBjoern A. Zeeb 	case 0x7915:
39*cbb3ec25SBjoern A. Zeeb 		return CHECK_EEPROM_ERR(is_mt7915(&dev->mt76));
406c92544dSBjoern A. Zeeb 	case 0x7916:
41*cbb3ec25SBjoern A. Zeeb 		return CHECK_EEPROM_ERR(is_mt7916(&dev->mt76));
42*cbb3ec25SBjoern A. Zeeb 	case 0x7981:
43*cbb3ec25SBjoern A. Zeeb 		return CHECK_EEPROM_ERR(is_mt7981(&dev->mt76));
446c92544dSBjoern A. Zeeb 	case 0x7986:
45*cbb3ec25SBjoern A. Zeeb 		return CHECK_EEPROM_ERR(is_mt7986(&dev->mt76));
466c92544dSBjoern A. Zeeb 	default:
476c92544dSBjoern A. Zeeb 		return -EINVAL;
486c92544dSBjoern A. Zeeb 	}
496c92544dSBjoern A. Zeeb }
506c92544dSBjoern A. Zeeb 
mt7915_eeprom_name(struct mt7915_dev * dev)516c92544dSBjoern A. Zeeb static char *mt7915_eeprom_name(struct mt7915_dev *dev)
526c92544dSBjoern A. Zeeb {
536c92544dSBjoern A. Zeeb 	switch (mt76_chip(&dev->mt76)) {
546c92544dSBjoern A. Zeeb 	case 0x7915:
556c92544dSBjoern A. Zeeb 		return dev->dbdc_support ?
566c92544dSBjoern A. Zeeb 		       MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT;
57*cbb3ec25SBjoern A. Zeeb 	case 0x7981:
58*cbb3ec25SBjoern A. Zeeb 		/* mt7981 only supports mt7976 and only in DBDC mode */
59*cbb3ec25SBjoern A. Zeeb 		return MT7981_EEPROM_MT7976_DEFAULT_DBDC;
606c92544dSBjoern A. Zeeb 	case 0x7986:
616c92544dSBjoern A. Zeeb 		switch (mt7915_check_adie(dev, true)) {
626c92544dSBjoern A. Zeeb 		case MT7976_ONE_ADIE_DBDC:
636c92544dSBjoern A. Zeeb 			return MT7986_EEPROM_MT7976_DEFAULT_DBDC;
646c92544dSBjoern A. Zeeb 		case MT7975_ONE_ADIE:
656c92544dSBjoern A. Zeeb 			return MT7986_EEPROM_MT7975_DEFAULT;
666c92544dSBjoern A. Zeeb 		case MT7976_ONE_ADIE:
676c92544dSBjoern A. Zeeb 			return MT7986_EEPROM_MT7976_DEFAULT;
686c92544dSBjoern A. Zeeb 		case MT7975_DUAL_ADIE:
696c92544dSBjoern A. Zeeb 			return MT7986_EEPROM_MT7975_DUAL_DEFAULT;
706c92544dSBjoern A. Zeeb 		case MT7976_DUAL_ADIE:
716c92544dSBjoern A. Zeeb 			return MT7986_EEPROM_MT7976_DUAL_DEFAULT;
726c92544dSBjoern A. Zeeb 		default:
736c92544dSBjoern A. Zeeb 			break;
746c92544dSBjoern A. Zeeb 		}
756c92544dSBjoern A. Zeeb 		return NULL;
766c92544dSBjoern A. Zeeb 	default:
776c92544dSBjoern A. Zeeb 		return MT7916_EEPROM_DEFAULT;
786c92544dSBjoern A. Zeeb 	}
796c92544dSBjoern A. Zeeb }
806c92544dSBjoern A. Zeeb 
816c92544dSBjoern A. Zeeb static int
mt7915_eeprom_load_default(struct mt7915_dev * dev)826c92544dSBjoern A. Zeeb mt7915_eeprom_load_default(struct mt7915_dev *dev)
836c92544dSBjoern A. Zeeb {
846c92544dSBjoern A. Zeeb 	u8 *eeprom = dev->mt76.eeprom.data;
856c92544dSBjoern A. Zeeb 	const struct firmware *fw = NULL;
866c92544dSBjoern A. Zeeb 	int ret;
876c92544dSBjoern A. Zeeb 
886c92544dSBjoern A. Zeeb 	ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev);
896c92544dSBjoern A. Zeeb 	if (ret)
906c92544dSBjoern A. Zeeb 		return ret;
916c92544dSBjoern A. Zeeb 
926c92544dSBjoern A. Zeeb 	if (!fw || !fw->data) {
936c92544dSBjoern A. Zeeb 		dev_err(dev->mt76.dev, "Invalid default bin\n");
946c92544dSBjoern A. Zeeb 		ret = -EINVAL;
956c92544dSBjoern A. Zeeb 		goto out;
966c92544dSBjoern A. Zeeb 	}
976c92544dSBjoern A. Zeeb 
986c92544dSBjoern A. Zeeb 	memcpy(eeprom, fw->data, mt7915_eeprom_size(dev));
996c92544dSBjoern A. Zeeb 	dev->flash_mode = true;
1006c92544dSBjoern A. Zeeb 
1016c92544dSBjoern A. Zeeb out:
1026c92544dSBjoern A. Zeeb 	release_firmware(fw);
1036c92544dSBjoern A. Zeeb 
1046c92544dSBjoern A. Zeeb 	return ret;
1056c92544dSBjoern A. Zeeb }
1066c92544dSBjoern A. Zeeb 
mt7915_eeprom_load(struct mt7915_dev * dev)1076c92544dSBjoern A. Zeeb static int mt7915_eeprom_load(struct mt7915_dev *dev)
1086c92544dSBjoern A. Zeeb {
1096c92544dSBjoern A. Zeeb 	int ret;
1106c92544dSBjoern A. Zeeb 	u16 eeprom_size = mt7915_eeprom_size(dev);
1116c92544dSBjoern A. Zeeb 
1126c92544dSBjoern A. Zeeb 	ret = mt76_eeprom_init(&dev->mt76, eeprom_size);
1136c92544dSBjoern A. Zeeb 	if (ret < 0)
1146c92544dSBjoern A. Zeeb 		return ret;
1156c92544dSBjoern A. Zeeb 
1166c92544dSBjoern A. Zeeb 	if (ret) {
1176c92544dSBjoern A. Zeeb 		dev->flash_mode = true;
1186c92544dSBjoern A. Zeeb 	} else {
1196c92544dSBjoern A. Zeeb 		u8 free_block_num;
1206c92544dSBjoern A. Zeeb 		u32 block_num, i;
121*cbb3ec25SBjoern A. Zeeb 		u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE;
1226c92544dSBjoern A. Zeeb 
123*cbb3ec25SBjoern A. Zeeb 		ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
124*cbb3ec25SBjoern A. Zeeb 		if (ret < 0)
125*cbb3ec25SBjoern A. Zeeb 			return ret;
126*cbb3ec25SBjoern A. Zeeb 
127*cbb3ec25SBjoern A. Zeeb 		/* efuse info isn't enough */
1286c92544dSBjoern A. Zeeb 		if (free_block_num >= 29)
1296c92544dSBjoern A. Zeeb 			return -EINVAL;
1306c92544dSBjoern A. Zeeb 
1316c92544dSBjoern A. Zeeb 		/* read eeprom data from efuse */
132*cbb3ec25SBjoern A. Zeeb 		block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
133*cbb3ec25SBjoern A. Zeeb 		for (i = 0; i < block_num; i++) {
134*cbb3ec25SBjoern A. Zeeb 			ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size);
135*cbb3ec25SBjoern A. Zeeb 			if (ret < 0)
136*cbb3ec25SBjoern A. Zeeb 				return ret;
137*cbb3ec25SBjoern A. Zeeb 		}
1386c92544dSBjoern A. Zeeb 	}
1396c92544dSBjoern A. Zeeb 
1406c92544dSBjoern A. Zeeb 	return mt7915_check_eeprom(dev);
1416c92544dSBjoern A. Zeeb }
1426c92544dSBjoern A. Zeeb 
mt7915_eeprom_parse_band_config(struct mt7915_phy * phy)1436c92544dSBjoern A. Zeeb static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
1446c92544dSBjoern A. Zeeb {
1456c92544dSBjoern A. Zeeb 	struct mt7915_dev *dev = phy->dev;
1466c92544dSBjoern A. Zeeb 	u8 *eeprom = dev->mt76.eeprom.data;
147*cbb3ec25SBjoern A. Zeeb 	u8 band = phy->mt76->band_idx;
1486c92544dSBjoern A. Zeeb 	u32 val;
1496c92544dSBjoern A. Zeeb 
150*cbb3ec25SBjoern A. Zeeb 	val = eeprom[MT_EE_WIFI_CONF + band];
1516c92544dSBjoern A. Zeeb 	val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
1526c92544dSBjoern A. Zeeb 
1536c92544dSBjoern A. Zeeb 	if (!is_mt7915(&dev->mt76)) {
1546c92544dSBjoern A. Zeeb 		switch (val) {
1556c92544dSBjoern A. Zeeb 		case MT_EE_V2_BAND_SEL_5GHZ:
1566c92544dSBjoern A. Zeeb 			phy->mt76->cap.has_5ghz = true;
1576c92544dSBjoern A. Zeeb 			return;
1586c92544dSBjoern A. Zeeb 		case MT_EE_V2_BAND_SEL_6GHZ:
1596c92544dSBjoern A. Zeeb 			phy->mt76->cap.has_6ghz = true;
1606c92544dSBjoern A. Zeeb 			return;
1616c92544dSBjoern A. Zeeb 		case MT_EE_V2_BAND_SEL_5GHZ_6GHZ:
1626c92544dSBjoern A. Zeeb 			phy->mt76->cap.has_5ghz = true;
1636c92544dSBjoern A. Zeeb 			phy->mt76->cap.has_6ghz = true;
1646c92544dSBjoern A. Zeeb 			return;
1656c92544dSBjoern A. Zeeb 		default:
1666c92544dSBjoern A. Zeeb 			phy->mt76->cap.has_2ghz = true;
1676c92544dSBjoern A. Zeeb 			return;
1686c92544dSBjoern A. Zeeb 		}
1696c92544dSBjoern A. Zeeb 	} else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) {
170*cbb3ec25SBjoern A. Zeeb 		val = band ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
1716c92544dSBjoern A. Zeeb 	}
1726c92544dSBjoern A. Zeeb 
1736c92544dSBjoern A. Zeeb 	switch (val) {
1746c92544dSBjoern A. Zeeb 	case MT_EE_BAND_SEL_5GHZ:
1756c92544dSBjoern A. Zeeb 		phy->mt76->cap.has_5ghz = true;
1766c92544dSBjoern A. Zeeb 		break;
1776c92544dSBjoern A. Zeeb 	case MT_EE_BAND_SEL_2GHZ:
1786c92544dSBjoern A. Zeeb 		phy->mt76->cap.has_2ghz = true;
1796c92544dSBjoern A. Zeeb 		break;
1806c92544dSBjoern A. Zeeb 	default:
1816c92544dSBjoern A. Zeeb 		phy->mt76->cap.has_2ghz = true;
1826c92544dSBjoern A. Zeeb 		phy->mt76->cap.has_5ghz = true;
1836c92544dSBjoern A. Zeeb 		break;
1846c92544dSBjoern A. Zeeb 	}
1856c92544dSBjoern A. Zeeb }
1866c92544dSBjoern A. Zeeb 
mt7915_eeprom_parse_hw_cap(struct mt7915_dev * dev,struct mt7915_phy * phy)1876c92544dSBjoern A. Zeeb void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
1886c92544dSBjoern A. Zeeb 				struct mt7915_phy *phy)
1896c92544dSBjoern A. Zeeb {
190*cbb3ec25SBjoern A. Zeeb 	u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;
1916c92544dSBjoern A. Zeeb 	struct mt76_phy *mphy = phy->mt76;
192*cbb3ec25SBjoern A. Zeeb 	u8 band = phy->mt76->band_idx;
1936c92544dSBjoern A. Zeeb 
1946c92544dSBjoern A. Zeeb 	mt7915_eeprom_parse_band_config(phy);
1956c92544dSBjoern A. Zeeb 
196*cbb3ec25SBjoern A. Zeeb 	/* read tx/rx path from eeprom */
1976c92544dSBjoern A. Zeeb 	if (is_mt7915(&dev->mt76)) {
198*cbb3ec25SBjoern A. Zeeb 		path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
1996c92544dSBjoern A. Zeeb 				 eeprom[MT_EE_WIFI_CONF]);
2006c92544dSBjoern A. Zeeb 	} else {
201*cbb3ec25SBjoern A. Zeeb 		path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
202*cbb3ec25SBjoern A. Zeeb 				 eeprom[MT_EE_WIFI_CONF + band]);
2036c92544dSBjoern A. Zeeb 	}
2046c92544dSBjoern A. Zeeb 
205*cbb3ec25SBjoern A. Zeeb 	if (!path || path > 4)
206*cbb3ec25SBjoern A. Zeeb 		path = 4;
2076c92544dSBjoern A. Zeeb 
2086c92544dSBjoern A. Zeeb 	/* read tx/rx stream */
209*cbb3ec25SBjoern A. Zeeb 	nss = path;
2106c92544dSBjoern A. Zeeb 	if (dev->dbdc_support) {
2116c92544dSBjoern A. Zeeb 		if (is_mt7915(&dev->mt76)) {
212*cbb3ec25SBjoern A. Zeeb 			path = min_t(u8, path, 2);
213*cbb3ec25SBjoern A. Zeeb 			nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
2146c92544dSBjoern A. Zeeb 					eeprom[MT_EE_WIFI_CONF + 3]);
215*cbb3ec25SBjoern A. Zeeb 			if (band)
216*cbb3ec25SBjoern A. Zeeb 				nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
2176c92544dSBjoern A. Zeeb 						eeprom[MT_EE_WIFI_CONF + 3]);
2186c92544dSBjoern A. Zeeb 		} else {
219*cbb3ec25SBjoern A. Zeeb 			nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
220*cbb3ec25SBjoern A. Zeeb 					eeprom[MT_EE_WIFI_CONF + 2 + band]);
2216c92544dSBjoern A. Zeeb 		}
2226c92544dSBjoern A. Zeeb 
223*cbb3ec25SBjoern A. Zeeb 		if (!is_mt798x(&dev->mt76))
224*cbb3ec25SBjoern A. Zeeb 			nss_max = 2;
2256c92544dSBjoern A. Zeeb 	}
2266c92544dSBjoern A. Zeeb 
227*cbb3ec25SBjoern A. Zeeb 	if (!nss)
228*cbb3ec25SBjoern A. Zeeb 		nss = nss_max;
229*cbb3ec25SBjoern A. Zeeb 	nss = min_t(u8, min_t(u8, nss_max, nss), path);
2306c92544dSBjoern A. Zeeb 
231*cbb3ec25SBjoern A. Zeeb 	mphy->chainmask = BIT(path) - 1;
232*cbb3ec25SBjoern A. Zeeb 	if (band)
2336c92544dSBjoern A. Zeeb 		mphy->chainmask <<= dev->chainshift;
234*cbb3ec25SBjoern A. Zeeb 	mphy->antenna_mask = BIT(nss) - 1;
2356c92544dSBjoern A. Zeeb 	dev->chainmask |= mphy->chainmask;
2366c92544dSBjoern A. Zeeb 	dev->chainshift = hweight8(dev->mphy.chainmask);
2376c92544dSBjoern A. Zeeb }
2386c92544dSBjoern A. Zeeb 
mt7915_eeprom_init(struct mt7915_dev * dev)2396c92544dSBjoern A. Zeeb int mt7915_eeprom_init(struct mt7915_dev *dev)
2406c92544dSBjoern A. Zeeb {
2416c92544dSBjoern A. Zeeb 	int ret;
2426c92544dSBjoern A. Zeeb 
2436c92544dSBjoern A. Zeeb 	ret = mt7915_eeprom_load(dev);
2446c92544dSBjoern A. Zeeb 	if (ret < 0) {
2456c92544dSBjoern A. Zeeb 		if (ret != -EINVAL)
2466c92544dSBjoern A. Zeeb 			return ret;
2476c92544dSBjoern A. Zeeb 
2486c92544dSBjoern A. Zeeb 		dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
2496c92544dSBjoern A. Zeeb 		ret = mt7915_eeprom_load_default(dev);
2506c92544dSBjoern A. Zeeb 		if (ret)
2516c92544dSBjoern A. Zeeb 			return ret;
2526c92544dSBjoern A. Zeeb 	}
2536c92544dSBjoern A. Zeeb 
2546c92544dSBjoern A. Zeeb 	ret = mt7915_eeprom_load_precal(dev);
2556c92544dSBjoern A. Zeeb 	if (ret)
2566c92544dSBjoern A. Zeeb 		return ret;
2576c92544dSBjoern A. Zeeb 
2586c92544dSBjoern A. Zeeb 	mt7915_eeprom_parse_hw_cap(dev, &dev->phy);
2596c92544dSBjoern A. Zeeb #if defined(__linux__)
2606c92544dSBjoern A. Zeeb 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
2616c92544dSBjoern A. Zeeb #elif defined(__FreeBSD__)
2626c92544dSBjoern A. Zeeb 	memcpy(dev->mphy.macaddr, (u8 *)dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
2636c92544dSBjoern A. Zeeb #endif
2646c92544dSBjoern A. Zeeb 	       ETH_ALEN);
2656c92544dSBjoern A. Zeeb 
2666c92544dSBjoern A. Zeeb 	mt76_eeprom_override(&dev->mphy);
2676c92544dSBjoern A. Zeeb 
2686c92544dSBjoern A. Zeeb 	return 0;
2696c92544dSBjoern A. Zeeb }
2706c92544dSBjoern A. Zeeb 
mt7915_eeprom_get_target_power(struct mt7915_dev * dev,struct ieee80211_channel * chan,u8 chain_idx)2716c92544dSBjoern A. Zeeb int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
2726c92544dSBjoern A. Zeeb 				   struct ieee80211_channel *chan,
2736c92544dSBjoern A. Zeeb 				   u8 chain_idx)
2746c92544dSBjoern A. Zeeb {
2756c92544dSBjoern A. Zeeb 	u8 *eeprom = dev->mt76.eeprom.data;
2766c92544dSBjoern A. Zeeb 	int index, target_power;
2776c92544dSBjoern A. Zeeb 	bool tssi_on, is_7976;
2786c92544dSBjoern A. Zeeb 
2796c92544dSBjoern A. Zeeb 	if (chain_idx > 3)
2806c92544dSBjoern A. Zeeb 		return -EINVAL;
2816c92544dSBjoern A. Zeeb 
2826c92544dSBjoern A. Zeeb 	tssi_on = mt7915_tssi_enabled(dev, chan->band);
2836c92544dSBjoern A. Zeeb 	is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
2846c92544dSBjoern A. Zeeb 
2856c92544dSBjoern A. Zeeb 	if (chan->band == NL80211_BAND_2GHZ) {
2866c92544dSBjoern A. Zeeb 		if (is_7976) {
2876c92544dSBjoern A. Zeeb 			index = MT_EE_TX0_POWER_2G_V2 + chain_idx;
2886c92544dSBjoern A. Zeeb 			target_power = eeprom[index];
2896c92544dSBjoern A. Zeeb 		} else {
2906c92544dSBjoern A. Zeeb 			index = MT_EE_TX0_POWER_2G + chain_idx * 3;
2916c92544dSBjoern A. Zeeb 			target_power = eeprom[index];
2926c92544dSBjoern A. Zeeb 
2936c92544dSBjoern A. Zeeb 			if (!tssi_on)
2946c92544dSBjoern A. Zeeb 				target_power += eeprom[index + 1];
2956c92544dSBjoern A. Zeeb 		}
2966c92544dSBjoern A. Zeeb 	} else if (chan->band == NL80211_BAND_5GHZ) {
2976c92544dSBjoern A. Zeeb 		int group = mt7915_get_channel_group_5g(chan->hw_value, is_7976);
2986c92544dSBjoern A. Zeeb 
2996c92544dSBjoern A. Zeeb 		if (is_7976) {
3006c92544dSBjoern A. Zeeb 			index = MT_EE_TX0_POWER_5G_V2 + chain_idx * 5;
3016c92544dSBjoern A. Zeeb 			target_power = eeprom[index + group];
3026c92544dSBjoern A. Zeeb 		} else {
3036c92544dSBjoern A. Zeeb 			index = MT_EE_TX0_POWER_5G + chain_idx * 12;
3046c92544dSBjoern A. Zeeb 			target_power = eeprom[index + group];
3056c92544dSBjoern A. Zeeb 
3066c92544dSBjoern A. Zeeb 			if (!tssi_on)
3076c92544dSBjoern A. Zeeb 				target_power += eeprom[index + 8];
3086c92544dSBjoern A. Zeeb 		}
3096c92544dSBjoern A. Zeeb 	} else {
3106c92544dSBjoern A. Zeeb 		int group = mt7915_get_channel_group_6g(chan->hw_value);
3116c92544dSBjoern A. Zeeb 
3126c92544dSBjoern A. Zeeb 		index = MT_EE_TX0_POWER_6G_V2 + chain_idx * 8;
3136c92544dSBjoern A. Zeeb 		target_power = is_7976 ? eeprom[index + group] : 0;
3146c92544dSBjoern A. Zeeb 	}
3156c92544dSBjoern A. Zeeb 
3166c92544dSBjoern A. Zeeb 	return target_power;
3176c92544dSBjoern A. Zeeb }
3186c92544dSBjoern A. Zeeb 
mt7915_eeprom_get_power_delta(struct mt7915_dev * dev,int band)3196c92544dSBjoern A. Zeeb s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
3206c92544dSBjoern A. Zeeb {
3216c92544dSBjoern A. Zeeb 	u8 *eeprom = dev->mt76.eeprom.data;
3226c92544dSBjoern A. Zeeb 	u32 val, offs;
3236c92544dSBjoern A. Zeeb 	s8 delta;
3246c92544dSBjoern A. Zeeb 	bool is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
3256c92544dSBjoern A. Zeeb 
3266c92544dSBjoern A. Zeeb 	if (band == NL80211_BAND_2GHZ)
3276c92544dSBjoern A. Zeeb 		offs = is_7976 ? MT_EE_RATE_DELTA_2G_V2 : MT_EE_RATE_DELTA_2G;
3286c92544dSBjoern A. Zeeb 	else if (band == NL80211_BAND_5GHZ)
3296c92544dSBjoern A. Zeeb 		offs = is_7976 ? MT_EE_RATE_DELTA_5G_V2 : MT_EE_RATE_DELTA_5G;
3306c92544dSBjoern A. Zeeb 	else
3316c92544dSBjoern A. Zeeb 		offs = is_7976 ? MT_EE_RATE_DELTA_6G_V2 : 0;
3326c92544dSBjoern A. Zeeb 
3336c92544dSBjoern A. Zeeb 	val = eeprom[offs];
3346c92544dSBjoern A. Zeeb 
3356c92544dSBjoern A. Zeeb 	if (!offs || !(val & MT_EE_RATE_DELTA_EN))
3366c92544dSBjoern A. Zeeb 		return 0;
3376c92544dSBjoern A. Zeeb 
3386c92544dSBjoern A. Zeeb 	delta = FIELD_GET(MT_EE_RATE_DELTA_MASK, val);
3396c92544dSBjoern A. Zeeb 
3406c92544dSBjoern A. Zeeb 	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
3416c92544dSBjoern A. Zeeb }
3426c92544dSBjoern A. Zeeb 
3436c92544dSBjoern A. Zeeb const u8 mt7915_sku_group_len[] = {
3446c92544dSBjoern A. Zeeb 	[SKU_CCK] = 4,
3456c92544dSBjoern A. Zeeb 	[SKU_OFDM] = 8,
3466c92544dSBjoern A. Zeeb 	[SKU_HT_BW20] = 8,
3476c92544dSBjoern A. Zeeb 	[SKU_HT_BW40] = 9,
3486c92544dSBjoern A. Zeeb 	[SKU_VHT_BW20] = 12,
3496c92544dSBjoern A. Zeeb 	[SKU_VHT_BW40] = 12,
3506c92544dSBjoern A. Zeeb 	[SKU_VHT_BW80] = 12,
3516c92544dSBjoern A. Zeeb 	[SKU_VHT_BW160] = 12,
3526c92544dSBjoern A. Zeeb 	[SKU_HE_RU26] = 12,
3536c92544dSBjoern A. Zeeb 	[SKU_HE_RU52] = 12,
3546c92544dSBjoern A. Zeeb 	[SKU_HE_RU106] = 12,
3556c92544dSBjoern A. Zeeb 	[SKU_HE_RU242] = 12,
3566c92544dSBjoern A. Zeeb 	[SKU_HE_RU484] = 12,
3576c92544dSBjoern A. Zeeb 	[SKU_HE_RU996] = 12,
3586c92544dSBjoern A. Zeeb 	[SKU_HE_RU2x996] = 12
3596c92544dSBjoern A. Zeeb };
360