blob: 786d7e6ad37e665584c788b8a76e08715436fa90 [file] [log] [blame]
developer9237f442024-06-14 17:13:04 +08001From 1ed0aea054ae9fcd011f81333888d15cba7fc19f Mon Sep 17 00:00:00 2001
developer66e89bc2024-04-23 14:50:01 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Mon, 11 Mar 2024 10:43:03 +0800
developer9237f442024-06-14 17:13:04 +08004Subject: [PATCH 029/116] mtk: wifi: mt76: mt7996: refactor eeprom loading flow
developer66e89bc2024-04-23 14:50:01 +08005 for sku checking
6
7Add eeprom sku checking mechanism to avoid using the
8wrong eeprom in flash/binfile mode
9The fields listed below will be checked by comparing the loaded eeprom to the default bin
101. FEM type
112. MAC address (warning for using default MAC address)
123. RF path & streams
13 (to distinguish cases such as BE7200 4i5i, BE6500 3i5i, and BE5040 2i3i)
14
developer66e89bc2024-04-23 14:50:01 +080015Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
developer66e89bc2024-04-23 14:50:01 +080016
171. Reset eeprom content before loading efuse
18 eeprom array might contain incomplete data read from flash or
19 binfile, which is not overwritten since this block is invalid
20 in efuse.
212. Remove testmode default bin since it is unnecessary
22 Not used in logan. Directly load normal mode default bin is fine.
23 Also, this way is better since we don't need to put testmode default
24 eeprom for each sku (especially kite's sku) in our SDK.
253. Set testmode_en field for default bin mode for consistency sake
26
developer66e89bc2024-04-23 14:50:01 +080027Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
28
291.
30Fix efuse mode txpower = 0 issue
31This fix might be changed if fw supports efuse merge for buffer mode = EE_MODE_EFUSE
322.
33Add Eagle BE19000 ifem default bin, add Eagle default bin bootstrip
34
developer66e89bc2024-04-23 14:50:01 +080035Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
36---
37 mt7996/eeprom.c | 207 ++++++++++++++++++++++++-------------------
38 mt7996/eeprom.h | 32 +++++++
39 mt7996/mcu.c | 18 +---
40 mt7996/mt7996.h | 3 +-
41 mt7996/mtk_debugfs.c | 2 +-
42 5 files changed, 150 insertions(+), 112 deletions(-)
43
44diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
developer9237f442024-06-14 17:13:04 +080045index fe8b253..f97d76c 100644
developer66e89bc2024-04-23 14:50:01 +080046--- a/mt7996/eeprom.c
47+++ b/mt7996/eeprom.c
48@@ -50,54 +50,84 @@ const u32 dpd_6g_bw320_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw320);
49
50 static int mt7996_check_eeprom(struct mt7996_dev *dev)
51 {
52-#define FEM_INT 0
53-#define FEM_EXT 3
54 u8 *eeprom = dev->mt76.eeprom.data;
55- u8 i, fem[__MT_MAX_BAND], fem_type;
56 u16 val = get_unaligned_le16(eeprom);
57
58- for (i = 0; i < __MT_MAX_BAND; i++)
59- fem[i] = eeprom[MT_EE_WIFI_CONF + 6 + i] & MT_EE_WIFI_PA_LNA_CONFIG;
60-
61 switch (val) {
62 case 0x7990:
63 return is_mt7996(&dev->mt76) ? 0 : -EINVAL;
64 case 0x7992:
65- if (dev->fem_type == MT7996_FEM_UNSET)
66- return is_mt7992(&dev->mt76) ? 0 : -EINVAL;
67-
68- if (fem[0] == FEM_EXT && fem[1] == FEM_EXT)
69- fem_type = MT7996_FEM_EXT;
70- else if (fem[0] == FEM_INT && fem[1] == FEM_INT)
71- fem_type = MT7996_FEM_INT;
72- else if (fem[0] == FEM_INT && fem[1] == FEM_EXT)
73- fem_type = MT7996_FEM_MIX;
74- else
75- return -EINVAL;
76-
77- return (is_mt7992(&dev->mt76) ? 0 : -EINVAL) |
78- (dev->fem_type == fem_type ? 0 : -EINVAL);
79+ return is_mt7992(&dev->mt76) ? 0 : -EINVAL;
80 default:
81 return -EINVAL;
82 }
83 }
84
85-const char *mt7996_eeprom_name(struct mt7996_dev *dev)
86+static int mt7996_check_eeprom_sku(struct mt7996_dev *dev, const u8 *dflt)
87 {
88- if (dev->bin_file_mode)
89- return dev->mt76.bin_file_name;
90+#define FEM_INT 0
91+#define FEM_EXT 3
92+ u8 *eeprom = dev->mt76.eeprom.data;
93+ u8 i, fem[__MT_MAX_BAND], fem_type;
94+ u16 mac_addr[__MT_MAX_BAND] = {MT_EE_MAC_ADDR, MT_EE_MAC_ADDR2, MT_EE_MAC_ADDR3};
95+ int max_band = is_mt7996(&dev->mt76) ? __MT_MAX_BAND : 2;
96+
97+ if (dev->fem_type == MT7996_FEM_UNSET)
98+ return -EINVAL;
99+
100+ /* FEM type */
101+ for (i = 0; i < max_band; i++)
102+ fem[i] = eeprom[MT_EE_WIFI_CONF + 6 + i] & MT_EE_WIFI_PA_LNA_CONFIG;
103+
104+ if (fem[0] == FEM_EXT && fem[1] == FEM_EXT)
105+ fem_type = MT7996_FEM_EXT;
106+ else if (fem[0] == FEM_INT && fem[1] == FEM_INT)
107+ fem_type = MT7996_FEM_INT;
108+ else if (fem[0] == FEM_INT && fem[1] == FEM_EXT)
109+ fem_type = MT7996_FEM_MIX;
110+ else
111+ return -EINVAL;
112
113- if (dev->testmode_enable) {
114- if (is_mt7992(&dev->mt76))
115- return MT7992_EEPROM_DEFAULT_TM;
116- else
117- return MT7996_EEPROM_DEFAULT_TM;
118+ if (dev->fem_type != fem_type)
119+ return -EINVAL;
120+
121+ /* RF path & stream */
122+ for (i = 0; i < max_band; i++) {
123+ u8 path, rx_path, nss;
124+ u8 dflt_path, dflt_rx_path, dflt_nss;
125+
126+ /* MAC address */
127+ if (ether_addr_equal(eeprom + mac_addr[i], dflt + mac_addr[i]))
128+ dev_warn(dev->mt76.dev,
129+ "Currently using default MAC address for band %d\n", i);
130+
131+ mt7996_parse_eeprom_stream(eeprom, i, &path, &rx_path, &nss);
132+ mt7996_parse_eeprom_stream(dflt, i, &dflt_path, &dflt_rx_path, &dflt_nss);
133+ if (path > dflt_path || rx_path > dflt_rx_path || nss > dflt_nss) {
134+ dev_err(dev->mt76.dev,
135+ "Invalid path/stream configuration for band %d\n", i);
136+ return -EINVAL;
137+ } else if (path < dflt_path || rx_path < dflt_rx_path || nss < dflt_nss) {
138+ dev_warn(dev->mt76.dev,
139+ "Restricted path/stream configuration for band %d\n", i);
140+ dev_warn(dev->mt76.dev,
141+ "path: %u/%u, rx_path: %u/%u, nss: %u/%u\n",
142+ path, dflt_path, rx_path, dflt_rx_path, nss, dflt_nss);
143+ }
144 }
145
146+ return 0;
147+}
148+
149+const char *mt7996_eeprom_name(struct mt7996_dev *dev)
150+{
151 switch (mt76_chip(&dev->mt76)) {
152 case 0x7990:
153 if (dev->chip_sku == MT7996_SKU_404)
154 return MT7996_EEPROM_DEFAULT_404;
155+
156+ if (dev->fem_type == MT7996_FEM_INT)
157+ return MT7996_EEPROM_DEFAULT_INT;
158 return MT7996_EEPROM_DEFAULT;
159 case 0x7992:
160 if (dev->chip_sku == MT7992_SKU_23) {
161@@ -148,21 +178,18 @@ mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band)
162 }
163
164 static int
165-mt7996_eeprom_load_default(struct mt7996_dev *dev)
166+mt7996_eeprom_load_bin(struct mt7996_dev *dev)
167 {
168 u8 *eeprom = dev->mt76.eeprom.data;
169 const struct firmware *fw = NULL;
170 int ret;
171
172- ret = request_firmware(&fw, mt7996_eeprom_name(dev), dev->mt76.dev);
173+ ret = request_firmware(&fw, dev->mt76.bin_file_name, dev->mt76.dev);
174 if (ret)
175 return ret;
176
177 if (!fw || !fw->data) {
178- if (dev->bin_file_mode)
179- dev_err(dev->mt76.dev, "Invalid bin (bin file mode)\n");
180- else
181- dev_err(dev->mt76.dev, "Invalid default bin\n");
182+ dev_err(dev->mt76.dev, "Invalid bin %s\n", dev->mt76.bin_file_name);
183 ret = -EINVAL;
184 goto out;
185 }
186@@ -180,7 +207,7 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
187 {
188 int ret = 1;
189
190- /* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
191+ /* return > 0 for load success, return 0 for load failed, return < 0 for no memory */
192 dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
193 if (dev->bin_file_mode) {
194 dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
195@@ -189,15 +216,15 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
196 if (!dev->mt76.eeprom.data)
197 return -ENOMEM;
198
199- if (mt7996_eeprom_load_default(dev))
200- return 0;
201-
202- if (mt7996_check_eeprom(dev))
203+ if (mt7996_eeprom_load_bin(dev))
204 return 0;
205 } else {
206 ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
207 }
208
209+ if (mt7996_check_eeprom(dev))
210+ return 0;
211+
212 return ret;
213 }
214
215@@ -206,30 +233,30 @@ int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev)
216 u8 *eeprom;
217 int ret;
218
219+ dev->testmode_enable = testmode_enable;
220+
221 /* load eeprom in flash or bin file mode to determine fw mode */
222 ret = mt7996_eeprom_load_flash(dev);
223+ if (ret <= 0)
224+ goto out;
225
226- if (ret < 0)
227- return ret;
228-
229- if (ret) {
230- dev->flash_mode = true;
231- dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
232- eeprom = dev->mt76.eeprom.data;
233- /* testmode enable priority: eeprom field > module parameter */
234- dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
235- testmode_enable;
236- }
237+ dev->flash_mode = true;
238+ dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
239+ eeprom = dev->mt76.eeprom.data;
240+ /* testmode enable priority: eeprom field > module parameter */
241+ dev->testmode_enable = eeprom[MT_EE_TESTMODE_EN];
242
243+out:
244 return ret;
245 }
246
247 static int mt7996_eeprom_load(struct mt7996_dev *dev)
248 {
249+ const struct firmware *fw = NULL;
250 int ret;
251- u8 free_block_num;
252 u32 block_num, i;
253 u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
254+ u8 free_block_num, *eeprom = dev->mt76.eeprom.data;
255
256 /* flash or bin file mode eeprom is loaded before mcu init */
257 if (!dev->flash_mode) {
258@@ -239,19 +266,49 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
259
260 /* efuse info isn't enough */
261 if (free_block_num >= 59)
262- return -EINVAL;
263+ goto dflt;
264+
265+ memset(eeprom, 0, MT7996_EEPROM_SIZE);
266+ /* check if efuse contains valid eeprom data */
267+ if (mt7996_mcu_get_eeprom(dev, 0, NULL) ||
268+ mt7996_check_eeprom(dev))
269+ goto dflt;
270
271 /* read eeprom data from efuse */
272 block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
273- for (i = 0; i < block_num; i++) {
274+ for (i = 1; i < block_num; i++) {
275 ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size, NULL);
276 if (ret && ret != -EINVAL)
277- return ret;
278+ goto dflt;
279 }
280 dev->eeprom_mode = EFUSE_MODE;
281 }
282
283- return mt7996_check_eeprom(dev);
284+dflt:
285+ ret = request_firmware(&fw, mt7996_eeprom_name(dev), dev->mt76.dev);
286+ if (ret)
287+ return ret;
288+
289+ if (!fw || !fw->data) {
290+ dev_err(dev->mt76.dev, "Invalid default bin\n");
291+ ret = -EINVAL;
292+ goto out;
293+ }
294+
295+ if (dev->eeprom_mode && !mt7996_check_eeprom_sku(dev, fw->data)) {
296+ ret = 0;
297+ goto out;
298+ }
299+
300+ memcpy(eeprom, fw->data, MT7996_EEPROM_SIZE);
301+ dev->bin_file_mode = false;
302+ dev->flash_mode = true;
303+ dev->eeprom_mode = DEFAULT_BIN_MODE;
304+ eeprom[MT_EE_TESTMODE_EN] = dev->testmode_enable;
305+ dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
306+out:
307+ release_firmware(fw);
308+ return ret;
309 }
310
311 static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
312@@ -323,32 +380,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
313 int max_path = 5, max_nss = 4;
314 int ret;
315
316- switch (band_idx) {
317- case MT_BAND1:
318- path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
319- eeprom[MT_EE_WIFI_CONF + 2]);
320- rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
321- eeprom[MT_EE_WIFI_CONF + 3]);
322- nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
323- eeprom[MT_EE_WIFI_CONF + 5]);
324- break;
325- case MT_BAND2:
326- path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
327- eeprom[MT_EE_WIFI_CONF + 2]);
328- rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
329- eeprom[MT_EE_WIFI_CONF + 4]);
330- nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
331- eeprom[MT_EE_WIFI_CONF + 5]);
332- break;
333- default:
334- path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
335- eeprom[MT_EE_WIFI_CONF + 1]);
336- rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
337- eeprom[MT_EE_WIFI_CONF + 3]);
338- nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
339- eeprom[MT_EE_WIFI_CONF + 4]);
340- break;
341- }
342+ mt7996_parse_eeprom_stream(eeprom, band_idx, &path, &rx_path, &nss);
343
344 if (!path || path > max_path)
345 path = max_path;
346@@ -437,17 +469,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
347 return ret;
348
349 ret = mt7996_eeprom_load(dev);
350- if (ret < 0) {
351- if (ret != -EINVAL)
352- return ret;
353-
354- dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
355- dev->bin_file_mode = false;
356- dev->eeprom_mode = DEFAULT_BIN_MODE;
357- ret = mt7996_eeprom_load_default(dev);
358- if (ret)
359- return ret;
360- }
361+ if (ret)
362+ return ret;
363
364 ret = mt7996_eeprom_load_precal(dev);
365 if (ret)
366diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
developer9237f442024-06-14 17:13:04 +0800367index 8f0f87b..03a4fd0 100644
developer66e89bc2024-04-23 14:50:01 +0800368--- a/mt7996/eeprom.h
369+++ b/mt7996/eeprom.h
370@@ -132,6 +132,38 @@ mt7996_get_channel_group_6g(int channel)
371 return DIV_ROUND_UP(channel - 29, 32);
372 }
373
374+static inline void
375+mt7996_parse_eeprom_stream(const u8 *eep, int band_idx,
376+ u8 *path, u8 *rx_path, u8 *nss)
377+{
378+ switch (band_idx) {
379+ case MT_BAND1:
380+ *path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
381+ eep[MT_EE_WIFI_CONF + 2]);
382+ *rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
383+ eep[MT_EE_WIFI_CONF + 3]);
384+ *nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
385+ eep[MT_EE_WIFI_CONF + 5]);
386+ break;
387+ case MT_BAND2:
388+ *path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
389+ eep[MT_EE_WIFI_CONF + 2]);
390+ *rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
391+ eep[MT_EE_WIFI_CONF + 4]);
392+ *nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
393+ eep[MT_EE_WIFI_CONF + 5]);
394+ break;
395+ default:
396+ *path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
397+ eep[MT_EE_WIFI_CONF + 1]);
398+ *rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
399+ eep[MT_EE_WIFI_CONF + 3]);
400+ *nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
401+ eep[MT_EE_WIFI_CONF + 4]);
402+ break;
403+ }
404+}
405+
406 enum mt7996_sku_rate_group {
407 SKU_CCK,
408 SKU_OFDM,
409diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developer9237f442024-06-14 17:13:04 +0800410index a3b66f1..446fe1f 100644
developer66e89bc2024-04-23 14:50:01 +0800411--- a/mt7996/mcu.c
412+++ b/mt7996/mcu.c
413@@ -3507,7 +3507,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
414 &req, sizeof(req), true);
415 }
416
417-static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
418+int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)
419 {
420 #define MAX_PAGE_IDX_MASK GENMASK(7, 5)
421 #define PAGE_IDX_MASK GENMASK(4, 2)
422@@ -3552,22 +3552,6 @@ static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
423 return 0;
424 }
425
426-int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)
427-{
428- struct mt7996_mcu_eeprom req = {
429- .tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
430- .len = cpu_to_le16(sizeof(req) - 4),
431- .buffer_mode = EE_MODE_EFUSE,
432- .format = EE_FORMAT_WHOLE
433- };
434-
435- if (dev->flash_mode)
436- return mt7996_mcu_set_eeprom_flash(dev);
437-
438- return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(EFUSE_CTRL),
439- &req, sizeof(req), true);
440-}
441-
442 int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset, u8 *read_buf)
443 {
444 struct mt7996_mcu_eeprom_info req = {
445diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developer9237f442024-06-14 17:13:04 +0800446index fd93db2..b2a9381 100644
developer66e89bc2024-04-23 14:50:01 +0800447--- a/mt7996/mt7996.h
448+++ b/mt7996/mt7996.h
449@@ -54,15 +54,14 @@
450 #define MT7992_ROM_PATCH_23 "mediatek/mt7996/mt7992_rom_patch_23.bin"
451
452 #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
453+#define MT7996_EEPROM_DEFAULT_INT "mediatek/mt7996/mt7996_eeprom_2i5i6i.bin"
454 #define MT7996_EEPROM_DEFAULT_404 "mediatek/mt7996/mt7996_eeprom_dual_404.bin"
455-#define MT7996_EEPROM_DEFAULT_TM "mediatek/mt7996/mt7996_eeprom_tm.bin"
456 #define MT7992_EEPROM_DEFAULT "mediatek/mt7996/mt7992_eeprom_2i5i.bin"
457 #define MT7992_EEPROM_DEFAULT_EXT "mediatek/mt7996/mt7992_eeprom_2e5e.bin"
458 #define MT7992_EEPROM_DEFAULT_MIX "mediatek/mt7996/mt7992_eeprom_2i5e.bin"
459 #define MT7992_EEPROM_DEFAULT_24 "mediatek/mt7996/mt7992_eeprom_24_2i5i.bin"
460 #define MT7992_EEPROM_DEFAULT_23 "mediatek/mt7996/mt7992_eeprom_23_2i5i.bin"
461 #define MT7992_EEPROM_DEFAULT_23_EXT "mediatek/mt7996/mt7992_eeprom_23_2e5e.bin"
462-#define MT7992_EEPROM_DEFAULT_TM "mediatek/mt7996/mt7992_eeprom_tm.bin"
463 #define MT7996_EEPROM_SIZE 7680
464 #define MT7996_EEPROM_BLOCK_SIZE 16
465 #define MT7996_TOKEN_SIZE 16384
466diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
developer9237f442024-06-14 17:13:04 +0800467index 2499f12..2a9f213 100644
developer66e89bc2024-04-23 14:50:01 +0800468--- a/mt7996/mtk_debugfs.c
469+++ b/mt7996/mtk_debugfs.c
470@@ -2827,7 +2827,7 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
471 seq_printf(s, " flash mode\n");
472 break;
473 case BIN_FILE_MODE:
474- seq_printf(s, " bin file mode\n filename = %s\n", mt7996_eeprom_name(dev));
475+ seq_printf(s, " bin file mode\n filename = %s\n", dev->mt76.bin_file_name);
476 break;
477 default:
478 break;
479--
developer9237f442024-06-14 17:13:04 +08004802.18.0
developer66e89bc2024-04-23 14:50:01 +0800481