[][MAC80211][WiFi6][mt76][Add cal free data support]

[Description]
Add cal free data support
Merge E3 low yield rate patch into cal free data flow

[Release-log]
N/A

Change-Id: I182ad0b2c5cef0311bee920e63ffd8fea0eba4ca
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8300432
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
deleted file mode 100644
index 408e5b6..0000000
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 81ddde34a61e2a320cf1af73cc91e0465e92cad8 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 30 Mar 2023 15:12:37 +0800
-Subject: [PATCH 1023/1040] wifi: mt76: mt7915: add E3 re-bonding for low yield
- rate issue
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7915/eeprom.c | 28 ++++++++++++++++++++++++++++
- mt7915/mt7915.h |  1 +
- 2 files changed, 29 insertions(+)
-
-diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index fd08d42..3b44a9d 100644
---- a/mt7915/eeprom.c
-+++ b/mt7915/eeprom.c
-@@ -244,6 +244,32 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
- 	dev->chainshift = hweight8(dev->mphy.chainmask);
- }
- 
-+void mt7915_eeprom_rebonding(struct mt7915_dev *dev)
-+{
-+#define MT7976_ADIE_MASK			BIT(1)
-+#define MT7986_ADIE1_EFFUSE_OFFSET		0x1000
-+#define MT7986_ADIE1_MT7976C_OFFSET		0x270
-+#define MT7986_ADIE1_E3_OFFSET			0x271
-+	u32 adie_offset, offset, sku = mt7915_check_adie(dev, true);
-+	u8 read_buf[MT7915_EEPROM_BLOCK_SIZE], *eeprom = dev->mt76.eeprom.data;
-+
-+
-+	if (!(sku & MT7976_ADIE_MASK))
-+		return;
-+
-+	adie_offset = (sku == MT7976_DUAL_ADIE) ? MT7986_ADIE1_EFFUSE_OFFSET : 0;
-+
-+	/* 7976 A-Die, To identify MT7976C */
-+	offset = MT7986_ADIE1_MT7976C_OFFSET + adie_offset;
-+	mt7915_mcu_get_eeprom(dev, offset, read_buf);
-+	eeprom[MT7986_ADIE1_MT7976C_OFFSET] = read_buf[offset % MT7915_EEPROM_BLOCK_SIZE];
-+
-+	/* E3 re-binding */
-+	offset = MT7986_ADIE1_E3_OFFSET + adie_offset;
-+	mt7915_mcu_get_eeprom(dev, offset, read_buf);
-+	eeprom[MT7986_ADIE1_E3_OFFSET] = read_buf[offset % MT7915_EEPROM_BLOCK_SIZE];
-+}
-+
- int mt7915_eeprom_init(struct mt7915_dev *dev)
- {
- 	int ret;
-@@ -280,6 +306,8 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
- 			return ret;
- 	}
- 
-+	mt7915_eeprom_rebonding(dev);
-+
- 	ret = mt7915_eeprom_load_precal(dev);
- 	if (ret)
- 		return ret;
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index febe070..a3d7b4b 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -506,6 +506,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
- 
- int mt7915_register_device(struct mt7915_dev *dev);
- void mt7915_unregister_device(struct mt7915_dev *dev);
-+void mt7915_eeprom_rebonding(struct mt7915_dev *dev);
- int mt7915_eeprom_init(struct mt7915_dev *dev);
- void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
- 				struct mt7915_phy *phy);
--- 
-2.18.0
-
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
new file mode 100644
index 0000000..273176b
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/1023-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch
@@ -0,0 +1,268 @@
+From 671c3c630c861155a465df211772e12fb6f7d48a Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 30 Mar 2023 15:12:37 +0800
+Subject: [PATCH] wifi: mt76: mt7915: add cal free data merge support
+
+1. add basic cal free data support
+2. add E3 low yield rate workaround for panther E3 with 7976 adie
+3. add Harrier freq offset workaround
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7915/eeprom.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.c    |  13 ++--
+ mt7915/mt7915.h |   1 +
+ 3 files changed, 198 insertions(+), 4 deletions(-)
+
+diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
+index 5eb9f88..b96776d 100644
+--- a/mt7915/eeprom.c
++++ b/mt7915/eeprom.c
+@@ -271,6 +271,190 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 	dev->chainshift = hweight8(dev->mphy.chainmask);
+ }
+ 
++static int mt7915_apply_cal_free_data(struct mt7915_dev *dev)
++{
++#define MT_EE_CAL_FREE_MAX_SIZE		70
++#define MT_EE_FREQ_OFFSET		0x77
++#define MT_EE_ADIE1_MT7976C_OFFSET	0x270
++#define MT_EE_ADIE1_E3_OFFSET		0x271
++#define MT_EE_END_OFFSET		0xffff
++#define MT_EE_ADIE1_BASE_7896		0x1000
++	enum adie_type {
++		ADIE_7975,
++		ADIE_7976,
++	};
++	enum ddie_type {
++		DDIE_7915,
++		DDIE_7916,
++	};
++	static const u16 ddie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[DDIE_7915] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
++			       0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23, 0x24,
++			       0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
++			       0x52, 0x70, 0x71, 0x72, 0x76, 0xa8, 0xa9, 0xaa, 0xab, 0xac,
++			       0xad, 0xae, 0xaf, -1},
++		[DDIE_7916] = {0x30, 0x31, 0x34, 0x35, 0x36, 0x38, 0x3c, 0x3a, 0x3d, 0x44,
++			       0x46, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xe0, -1},
++	};
++	static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0x7cd, 0x7cf, 0x7d1, 0x7d3, 0x802, 0x803, 0x804, 0x805, 0x806,
++			       0x808, 0x80a, 0x80b, 0x80c, 0x80d, 0x80e, 0x810, 0x812, 0x813,
++			       0x814, 0x815, 0x816, 0x818, 0x81a, 0x81b, 0x81c, 0x81d, 0x81e,
++			       0x820, 0x822, 0x823, 0x824, 0x825, 0x826, 0x827, 0x828, 0x829,
++			       0x82f, 0x8c0, 0x8c1, 0x8c2, 0x8c3, 0x9a0, 0x8d0, 0x8d1, 0x8d7,
++			       0x8d8, 0x8fa, 0x9a1, 0x9a5, 0x9a6, 0x9a8, 0x9aa, 0x9b0, 0x9b1,
++			       0x9b2, 0x9b3, 0x9b4, 0x9b5, 0x9b6, 0x9b7, -1},
++		[ADIE_7976] = {0x24c, 0x24d, 0x24e, 0x24f, 0x250, 0x251, 0x253, 0x255, 0x257,
++			       0x259, 0x990, 0x991, 0x994, 0x995, 0x9a6, 0x9a8, 0x9aa, -1},
++	};
++	static const u16 eep_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
++		[ADIE_7975] = {0xe00, 0xe01, 0xe02, 0xe03, 0xe04, 0xe05, 0xe06, 0xe07, 0xe08,
++			       0xe09, 0xe0a, 0xe0b, 0xe0c, 0xe0d, 0x80e, 0xe0f, 0xe10, 0xe11,
++			       0xe12, 0xe13, 0xe14, 0xe15, 0xe16, 0xe17, 0xe18, 0xe19, 0xe1a,
++			       0xe1b, 0xe1c, 0xe1d, 0xe1e, 0xe1f, 0xe20, 0xe21, 0xe22, 0xe23,
++			       0xe24, 0xe25, 0xe26, 0xe27, 0xe28, 0xe29, 0xe2a, 0xe2b, 0xe2c,
++			       0xe2d, 0xe2e, 0xe2f, 0xe33, 0xe34, 0xe36, 0xe38, 0xe39, 0xe3a,
++			       0xe3b, 0xe3c, 0xe3d, 0xe3e, 0xe3f, 0xe40, -1},
++		[ADIE_7976] = {0x33c, 0x33d, 0x33e, 0x33f, 0x340, 0x341, 0x343, 0x345, 0x347,
++			       0x349, 0x359, 0x35a, 0x35d, 0x35e, 0x36a, 0x36c, 0x36e, -1},
++	};
++	static const u16 *ddie_offs;
++	static const u16 *adie_offs[__MT_MAX_BAND];
++	static const u16 *eep_offs[__MT_MAX_BAND];
++	static u16 adie_base[__MT_MAX_BAND] = {0};
++	u8 *eeprom = dev->mt76.eeprom.data;
++	u8 buf[MT7915_EEPROM_BLOCK_SIZE];
++	int adie_id, band, i, ret;
++
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7915:
++		ddie_offs = ddie_offs_list[DDIE_7915];
++		ret = mt7915_mcu_get_eeprom(dev, MT_EE_ADIE_FT_VERSION, buf);
++		if (ret)
++			return ret;
++		adie_id = buf[MT_EE_ADIE_FT_VERSION % MT7915_EEPROM_BLOCK_SIZE] - 1;
++		adie_offs[0] = adie_offs_list[ADIE_7975];
++		/* same as adie offset */
++		eep_offs[0] = NULL;
++		break;
++	case 0x7906:
++	case 0x7981:
++		if (is_mt7916(&dev->mt76))
++			ddie_offs = ddie_offs_list[DDIE_7916];
++		adie_offs[0] = adie_offs_list[ADIE_7976];
++		eep_offs[0] = NULL;
++		break;
++	case 0x7986:
++		adie_id = mt7915_check_adie(dev, true);
++		switch (adie_id) {
++		case MT7975_ONE_ADIE:
++		case MT7975_DUAL_ADIE:
++			adie_offs[0] = adie_offs_list[ADIE_7975];
++			eep_offs[0] = NULL;
++			if (adie_id == MT7975_DUAL_ADIE) {
++				adie_offs[1] = adie_offs_list[ADIE_7975];
++				eep_offs[1] = eep_offs_list[ADIE_7975];
++			}
++			break;
++		case MT7976_ONE_ADIE_DBDC:
++		case MT7976_ONE_ADIE:
++		case MT7976_DUAL_ADIE: {
++			u16 base = 0, offset = MT_EE_ADIE1_MT7976C_OFFSET;
++
++			adie_offs[0] = adie_offs_list[ADIE_7976];
++			eep_offs[0] = NULL;
++			if (adie_id == MT7976_DUAL_ADIE) {
++				adie_offs[1] = adie_offs_list[ADIE_7976];
++				eep_offs[1] = eep_offs_list[ADIE_7976];
++				base = MT_EE_ADIE1_BASE_7896;
++			}
++
++			/* E3 re-bonding workaround */
++			ret = mt7915_mcu_get_eeprom(dev, offset + base, buf);
++			if (ret)
++				break;
++			offset = (offset + base) % MT7915_EEPROM_BLOCK_SIZE;
++			eeprom[MT_EE_ADIE1_MT7976C_OFFSET] = buf[offset];
++			offset = (MT_EE_ADIE1_E3_OFFSET + base) % MT7915_EEPROM_BLOCK_SIZE;
++			eeprom[MT_EE_ADIE1_E3_OFFSET] = buf[offset];
++			break;
++		}
++		default:
++			return -EINVAL;
++		}
++		adie_base[1] = MT_EE_ADIE1_BASE_7896;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* ddie */
++	if (ddie_offs) {
++		u16 ddie_offset;
++		u32 block_num, prev_block_num = -1;
++
++		for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
++			ddie_offset = ddie_offs[i];
++			block_num = ddie_offset / MT7915_EEPROM_BLOCK_SIZE;
++
++			if (ddie_offset == MT_EE_END_OFFSET)
++				break;
++
++			if (prev_block_num != block_num) {
++				ret = mt7915_mcu_get_eeprom(dev, ddie_offset, buf);
++				if (ret) {
++					prev_block_num = -1;
++					continue;
++				}
++			}
++
++			eeprom[ddie_offset] = buf[ddie_offset % MT7915_EEPROM_BLOCK_SIZE];
++			prev_block_num = block_num;
++		}
++	}
++
++	/* adie */
++	for (band = 0; band < __MT_MAX_BAND; band++) {
++		u16 adie_offset, eep_offset;
++		u32 block_num, prev_block_num = -1;
++
++		if (!adie_offs[band])
++			continue;
++
++		for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
++			adie_offset = adie_offs[band][i] + adie_base[band];
++			eep_offset = adie_offset;
++			if (eep_offs[band])
++				eep_offset = eep_offs[band][i];
++			block_num = adie_offset / MT7915_EEPROM_BLOCK_SIZE;
++
++			if (adie_offs[band][i] == MT_EE_END_OFFSET)
++				break;
++
++			if (is_mt7915(&dev->mt76) && !adie_id &&
++			    adie_offset >= 0x8c0 && adie_offset <= 0x8c3)
++				continue;
++
++			if (prev_block_num != block_num) {
++				ret = mt7915_mcu_get_eeprom(dev, adie_offset, buf);
++				if (ret) {
++					prev_block_num = -1;
++					continue;
++				}
++			}
++
++			eeprom[eep_offset] = buf[adie_offset % MT7915_EEPROM_BLOCK_SIZE];
++			prev_block_num = block_num;
++
++			/* workaround for Harrier */
++			if (is_mt7915(&dev->mt76) && adie_offset == 0x9a1)
++				eeprom[MT_EE_FREQ_OFFSET] = eeprom[adie_offset];
++		}
++	}
++
++	return 0;
++}
++
+ int mt7915_eeprom_init(struct mt7915_dev *dev)
+ {
+ 	int ret;
+@@ -311,6 +495,10 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = mt7915_apply_cal_free_data(dev);
++	if (ret)
++		return ret;
++
+ 	mt7915_eeprom_parse_hw_cap(dev, &dev->phy);
+ 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
+ 	       ETH_ALEN);
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 7e33386..28e023d 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -2879,6 +2879,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
+ 	};
+ 	struct mt7915_mcu_eeprom_info *res;
+ 	struct sk_buff *skb;
++	bool valid;
+ 	int ret;
+ 	u8 *buf = read_buf;
+ 
+@@ -2889,10 +2890,14 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
+ 		return ret;
+ 
+ 	res = (struct mt7915_mcu_eeprom_info *)skb->data;
+-
+-	if (!buf)
+-		buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
+-	memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
++	valid = !!le32_to_cpu(res->valid);
++	if (valid) {
++		if (!buf)
++			buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
++		memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
++	} else {
++		ret = -EINVAL;
++	}
+ 
+ 	dev_kfree_skb(skb);
+ 
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 8730655..25a6815 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -507,6 +507,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+ 
+ int mt7915_register_device(struct mt7915_dev *dev);
+ void mt7915_unregister_device(struct mt7915_dev *dev);
++void mt7915_eeprom_rebonding(struct mt7915_dev *dev);
+ int mt7915_eeprom_init(struct mt7915_dev *dev);
+ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 				struct mt7915_phy *phy);
+-- 
+2.18.0
+