blob: 5ae752aba886d1868bd6c5c8e237bbfa6e19333d [file] [log] [blame]
developer617abbd2024-04-23 14:50:01 +08001From 83c7e6d692657d514891430ad530df1337b90799 Mon Sep 17 00:00:00 2001
2From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Fri, 31 Mar 2023 11:36:34 +0800
4Subject: [PATCH 027/116] mtk: wifi: mt76: mt7996: add binfile mode support
5
6Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
7Change-Id: I06369a46f75c0707d9ababd8ade70d79a89b1a1c
8
9Fix binfile cannot sync precal data to atenl
10Binfile is viewed as efuse mode in atenl, so atenl does not allocate
11precal memory for its eeprom file
12Use mtd offset == 0xFFFFFFFF to determine whether it is binfile or flash mode
13Add support for loading precal in binfile mode
14
15Align upstream
16
17CR-Id: WCNCR00274293
18Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
19Change-Id: I4c8fd2b0a9956d2ee961b70cd28973e2e9410aca
20---
21 eeprom.c | 25 +++++++++++
22 mt76.h | 3 ++
23 mt7996/eeprom.c | 103 ++++++++++++++++++++++++++++++++++++++++---
24 mt7996/eeprom.h | 7 +++
25 mt7996/mt7996.h | 4 ++
26 mt7996/mtk_debugfs.c | 41 +++++++++++++++++
27 testmode.h | 2 +-
28 7 files changed, 179 insertions(+), 6 deletions(-)
29
30diff --git a/eeprom.c b/eeprom.c
31index 11efe2937..3da94926e 100644
32--- a/eeprom.c
33+++ b/eeprom.c
34@@ -161,6 +161,31 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
35 return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
36 }
37
38+bool mt76_check_bin_file_mode(struct mt76_dev *dev)
39+{
40+ struct device_node *np = dev->dev->of_node;
41+ const char *bin_file_name = NULL;
42+
43+ if (!np)
44+ return false;
45+
46+ of_property_read_string(np, "bin_file_name", &bin_file_name);
47+
48+ dev->bin_file_name = bin_file_name;
49+ if (dev->bin_file_name) {
50+ dev_info(dev->dev, "Using bin file %s\n", dev->bin_file_name);
51+#ifdef CONFIG_NL80211_TESTMODE
52+ dev->test_mtd.name = devm_kstrdup(dev->dev, bin_file_name, GFP_KERNEL);
53+ dev->test_mtd.offset = -1;
54+#endif
55+ }
56+
57+ of_node_put(np);
58+
59+ return dev->bin_file_name ? true : false;
60+}
61+EXPORT_SYMBOL_GPL(mt76_check_bin_file_mode);
62+
63 void
64 mt76_eeprom_override(struct mt76_phy *phy)
65 {
66diff --git a/mt76.h b/mt76.h
67index 20fdd050a..0b6d8b84e 100644
68--- a/mt76.h
69+++ b/mt76.h
70@@ -954,6 +954,8 @@ struct mt76_dev {
71 struct mt76_usb usb;
72 struct mt76_sdio sdio;
73 };
74+
75+ const char *bin_file_name;
76 };
77
78 /* per-phy stats. */
79@@ -1225,6 +1227,7 @@ void mt76_eeprom_override(struct mt76_phy *phy);
80 int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
81 int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
82 const char *cell_name, int len);
83+bool mt76_check_bin_file_mode(struct mt76_dev *dev);
84
85 struct mt76_queue *
86 mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
87diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
88index 6ac992a81..fe8b25352 100644
89--- a/mt7996/eeprom.c
90+++ b/mt7996/eeprom.c
91@@ -82,10 +82,17 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
92 }
93 }
94
95-static char *mt7996_eeprom_name(struct mt7996_dev *dev)
96+const char *mt7996_eeprom_name(struct mt7996_dev *dev)
97 {
98- if (dev->testmode_enable)
99- return MT7996_EEPROM_DEFAULT_TM;
100+ if (dev->bin_file_mode)
101+ return dev->mt76.bin_file_name;
102+
103+ if (dev->testmode_enable) {
104+ if (is_mt7992(&dev->mt76))
105+ return MT7992_EEPROM_DEFAULT_TM;
106+ else
107+ return MT7996_EEPROM_DEFAULT_TM;
108+ }
109
110 switch (mt76_chip(&dev->mt76)) {
111 case 0x7990:
112@@ -152,7 +159,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
113 return ret;
114
115 if (!fw || !fw->data) {
116- dev_err(dev->mt76.dev, "Invalid default bin\n");
117+ if (dev->bin_file_mode)
118+ dev_err(dev->mt76.dev, "Invalid bin (bin file mode)\n");
119+ else
120+ dev_err(dev->mt76.dev, "Invalid default bin\n");
121 ret = -EINVAL;
122 goto out;
123 }
124@@ -166,18 +176,45 @@ out:
125 return ret;
126 }
127
128+static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
129+{
130+ int ret = 1;
131+
132+ /* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
133+ dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
134+ if (dev->bin_file_mode) {
135+ dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
136+ dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
137+ GFP_KERNEL);
138+ if (!dev->mt76.eeprom.data)
139+ return -ENOMEM;
140+
141+ if (mt7996_eeprom_load_default(dev))
142+ return 0;
143+
144+ if (mt7996_check_eeprom(dev))
145+ return 0;
146+ } else {
147+ ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
148+ }
149+
150+ return ret;
151+}
152+
153 int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev)
154 {
155 u8 *eeprom;
156 int ret;
157
158 /* load eeprom in flash or bin file mode to determine fw mode */
159- ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
160+ ret = mt7996_eeprom_load_flash(dev);
161+
162 if (ret < 0)
163 return ret;
164
165 if (ret) {
166 dev->flash_mode = true;
167+ dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
168 eeprom = dev->mt76.eeprom.data;
169 /* testmode enable priority: eeprom field > module parameter */
170 dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
171@@ -211,6 +248,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
172 if (ret && ret != -EINVAL)
173 return ret;
174 }
175+ dev->eeprom_mode = EFUSE_MODE;
176 }
177
178 return mt7996_check_eeprom(dev);
179@@ -337,6 +375,59 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
180 return mt7996_eeprom_parse_band_config(phy);
181 }
182
183+static int
184+mt7996_eeprom_load_precal_binfile(struct mt7996_dev *dev, u32 offs, u32 size)
185+{
186+ const struct firmware *fw = NULL;
187+ int ret;
188+
189+ ret = request_firmware(&fw, dev->mt76.bin_file_name, dev->mt76.dev);
190+ if (ret)
191+ return ret;
192+
193+ if (!fw || !fw->data) {
194+ dev_err(dev->mt76.dev, "Invalid bin (bin file mode), load precal fail\n");
195+ ret = -EINVAL;
196+ goto out;
197+ }
198+
199+ memcpy(dev->cal, fw->data + offs, size);
200+
201+out:
202+ release_firmware(fw);
203+
204+ return ret;
205+}
206+
207+static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
208+{
209+ struct mt76_dev *mdev = &dev->mt76;
210+ u8 *eeprom = mdev->eeprom.data;
211+ u32 offs = MT_EE_DO_PRE_CAL;
212+ u32 size, val = eeprom[offs];
213+ int ret;
214+
215+ mt7996_eeprom_init_precal(dev);
216+
217+ if (!dev->flash_mode || !val)
218+ return 0;
219+
220+ size = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
221+
222+ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
223+ if (!dev->cal)
224+ return -ENOMEM;
225+
226+ if (dev->bin_file_mode)
227+ return mt7996_eeprom_load_precal_binfile(dev, MT_EE_PRECAL, size);
228+
229+ ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
230+ if (!ret)
231+ return ret;
232+
233+ return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
234+}
235+
236 int mt7996_eeprom_init(struct mt7996_dev *dev)
237 {
238 int ret;
239@@ -351,6 +442,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
240 return ret;
241
242 dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
243+ dev->bin_file_mode = false;
244+ dev->eeprom_mode = DEFAULT_BIN_MODE;
245 ret = mt7996_eeprom_load_default(dev);
246 if (ret)
247 return ret;
248diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
249index b19ff068e..8f0f87b6b 100644
250--- a/mt7996/eeprom.h
251+++ b/mt7996/eeprom.h
252@@ -102,6 +102,13 @@ enum mt7996_eeprom_band {
253 MT_EE_BAND_SEL_6GHZ,
254 };
255
256+enum mt7915_eeprom_mode {
257+ DEFAULT_BIN_MODE,
258+ EFUSE_MODE,
259+ FLASH_MODE,
260+ BIN_FILE_MODE,
261+};
262+
263 static inline int
264 mt7996_get_channel_group_5g(int channel)
265 {
266diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
267index 6ab45cc7e..9d6e85c1d 100644
268--- a/mt7996/mt7996.h
269+++ b/mt7996/mt7996.h
270@@ -62,6 +62,7 @@
271 #define MT7992_EEPROM_DEFAULT_24 "mediatek/mt7996/mt7992_eeprom_24_2i5i.bin"
272 #define MT7992_EEPROM_DEFAULT_23 "mediatek/mt7996/mt7992_eeprom_23_2i5i.bin"
273 #define MT7992_EEPROM_DEFAULT_23_EXT "mediatek/mt7996/mt7992_eeprom_23_2e5e.bin"
274+#define MT7992_EEPROM_DEFAULT_TM "mediatek/mt7996/mt7992_eeprom_tm.bin"
275 #define MT7996_EEPROM_SIZE 7680
276 #define MT7996_EEPROM_BLOCK_SIZE 16
277 #define MT7996_TOKEN_SIZE 16384
278@@ -395,6 +396,8 @@ struct mt7996_dev {
279 } wed_rro;
280
281 bool testmode_enable;
282+ bool bin_file_mode;
283+ u8 eeprom_mode;
284
285 bool ibf;
286 u8 fw_debug_wm;
287@@ -523,6 +526,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
288 u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
289 int mt7996_register_device(struct mt7996_dev *dev);
290 void mt7996_unregister_device(struct mt7996_dev *dev);
291+const char *mt7996_eeprom_name(struct mt7996_dev *dev);
292 int mt7996_eeprom_init(struct mt7996_dev *dev);
293 int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev);
294 int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
295diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
296index 48209668c..3ecce1329 100644
297--- a/mt7996/mtk_debugfs.c
298+++ b/mt7996/mtk_debugfs.c
299@@ -2798,6 +2798,44 @@ static const struct file_operations mt7996_txpower_path_fops = {
300 .llseek = default_llseek,
301 };
302
303+static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
304+{
305+ struct mt7996_dev *dev = dev_get_drvdata(s->private);
306+ struct mt76_dev *mdev = &dev->mt76;
307+#ifdef CONFIG_NL80211_TESTMODE
308+ const char *mtd_name = mdev->test_mtd.name;
309+ u32 mtd_offset = mdev->test_mtd.offset;
310+#else
311+ const char *mtd_name = NULL;
312+ u32 mtd_offset;
313+#endif
314+
315+ seq_printf(s, "Current eeprom mode:\n");
316+
317+ switch (dev->eeprom_mode) {
318+ case DEFAULT_BIN_MODE:
319+ seq_printf(s, " default bin mode\n filename = %s\n", mt7996_eeprom_name(dev));
320+ break;
321+ case EFUSE_MODE:
322+ seq_printf(s, " efuse mode\n");
323+ break;
324+ case FLASH_MODE:
325+ if (mtd_name)
326+ seq_printf(s, " flash mode\n mtd name = %s\n flash offset = 0x%x\n",
327+ mtd_name, mtd_offset);
328+ else
329+ seq_printf(s, " flash mode\n");
330+ break;
331+ case BIN_FILE_MODE:
332+ seq_printf(s, " bin file mode\n filename = %s\n", mt7996_eeprom_name(dev));
333+ break;
334+ default:
335+ break;
336+ }
337+
338+ return 0;
339+}
340+
341 int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
342 {
343 struct mt7996_dev *dev = phy->dev;
344@@ -2866,6 +2904,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
345 debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
346 debugfs_create_file("txpower_path", 0600, dir, phy, &mt7996_txpower_path_fops);
347
348+ debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
349+ mt7996_show_eeprom_mode);
350+
351 debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
352 mt7996_wtbl_read);
353
354diff --git a/testmode.h b/testmode.h
355index d6601cdcf..5d677f8c1 100644
356--- a/testmode.h
357+++ b/testmode.h
358@@ -16,7 +16,7 @@
359 * @MT76_TM_ATTR_RESET: reset parameters to default (flag)
360 * @MT76_TM_ATTR_STATE: test state (u32), see &enum mt76_testmode_state
361 *
362- * @MT76_TM_ATTR_MTD_PART: mtd partition used for eeprom data (string)
363+ * @MT76_TM_ATTR_MTD_PART: mtd partition or binfile used for eeprom data (string)
364 * @MT76_TM_ATTR_MTD_OFFSET: offset of eeprom data within the partition (u32)
365 * @MT76_TM_ATTR_BAND_IDX: band idx of the chip (u8)
366 *
367--
3682.39.2
369