blob: b3a652a383c6486ca5e4a56fd51f40ab1ccb2bea [file] [log] [blame]
developer3abe1ad2022-01-24 11:13:32 +08001#define _GNU_SOURCE
2#include <fcntl.h>
3#include <sys/mman.h>
4#include <sys/stat.h>
5#include <sys/wait.h>
6
7#include "atenl.h"
8
developer11f4a0b2023-03-31 17:43:25 +08009#define EEPROM_PART_SIZE 0xFF000
developera6267142022-01-26 20:50:22 +080010char *eeprom_file;
developer3abe1ad2022-01-24 11:13:32 +080011
developer82af5012022-11-01 11:15:32 +080012static int
13atenl_create_file(struct atenl *an, bool flash_mode)
developer3abe1ad2022-01-24 11:13:32 +080014{
developer82af5012022-11-01 11:15:32 +080015 char fname[64], buf[1024];
16 ssize_t w, len, max_len, total_len = 0;
17 int fd_ori, fd, ret;
developer3abe1ad2022-01-24 11:13:32 +080018
developer82af5012022-11-01 11:15:32 +080019 /* reserve space for pre-cal data in flash mode */
20 if (flash_mode) {
developer2533bb32023-10-27 19:57:13 +080021 atenl_dbg("%s: init eeprom with flash / binfile mode\n", __func__);
developer82af5012022-11-01 11:15:32 +080022 max_len = EEPROM_PART_SIZE;
23 } else {
developer2533bb32023-10-27 19:57:13 +080024 atenl_dbg("%s: init eeprom with efuse / default bin mode\n", __func__);
developerf90c9af2022-12-28 22:40:23 +080025 max_len = 0x1e00;
developer3abe1ad2022-01-24 11:13:32 +080026 }
developer3abe1ad2022-01-24 11:13:32 +080027
developer82af5012022-11-01 11:15:32 +080028 snprintf(fname, sizeof(fname),
29 "/sys/kernel/debug/ieee80211/phy%d/mt76/eeprom",
developere0111812024-06-03 16:24:42 +080030 an->main_phy_idx);
developer82af5012022-11-01 11:15:32 +080031 fd_ori = open(fname, O_RDONLY);
32 if (fd_ori < 0)
developer3abe1ad2022-01-24 11:13:32 +080033 return -1;
developer3abe1ad2022-01-24 11:13:32 +080034
developera6267142022-01-26 20:50:22 +080035 fd = open(eeprom_file, O_RDWR | O_CREAT | O_EXCL, 00644);
developer3abe1ad2022-01-24 11:13:32 +080036 if (fd < 0)
37 goto out;
38
developer82af5012022-11-01 11:15:32 +080039 while ((len = read(fd_ori, buf, sizeof(buf))) > 0) {
developer3abe1ad2022-01-24 11:13:32 +080040retry:
41 w = write(fd, buf, len);
developer5698c9c2022-05-30 16:40:23 +080042 if (w > 0) {
developer82af5012022-11-01 11:15:32 +080043 total_len += len;
developer3abe1ad2022-01-24 11:13:32 +080044 continue;
developer5698c9c2022-05-30 16:40:23 +080045 }
developer3abe1ad2022-01-24 11:13:32 +080046
47 if (errno == EINTR)
48 goto retry;
49
50 perror("write");
developera6267142022-01-26 20:50:22 +080051 unlink(eeprom_file);
developer3abe1ad2022-01-24 11:13:32 +080052 close(fd);
53 fd = -1;
54 goto out;
55 }
56
developer82af5012022-11-01 11:15:32 +080057 /* reserve space for pre-cal data in flash mode */
58 len = sizeof(buf);
59 memset(buf, 0, len);
60 while (total_len < max_len) {
developer3abe1ad2022-01-24 11:13:32 +080061 w = write(fd, buf, len);
developer3abe1ad2022-01-24 11:13:32 +080062
developer82af5012022-11-01 11:15:32 +080063 if (w > 0) {
64 total_len += len;
65 continue;
66 }
developer3abe1ad2022-01-24 11:13:32 +080067
developer82af5012022-11-01 11:15:32 +080068 if (errno != EINTR) {
69 perror("write");
70 unlink(eeprom_file);
71 close(fd);
72 fd = -1;
73 goto out;
74 }
developer3abe1ad2022-01-24 11:13:32 +080075 }
76
developer82af5012022-11-01 11:15:32 +080077
developer3abe1ad2022-01-24 11:13:32 +080078 ret = lseek(fd, 0, SEEK_SET);
79 if (ret) {
80 close(fd_ori);
81 close(fd);
82 return ret;
83 }
84
85out:
86 close(fd_ori);
87 return fd;
88}
89
90static bool
91atenl_eeprom_file_exists(void)
92{
93 struct stat st;
94
developera6267142022-01-26 20:50:22 +080095 return stat(eeprom_file, &st) == 0;
developer3abe1ad2022-01-24 11:13:32 +080096}
97
98static int
99atenl_eeprom_init_file(struct atenl *an, bool flash_mode)
100{
101 int fd;
102
developer82af5012022-11-01 11:15:32 +0800103 if (!atenl_eeprom_file_exists())
104 return atenl_create_file(an, flash_mode);
developer3abe1ad2022-01-24 11:13:32 +0800105
developera6267142022-01-26 20:50:22 +0800106 fd = open(eeprom_file, O_RDWR);
developer3abe1ad2022-01-24 11:13:32 +0800107 if (fd < 0)
108 perror("open");
109
developer3abe1ad2022-01-24 11:13:32 +0800110 return fd;
111}
112
113static void
developer5698c9c2022-05-30 16:40:23 +0800114atenl_eeprom_init_chip_id(struct atenl *an)
115{
116 an->chip_id = *(u16 *)an->eeprom_data;
117
118 if (is_mt7915(an)) {
119 an->adie_id = 0x7975;
developer36364002023-10-31 16:53:21 +0800120 } else if (is_mt7916(an) || is_mt7981(an)) {
developer5698c9c2022-05-30 16:40:23 +0800121 an->adie_id = 0x7976;
122 } else if (is_mt7986(an)) {
123 bool is_7975 = false;
124 u32 val;
125 u8 sub_id;
126
127 atenl_reg_read(an, 0x18050000, &val);
128
129 switch (val & 0xf) {
130 case MT7975_ONE_ADIE_SINGLE_BAND:
131 is_7975 = true;
132 /* fallthrough */
133 case MT7976_ONE_ADIE_SINGLE_BAND:
134 sub_id = 0xa;
135 break;
136 case MT7976_ONE_ADIE_DBDC:
137 sub_id = 0x7;
138 break;
139 case MT7975_DUAL_ADIE_DBDC:
140 is_7975 = true;
141 /* fallthrough */
142 case MT7976_DUAL_ADIE_DBDC:
143 default:
144 sub_id = 0xf;
145 break;
146 }
147
148 an->sub_chip_id = sub_id;
149 an->adie_id = is_7975 ? 0x7975 : 0x7976;
developerf90c9af2022-12-28 22:40:23 +0800150 } else if (is_mt7996(an)) {
151 /* TODO: parse info if required */
developerd64cd9b2023-10-13 18:41:57 +0800152 } else if (is_mt7992(an)) {
153 /* TODO: parse info if required */
developer5698c9c2022-05-30 16:40:23 +0800154 }
155}
156
157static void
developer3abe1ad2022-01-24 11:13:32 +0800158atenl_eeprom_init_max_size(struct atenl *an)
159{
160 switch (an->chip_id) {
161 case 0x7915:
162 an->eeprom_size = 3584;
developer071927d2022-08-31 20:39:29 +0800163 an->eeprom_prek_offs = 0x62;
developer3abe1ad2022-01-24 11:13:32 +0800164 break;
165 case 0x7906:
166 case 0x7916:
developer36364002023-10-31 16:53:21 +0800167 case 0x7981:
developer3abe1ad2022-01-24 11:13:32 +0800168 case 0x7986:
169 an->eeprom_size = 4096;
developer071927d2022-08-31 20:39:29 +0800170 an->eeprom_prek_offs = 0x19a;
developer3abe1ad2022-01-24 11:13:32 +0800171 break;
developerf90c9af2022-12-28 22:40:23 +0800172 case 0x7990:
developerd64cd9b2023-10-13 18:41:57 +0800173 case 0x7992:
developerf90c9af2022-12-28 22:40:23 +0800174 an->eeprom_size = 7680;
175 an->eeprom_prek_offs = 0x1a5;
developer3abe1ad2022-01-24 11:13:32 +0800176 default:
177 break;
178 }
179}
180
181static void
182atenl_eeprom_init_band_cap(struct atenl *an)
183{
developerf90c9af2022-12-28 22:40:23 +0800184#define EAGLE_BAND_SEL(index) MT_EE_WIFI_EAGLE_CONF##index##_BAND_SEL
developer3abe1ad2022-01-24 11:13:32 +0800185 u8 *eeprom = an->eeprom_data;
186
187 if (is_mt7915(an)) {
188 u8 val = eeprom[MT_EE_WIFI_CONF];
189 u8 band_sel = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
190 struct atenl_band *anb = &an->anb[0];
191
192 /* MT7915A */
193 if (band_sel == MT_EE_BAND_SEL_DEFAULT) {
194 anb->valid = true;
195 anb->cap = BAND_TYPE_2G_5G;
196 return;
197 }
198
199 /* MT7915D */
200 if (band_sel == MT_EE_BAND_SEL_2GHZ) {
201 anb->valid = true;
202 anb->cap = BAND_TYPE_2G;
203 }
204
205 val = eeprom[MT_EE_WIFI_CONF + 1];
206 band_sel = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
207 anb++;
208
209 if (band_sel == MT_EE_BAND_SEL_5GHZ) {
210 anb->valid = true;
211 anb->cap = BAND_TYPE_5G;
212 }
developer36364002023-10-31 16:53:21 +0800213 } else if (is_mt7916(an) || is_mt7981(an) || is_mt7986(an)) {
developer3abe1ad2022-01-24 11:13:32 +0800214 struct atenl_band *anb;
215 u8 val, band_sel;
216 int i;
217
218 for (i = 0; i < 2; i++) {
219 val = eeprom[MT_EE_WIFI_CONF + i];
220 band_sel = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
221 anb = &an->anb[i];
222
223 anb->valid = true;
224 switch (band_sel) {
225 case MT_EE_BAND_SEL_2G:
226 anb->cap = BAND_TYPE_2G;
227 break;
228 case MT_EE_BAND_SEL_5G:
229 anb->cap = BAND_TYPE_5G;
230 break;
231 case MT_EE_BAND_SEL_6G:
232 anb->cap = BAND_TYPE_6G;
233 break;
234 case MT_EE_BAND_SEL_5G_6G:
235 anb->cap = BAND_TYPE_5G_6G;
236 break;
237 default:
238 break;
239 }
240 }
developerf90c9af2022-12-28 22:40:23 +0800241 } else if (is_mt7996(an)) {
242 struct atenl_band *anb;
243 u8 val, band_sel;
244 u8 band_sel_mask[3] = {EAGLE_BAND_SEL(0), EAGLE_BAND_SEL(1),
245 EAGLE_BAND_SEL(2)};
246 int i;
247
248 for (i = 0; i < 3; i++) {
249 val = eeprom[MT_EE_WIFI_CONF + i];
250 band_sel = FIELD_GET(band_sel_mask[i], val);
251 anb = &an->anb[i];
252
253 anb->valid = true;
254 switch (band_sel) {
255 case MT_EE_EAGLE_BAND_SEL_2GHZ:
256 anb->cap = BAND_TYPE_2G;
257 break;
258 case MT_EE_EAGLE_BAND_SEL_5GHZ:
259 anb->cap = BAND_TYPE_5G;
260 break;
261 case MT_EE_EAGLE_BAND_SEL_6GHZ:
262 anb->cap = BAND_TYPE_6G;
263 break;
264 case MT_EE_EAGLE_BAND_SEL_5GHZ_6GHZ:
265 anb->cap = BAND_TYPE_5G_6G;
266 break;
267 default:
268 break;
269 }
270 }
developerd64cd9b2023-10-13 18:41:57 +0800271 } else if (is_mt7992(an)) {
272 struct atenl_band *anb;
273 u8 val, band_sel;
274 u8 band_sel_mask[2] = {EAGLE_BAND_SEL(0), EAGLE_BAND_SEL(1)};
275 int i;
276
277 for (i = 0; i < 2; i++) {
278 val = eeprom[MT_EE_WIFI_CONF + i];
279 band_sel = FIELD_GET(band_sel_mask[i], val);
280 anb = &an->anb[i];
281
282 anb->valid = true;
283 switch (band_sel) {
284 case MT_EE_EAGLE_BAND_SEL_2GHZ:
285 anb->cap = BAND_TYPE_2G;
286 break;
287 case MT_EE_EAGLE_BAND_SEL_5GHZ:
288 anb->cap = BAND_TYPE_5G;
289 break;
290 case MT_EE_EAGLE_BAND_SEL_6GHZ:
291 anb->cap = BAND_TYPE_6G;
292 break;
293 case MT_EE_EAGLE_BAND_SEL_5GHZ_6GHZ:
294 anb->cap = BAND_TYPE_5G_6G;
295 break;
296 default:
297 break;
298 }
299 }
developer3abe1ad2022-01-24 11:13:32 +0800300 }
301}
302
303static void
304atenl_eeprom_init_antenna_cap(struct atenl *an)
305{
developerd64cd9b2023-10-13 18:41:57 +0800306 switch (an->chip_id) {
307 case 0x7915:
developer3abe1ad2022-01-24 11:13:32 +0800308 if (an->anb[0].cap == BAND_TYPE_2G_5G)
309 an->anb[0].chainmask = 0xf;
310 else {
311 an->anb[0].chainmask = 0x3;
312 an->anb[1].chainmask = 0xc;
313 }
developerd64cd9b2023-10-13 18:41:57 +0800314 break;
315 case 0x7906:
316 case 0x7916:
developer3abe1ad2022-01-24 11:13:32 +0800317 an->anb[0].chainmask = 0x3;
318 an->anb[1].chainmask = 0x3;
developerd64cd9b2023-10-13 18:41:57 +0800319 break;
developer36364002023-10-31 16:53:21 +0800320 case 0x7981:
321 an->anb[0].chainmask = 0x3;
322 an->anb[1].chainmask = 0x7;
323 break;
developerd64cd9b2023-10-13 18:41:57 +0800324 case 0x7986:
developer3abe1ad2022-01-24 11:13:32 +0800325 an->anb[0].chainmask = 0xf;
326 an->anb[1].chainmask = 0xf;
developerd64cd9b2023-10-13 18:41:57 +0800327 break;
328 case 0x7990:
developerf90c9af2022-12-28 22:40:23 +0800329 an->anb[0].chainmask = 0xf;
330 an->anb[1].chainmask = 0xf;
331 an->anb[2].chainmask = 0xf;
developerd64cd9b2023-10-13 18:41:57 +0800332 break;
333 case 0x7992:
334 an->anb[0].chainmask = 0xf;
335 an->anb[1].chainmask = 0xf;
336 break;
337 default:
338 break;
developer3abe1ad2022-01-24 11:13:32 +0800339 }
340}
341
342int atenl_eeprom_init(struct atenl *an, u8 phy_idx)
343{
344 bool flash_mode;
345 int eeprom_fd;
developera6267142022-01-26 20:50:22 +0800346 char buf[30];
developer3abe1ad2022-01-24 11:13:32 +0800347
348 set_band_val(an, 0, phy_idx, phy_idx);
developer3abe1ad2022-01-24 11:13:32 +0800349 atenl_nl_check_mtd(an);
350 flash_mode = an->mtd_part != NULL;
351
developerf90c9af2022-12-28 22:40:23 +0800352 // Get the first main phy index for this chip
developere0111812024-06-03 16:24:42 +0800353 an->main_phy_idx = phy_idx - an->band_idx;
354 snprintf(buf, sizeof(buf), "/tmp/atenl-eeprom-phy%u", an->main_phy_idx);
developer071927d2022-08-31 20:39:29 +0800355 eeprom_file = strdup(buf);
356
developer3abe1ad2022-01-24 11:13:32 +0800357 eeprom_fd = atenl_eeprom_init_file(an, flash_mode);
358 if (eeprom_fd < 0)
359 return -1;
360
361 an->eeprom_data = mmap(NULL, EEPROM_PART_SIZE, PROT_READ | PROT_WRITE,
developer071927d2022-08-31 20:39:29 +0800362 MAP_SHARED, eeprom_fd, 0);
developer3abe1ad2022-01-24 11:13:32 +0800363 if (!an->eeprom_data) {
364 perror("mmap");
365 close(eeprom_fd);
366 return -1;
367 }
368
369 an->eeprom_fd = eeprom_fd;
developer5698c9c2022-05-30 16:40:23 +0800370 atenl_eeprom_init_chip_id(an);
developer3abe1ad2022-01-24 11:13:32 +0800371 atenl_eeprom_init_max_size(an);
372 atenl_eeprom_init_band_cap(an);
373 atenl_eeprom_init_antenna_cap(an);
374
375 if (get_band_val(an, 1, valid))
376 set_band_val(an, 1, phy_idx, phy_idx + 1);
377
developer77215642023-05-15 13:52:35 +0800378 if (get_band_val(an, 2, valid))
379 set_band_val(an, 2, phy_idx, phy_idx + 2);
380
developer3abe1ad2022-01-24 11:13:32 +0800381 return 0;
382}
383
384void atenl_eeprom_close(struct atenl *an)
385{
386 msync(an->eeprom_data, EEPROM_PART_SIZE, MS_SYNC);
387 munmap(an->eeprom_data, EEPROM_PART_SIZE);
388 close(an->eeprom_fd);
389
developer5698c9c2022-05-30 16:40:23 +0800390 if (!an->cmd_mode) {
developera6267142022-01-26 20:50:22 +0800391 if (remove(eeprom_file))
developer3abe1ad2022-01-24 11:13:32 +0800392 perror("remove");
developera6267142022-01-26 20:50:22 +0800393 }
394
395 free(eeprom_file);
developer3abe1ad2022-01-24 11:13:32 +0800396}
397
developer071927d2022-08-31 20:39:29 +0800398int atenl_eeprom_update_precal(struct atenl *an, int write_offs, int size)
399{
400 u32 offs = an->eeprom_prek_offs;
401 u8 cal_indicator, *eeprom, *pre_cal;
402
403 if (!an->cal && !an->cal_info)
404 return 0;
405
406 eeprom = an->eeprom_data;
407 pre_cal = eeprom + an->eeprom_size;
408 cal_indicator = an->cal_info[4];
409
410 memcpy(eeprom + offs, &cal_indicator, sizeof(u8));
411 memcpy(pre_cal, an->cal_info, PRE_CAL_INFO);
412 pre_cal += (PRE_CAL_INFO + write_offs);
413
414 if (an->cal)
415 memcpy(pre_cal, an->cal, size);
416 else
417 memset(pre_cal, 0, size);
418
419 return 0;
420}
421
developer3abe1ad2022-01-24 11:13:32 +0800422int atenl_eeprom_write_mtd(struct atenl *an)
423{
developer0fab1142023-11-10 11:26:03 +0800424#define TMP_FILE "/tmp/tmp_eeprom.bin"
developer3abe1ad2022-01-24 11:13:32 +0800425 pid_t pid;
developer0fab1142023-11-10 11:26:03 +0800426 u32 size = an->eeprom_size;
427 u32 *precal_info = an->eeprom_data + an->eeprom_size;
428 u32 precal_size = precal_info[0] + precal_info[1];
429 char cmd[100];
developer3abe1ad2022-01-24 11:13:32 +0800430
developer2533bb32023-10-27 19:57:13 +0800431 if (an->mtd_part == NULL || !(~an->mtd_offset))
developer3abe1ad2022-01-24 11:13:32 +0800432 return 0;
433
developer0fab1142023-11-10 11:26:03 +0800434 if (precal_size)
435 size += PRE_CAL_INFO + precal_size;
436
437 sprintf(cmd, "dd if=%s of=%s bs=1 count=%d", eeprom_file, TMP_FILE, size);
438 system(cmd);
439
440 sprintf(cmd, "mtd -p %d write %s %s", an->mtd_offset, TMP_FILE, an->mtd_part);
441 system(cmd);
developer3abe1ad2022-01-24 11:13:32 +0800442
developer0fab1142023-11-10 11:26:03 +0800443 sprintf(cmd, "rm %s", TMP_FILE);
444 system(cmd);
developer3abe1ad2022-01-24 11:13:32 +0800445
446 return 0;
447}
448
developer5698c9c2022-05-30 16:40:23 +0800449/* Directly read values from driver's eeprom.
developer3abe1ad2022-01-24 11:13:32 +0800450 * It's usally used to get calibrated data from driver.
451 */
452int atenl_eeprom_read_from_driver(struct atenl *an, u32 offset, int len)
453{
454 u8 *eeprom_data = an->eeprom_data + offset;
455 char fname[64], buf[1024];
456 int fd_ori, ret;
457 ssize_t rd;
458
459 snprintf(fname, sizeof(fname),
460 "/sys/kernel/debug/ieee80211/phy%d/mt76/eeprom",
developere0111812024-06-03 16:24:42 +0800461 an->main_phy_idx);
developer3abe1ad2022-01-24 11:13:32 +0800462 fd_ori = open(fname, O_RDONLY);
463 if (fd_ori < 0)
464 return -1;
465
466 ret = lseek(fd_ori, offset, SEEK_SET);
467 if (ret < 0)
468 goto out;
469
470 while ((rd = read(fd_ori, buf, sizeof(buf))) > 0 && len) {
471 if (len < rd) {
472 memcpy(eeprom_data, buf, len);
473 break;
474 } else {
475 memcpy(eeprom_data, buf, rd);
476 eeprom_data += rd;
477 len -= rd;
478 }
479 }
480
481 ret = 0;
482out:
483 close(fd_ori);
484 return ret;
485}
486
487/* Update all eeprom values to driver before writing efuse */
488static void
489atenl_eeprom_sync_to_driver(struct atenl *an)
490{
491 int i;
492
developera6267142022-01-26 20:50:22 +0800493 for (i = 0; i < an->eeprom_size; i += 16)
developer3abe1ad2022-01-24 11:13:32 +0800494 atenl_nl_write_eeprom(an, i, &an->eeprom_data[i], 16);
495}
496
497void atenl_eeprom_cmd_handler(struct atenl *an, u8 phy_idx, char *cmd)
498{
developer3abe1ad2022-01-24 11:13:32 +0800499 an->cmd_mode = true;
500
501 atenl_eeprom_init(an, phy_idx);
developer3abe1ad2022-01-24 11:13:32 +0800502
503 if (!strncmp(cmd, "sync eeprom all", 15)) {
504 atenl_eeprom_write_mtd(an);
505 } else if (!strncmp(cmd, "eeprom", 6)) {
506 char *s = strchr(cmd, ' ');
507
508 if (!s) {
developer5698c9c2022-05-30 16:40:23 +0800509 atenl_err("eeprom: please type a correct command\n");
developer3abe1ad2022-01-24 11:13:32 +0800510 return;
511 }
512
513 s++;
514 if (!strncmp(s, "reset", 5)) {
developera6267142022-01-26 20:50:22 +0800515 unlink(eeprom_file);
developer3abe1ad2022-01-24 11:13:32 +0800516 } else if (!strncmp(s, "file", 4)) {
developera6267142022-01-26 20:50:22 +0800517 atenl_info("%s\n", eeprom_file);
developer2533bb32023-10-27 19:57:13 +0800518 if (an->mtd_part != NULL)
519 atenl_info("%s mode\n",
520 ~an->mtd_offset == 0 ? "Binfile" : "Flash");
521 else
522 atenl_info("Efuse / Default bin mode\n");
developer3abe1ad2022-01-24 11:13:32 +0800523 } else if (!strncmp(s, "set", 3)) {
524 u32 offset, val;
525
526 s = strchr(s, ' ');
527 if (!s)
528 return;
529 s++;
530
531 if (!sscanf(s, "%x=%x", &offset, &val) ||
532 offset > EEPROM_PART_SIZE)
533 return;
534
535 an->eeprom_data[offset] = val;
536 atenl_info("set offset 0x%x to 0x%x\n", offset, val);
developer9b7cdad2022-03-10 14:24:55 +0800537 } else if (!strncmp(s, "update buffermode", 17)) {
developera6267142022-01-26 20:50:22 +0800538 atenl_eeprom_sync_to_driver(an);
developer3abe1ad2022-01-24 11:13:32 +0800539 atenl_nl_update_buffer_mode(an);
540 } else if (!strncmp(s, "write", 5)) {
541 s = strchr(s, ' ');
542 if (!s)
543 return;
544 s++;
545
developer9b7cdad2022-03-10 14:24:55 +0800546 if (!strncmp(s, "flash", 5)) {
developer3abe1ad2022-01-24 11:13:32 +0800547 atenl_eeprom_write_mtd(an);
developerd64cd9b2023-10-13 18:41:57 +0800548 } else if (!strncmp(s, "to efuse", 8)) {
549 atenl_eeprom_sync_to_driver(an);
550 atenl_nl_write_efuse_all(an);
551 }
developer3abe1ad2022-01-24 11:13:32 +0800552 } else if (!strncmp(s, "read", 4)) {
553 u32 offset;
554
555 s = strchr(s, ' ');
556 if (!s)
557 return;
558 s++;
559
560 if (!sscanf(s, "%x", &offset) ||
561 offset > EEPROM_PART_SIZE)
562 return;
563
564 atenl_info("val = 0x%x (%u)\n", an->eeprom_data[offset],
565 an->eeprom_data[offset]);
developer071927d2022-08-31 20:39:29 +0800566 } else if (!strncmp(s, "precal", 6)) {
567 s = strchr(s, ' ');
568 if (!s)
569 return;
570 s++;
571
572 if (!strncmp(s, "sync group", 10)) {
573 atenl_nl_precal_sync_from_driver(an, PREK_SYNC_GROUP);
574 } else if (!strncmp(s, "sync dpd 2g", 11)) {
575 atenl_nl_precal_sync_from_driver(an, PREK_SYNC_DPD_2G);
576 } else if (!strncmp(s, "sync dpd 5g", 11)) {
577 atenl_nl_precal_sync_from_driver(an, PREK_SYNC_DPD_5G);
578 } else if (!strncmp(s, "sync dpd 6g", 11)) {
579 atenl_nl_precal_sync_from_driver(an, PREK_SYNC_DPD_6G);
580 } else if (!strncmp(s, "group clean", 11)) {
581 atenl_nl_precal_sync_from_driver(an, PREK_CLEAN_GROUP);
582 } else if (!strncmp(s, "dpd clean", 9)) {
583 atenl_nl_precal_sync_from_driver(an, PREK_CLEAN_DPD);
584 } else if (!strncmp(s, "sync", 4)) {
585 atenl_nl_precal_sync_from_driver(an, PREK_SYNC_ALL);
586 }
developer44ae8e92023-07-21 13:42:14 +0800587 } else if (!strncmp(s, "ibf sync", 8)) {
588 atenl_get_ibf_cal_result(an);
developer9b7cdad2022-03-10 14:24:55 +0800589 } else {
developer44ae8e92023-07-21 13:42:14 +0800590 atenl_err("Unknown eeprom command: %s\n", cmd);
591 }
developer3abe1ad2022-01-24 11:13:32 +0800592 } else {
593 atenl_err("Unknown command: %s\n", cmd);
594 }
595}