blob: 44039099cb829294cd105b6eadfa85f596ad4601 [file] [log] [blame]
developer9237f442024-06-14 17:13:04 +08001From 571a367ee2ab7e447b7126bb05f778ec4ffdb3d0 Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Fri, 24 Nov 2023 09:49:08 +0800
developer9237f442024-06-14 17:13:04 +08004Subject: [PATCH 051/116] mtk: wifi: mt76: mt7996: add adie efuse merge support
developer66e89bc2024-04-23 14:50:01 +08005
6Merge adie-dependent parameters in efuse into eeprom after FT.
7Note that Eagle BE14000 is not considered yet.
8Add efuse dump command.
9
developer66e89bc2024-04-23 14:50:01 +080010Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
developer66e89bc2024-04-23 14:50:01 +080011---
12 mt7996/debugfs.c | 41 +++++++++++++
13 mt7996/eeprom.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++
14 mt7996/mcu.c | 6 +-
15 mt7996/testmode.c | 8 ++-
16 4 files changed, 195 insertions(+), 4 deletions(-)
17
18diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
developer9237f442024-06-14 17:13:04 +080019index 3074202..f3a520b 100644
developer66e89bc2024-04-23 14:50:01 +080020--- a/mt7996/debugfs.c
21+++ b/mt7996/debugfs.c
22@@ -894,6 +894,46 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_muru_disable,
23 mt7996_fw_debug_muru_disable_get,
24 mt7996_fw_debug_muru_disable_set, "%lld\n");
25
26+static ssize_t
27+mt7996_efuse_get(struct file *file, char __user *user_buf,
28+ size_t count, loff_t *ppos)
29+{
30+ struct mt7996_dev *dev = file->private_data;
31+ struct mt76_dev *mdev = &dev->mt76;
32+ u8 *buff = mdev->otp.data;
33+ int i;
34+ ssize_t ret;
35+ u32 block_num;
36+
37+ mdev->otp.size = MT7996_EEPROM_SIZE;
38+ if (is_mt7996(&dev->mt76) && dev->chip_sku == MT7996_SKU_444)
39+ mdev->otp.size += 3 * MT_EE_CAL_UNIT;
40+
41+ if (!mdev->otp.data) {
42+ mdev->otp.data = devm_kzalloc(mdev->dev, mdev->otp.size, GFP_KERNEL);
43+ if (!mdev->otp.data)
44+ return -ENOMEM;
45+
46+ block_num = DIV_ROUND_UP(mdev->otp.size, MT7996_EEPROM_BLOCK_SIZE);
47+ for (i = 0; i < block_num; i++) {
48+ buff = mdev->otp.data + i * MT7996_EEPROM_BLOCK_SIZE;
49+ ret = mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE, buff);
50+ if (ret && ret != -EINVAL)
51+ return ret;
52+ }
53+ }
54+
55+ ret = simple_read_from_buffer(user_buf, count, ppos, mdev->otp.data, mdev->otp.size);
56+
57+ return ret;
58+}
59+
60+static const struct file_operations mt7996_efuse_ops = {
61+ .read = mt7996_efuse_get,
62+ .open = simple_open,
63+ .llseek = default_llseek,
64+};
65+
66 int mt7996_init_debugfs(struct mt7996_phy *phy)
67 {
68 struct mt7996_dev *dev = phy->dev;
69@@ -920,6 +960,7 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
70 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
71 mt7996_twt_stats);
72 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
73+ debugfs_create_file("otp", 0400, dir, dev, &mt7996_efuse_ops);
74
75 if (phy->mt76->cap.has_5ghz) {
76 debugfs_create_u32("dfs_hw_pattern", 0400, dir,
77diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
developer9237f442024-06-14 17:13:04 +080078index 215d81e..3cdd585 100644
developer66e89bc2024-04-23 14:50:01 +080079--- a/mt7996/eeprom.c
80+++ b/mt7996/eeprom.c
81@@ -496,6 +496,146 @@ static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
82 return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
83 }
84
85+static int mt7996_apply_cal_free_data(struct mt7996_dev *dev)
86+{
87+#define MT_EE_CAL_FREE_MAX_SIZE 30
88+#define MT_EE_7977BN_OFFSET (0x1200 - 0x500)
89+#define MT_EE_END_OFFSET 0xffff
90+ enum adie_type {
91+ ADIE_7975,
92+ ADIE_7976,
93+ ADIE_7977,
94+ ADIE_7978,
95+ ADIE_7979,
96+ };
97+ static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
98+ [ADIE_7975] = {0x5cd, 0x5cf, 0x5d1, 0x5d3, 0x6c0, 0x6c1, 0x6c2, 0x6c3,
99+ 0x7a1, 0x7a6, 0x7a8, 0x7aa, -1},
100+ [ADIE_7976] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
101+ 0x70, 0x71, 0x790, 0x791, 0x794, 0x795, 0x7a6, 0x7a8, 0x7aa, -1},
102+ [ADIE_7977] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
103+ 0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, -1},
104+ [ADIE_7978] = {0x91, 0x95, 0x100, 0x102, 0x104, 0x106, 0x107,
105+ 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0x10e, 0x110, -1},
106+ [ADIE_7979] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59,
107+ 0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7e, 0x80, -1},
108+ };
109+ static const u16 eep_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
110+ [ADIE_7975] = {0x451, 0x453, 0x455, 0x457, 0x44c, 0x44d, 0x44e, 0x44f,
111+ 0xba1, 0xba6, 0xba8, 0xbaa, -1},
112+ [ADIE_7976] = {0x44c, 0x44d, 0x44e, 0x44f, 0x450,
113+ 0x451, 0x453, 0x455, 0x457, 0x459,
114+ 0x470, 0x471, 0xb90, 0xb91, 0xb94, 0xb95,
115+ 0xba6, 0xba8, 0xbaa, -1},
116+ [ADIE_7977] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250,
117+ 0x1251, 0x1253, 0x1255, 0x1257, 0x1259,
118+ 0x1269, 0x126a, 0x127a, 0x127b, 0x127c, 0x127d, 0x127e, -1},
119+ [ADIE_7978] = {0xb91, 0xb95, 0x480, 0x482, 0x484, 0x486, 0x487, 0x488, 0x489,
120+ 0x48a, 0x48b, 0x48c, 0x48e, 0x490, -1},
121+ [ADIE_7979] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250, 0x1251,
122+ 0x1253, 0x1255, 0x1257, 0x1259, 0x1269, 0x126a,
123+ 0x127a, 0x127b, 0x127c, 0x127e, 0x1280, -1},
124+ };
125+ static const u16 adie_base_7996[] = {
126+ 0x400, 0x1e00, 0x1200
127+ };
128+ static const u16 adie_base_7992[] = {
129+ 0x400, 0x1200, 0x0
130+ };
131+ static const u16 *adie_offs[__MT_MAX_BAND];
132+ static const u16 *eep_offs[__MT_MAX_BAND];
133+ static const u16 *adie_base;
134+ u8 *eeprom = dev->mt76.eeprom.data;
135+ u8 buf[MT7996_EEPROM_BLOCK_SIZE];
136+ int adie_id, band, i, ret;
137+
138+ switch (mt76_chip(&dev->mt76)) {
139+ case 0x7990:
140+ adie_base = adie_base_7996;
141+ /* adie 0 */
142+ if (dev->fem_type == MT7996_FEM_INT)
143+ adie_id = ADIE_7975;
144+ else
145+ adie_id = ADIE_7976;
146+ adie_offs[0] = adie_offs_list[adie_id];
147+ eep_offs[0] = eep_offs_list[adie_id];
148+
149+ /* adie 1 */
150+ if (dev->chip_sku != MT7996_SKU_404) {
151+ adie_offs[1] = adie_offs_list[ADIE_7977];
152+ eep_offs[1] = eep_offs_list[ADIE_7977];
153+ }
154+
155+ /* adie 2 */
156+ adie_offs[2] = adie_offs_list[ADIE_7977];
157+ eep_offs[2] = eep_offs_list[ADIE_7977];
158+ break;
159+ case 0x7992:
160+ adie_base = adie_base_7992;
161+ /* adie 0 */
162+ if (dev->chip_sku == MT7992_SKU_44 &&
163+ dev->fem_type != MT7996_FEM_EXT)
164+ adie_id = ADIE_7975;
165+ else if (dev->chip_sku == MT7992_SKU_24)
166+ adie_id = ADIE_7978;
167+ else
168+ adie_id = ADIE_7976;
169+ adie_offs[0] = adie_offs_list[adie_id];
170+ eep_offs[0] = eep_offs_list[adie_id];
171+
172+ /* adie 1 */
173+ if (dev->chip_sku == MT7992_SKU_44 &&
174+ dev->fem_type != MT7996_FEM_INT)
175+ adie_id = ADIE_7977;
176+ else if (dev->chip_sku != MT7992_SKU_23)
177+ adie_id = ADIE_7979;
178+ else
179+ break;
180+ adie_offs[1] = adie_offs_list[adie_id];
181+ eep_offs[1] = eep_offs_list[adie_id];
182+ break;
183+ default:
184+ return -EINVAL;
185+ }
186+
187+ for (band = 0; band < __MT_MAX_BAND; band++) {
188+ u16 adie_offset, eep_offset;
189+ u32 block_num, prev_block_num = -1;
190+
191+ if (!adie_offs[band])
192+ continue;
193+
194+ for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) {
195+ adie_offset = adie_offs[band][i] + adie_base[band];
196+ eep_offset = eep_offs[band][i];
197+ block_num = adie_offset / MT7996_EEPROM_BLOCK_SIZE;
198+
199+ if (adie_offs[band][i] == MT_EE_END_OFFSET)
200+ break;
201+
202+ if (is_mt7996(&dev->mt76) && dev->chip_sku == MT7996_SKU_444 &&
203+ band == MT_BAND1)
204+ eep_offset -= MT_EE_7977BN_OFFSET;
205+
206+ if (prev_block_num != block_num) {
207+ ret = mt7996_mcu_get_eeprom(dev, adie_offset, buf);
208+ if (ret) {
209+ if (ret != -EINVAL)
210+ return ret;
211+
212+ prev_block_num = -1;
213+ continue;
214+ }
215+ }
216+
217+ eeprom[eep_offset] = buf[adie_offset % MT7996_EEPROM_BLOCK_SIZE];
218+ prev_block_num = block_num;
219+ }
220+ }
221+
222+ return 0;
223+}
224+
225 int mt7996_eeprom_init(struct mt7996_dev *dev)
226 {
227 int ret;
228@@ -512,6 +652,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
229 if (ret)
230 return ret;
231
232+ ret = mt7996_apply_cal_free_data(dev);
233+ if (ret)
234+ return ret;
235+
236 ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy);
237 if (ret < 0)
238 return ret;
239diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer9237f442024-06-14 17:13:04 +0800240index b5c6638..1a904e4 100644
developer66e89bc2024-04-23 14:50:01 +0800241--- a/mt7996/mcu.c
242+++ b/mt7996/mcu.c
243@@ -3606,7 +3606,7 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
244 };
245 struct sk_buff *skb;
246 bool valid;
247- int ret;
248+ int ret = 0;
249 u8 *buf = read_buf;
250
251 ret = mt76_mcu_send_and_get_msg(&dev->mt76,
252@@ -3624,11 +3624,13 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
253
254 skb_pull(skb, 48);
255 memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);
256+ } else {
257+ ret = -EINVAL;
258 }
259
260 dev_kfree_skb(skb);
261
262- return 0;
263+ return ret;
264 }
265
266 int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
267diff --git a/mt7996/testmode.c b/mt7996/testmode.c
developer9237f442024-06-14 17:13:04 +0800268index 9fa4edc..784a8be 100644
developer66e89bc2024-04-23 14:50:01 +0800269--- a/mt7996/testmode.c
270+++ b/mt7996/testmode.c
271@@ -2116,8 +2116,12 @@ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
272 memcpy(req.data, eeprom + i, MT76_TM_EEPROM_BLOCK_SIZE);
273
274 ret = mt7996_mcu_get_eeprom(dev, i, read_buf);
275- if (ret < 0)
276- return ret;
277+ if (ret) {
278+ if (ret != -EINVAL)
279+ return ret;
280+
281+ memset(read_buf, 0, MT76_TM_EEPROM_BLOCK_SIZE);
282+ }
283
284 if (!memcmp(req.data, read_buf, MT76_TM_EEPROM_BLOCK_SIZE))
285 continue;
286--
developer9237f442024-06-14 17:13:04 +08002872.18.0
developer66e89bc2024-04-23 14:50:01 +0800288