1
2
3
4
5
6
7
8
9#include <common.h>
10#include <command.h>
11#include <env.h>
12#include <i2c.h>
13#include <linux/ctype.h>
14#include <u-boot/crc.h>
15
16#ifdef CONFIG_SYS_I2C_EEPROM_CCID
17#include "../common/eeprom.h"
18#define MAX_NUM_PORTS 8
19#endif
20
21#ifdef CONFIG_SYS_I2C_EEPROM_NXID
22
23
24#ifndef MAX_NUM_PORTS
25#define MAX_NUM_PORTS 16
26#endif
27#define NXID_VERSION 1
28#endif
29
30
31
32
33
34
35static struct __attribute__ ((__packed__)) eeprom {
36#ifdef CONFIG_SYS_I2C_EEPROM_CCID
37 u8 id[4];
38 u8 major;
39 u8 minor;
40 u8 sn[10];
41 u8 errata[2];
42 u8 date[6];
43 u8 res_0[40];
44 u8 mac_count;
45 u8 mac_flag;
46 u8 mac[MAX_NUM_PORTS][6];
47 u32 crc;
48#endif
49#ifdef CONFIG_SYS_I2C_EEPROM_NXID
50 u8 id[4];
51 u8 sn[12];
52 u8 errata[5];
53 u8 date[6];
54 u8 res_0;
55 u32 version;
56 u8 tempcal[8];
57 u8 tempcalsys[2];
58 u8 tempcalflags;
59 u8 res_1[21];
60 u8 mac_count;
61 u8 mac_flag;
62 u8 mac[MAX_NUM_PORTS][6];
63 u8 res_2[90];
64 u32 crc;
65#endif
66} e;
67
68
69static int has_been_read = 0;
70
71#ifdef CONFIG_SYS_I2C_EEPROM_NXID
72
73#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \
74 (e.id[2] == 'I') || (e.id[3] == 'D'))
75#endif
76
77#ifdef CONFIG_SYS_I2C_EEPROM_CCID
78
79#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \
80 (e.id[2] == 'I') || (e.id[3] == 'D'))
81#endif
82
83
84
85
86static void show_eeprom(void)
87{
88 int i;
89 unsigned int crc;
90
91
92#ifdef CONFIG_SYS_I2C_EEPROM_NXID
93 printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
94 be32_to_cpu(e.version));
95#else
96 printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
97#endif
98
99
100 printf("SN: %s\n", e.sn);
101
102
103#ifdef CONFIG_SYS_I2C_EEPROM_NXID
104 printf("Errata: %s\n", e.errata);
105#else
106 printf("Errata: %c%c\n",
107 e.errata[0] ? e.errata[0] : '.',
108 e.errata[1] ? e.errata[1] : '.');
109#endif
110
111
112 printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n",
113 e.date[0], e.date[1], e.date[2],
114 e.date[3] & 0x7F, e.date[4], e.date[5],
115 e.date[3] & 0x80 ? "PM" : "");
116
117
118 for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
119
120 u8 *p = e.mac[i];
121
122 printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i,
123 p[0], p[1], p[2], p[3], p[4], p[5]);
124 }
125
126 crc = crc32(0, (void *)&e, sizeof(e) - 4);
127
128 if (crc == be32_to_cpu(e.crc))
129 printf("CRC: %08x\n", be32_to_cpu(e.crc));
130 else
131 printf("CRC: %08x (should be %08x)\n",
132 be32_to_cpu(e.crc), crc);
133
134#ifdef DEBUG
135 printf("EEPROM dump: (0x%x bytes)\n", sizeof(e));
136 for (i = 0; i < sizeof(e); i++) {
137 if ((i % 16) == 0)
138 printf("%02X: ", i);
139 printf("%02X ", ((u8 *)&e)[i]);
140 if (((i % 16) == 15) || (i == sizeof(e) - 1))
141 printf("\n");
142 }
143#endif
144}
145
146
147
148
149static int read_eeprom(void)
150{
151 int ret;
152#ifdef CONFIG_SYS_EEPROM_BUS_NUM
153#ifndef CONFIG_DM_I2C
154 unsigned int bus;
155#endif
156#endif
157
158 if (has_been_read)
159 return 0;
160
161#ifdef CONFIG_SYS_EEPROM_BUS_NUM
162#ifndef CONFIG_DM_I2C
163 bus = i2c_get_bus_num();
164 i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
165#endif
166#endif
167
168#ifndef CONFIG_DM_I2C
169 ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
170 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
171 (void *)&e, sizeof(e));
172#else
173 struct udevice *dev;
174#ifdef CONFIG_SYS_EEPROM_BUS_NUM
175 ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
176 CONFIG_SYS_I2C_EEPROM_ADDR, 1, &dev);
177#else
178 ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR, 1, &dev);
179#endif
180 if (!ret)
181 ret = dm_i2c_read(dev, 0, (void *)&e, sizeof(e));
182#endif
183
184#ifdef CONFIG_SYS_EEPROM_BUS_NUM
185#ifndef CONFIG_DM_I2C
186 i2c_set_bus_num(bus);
187#endif
188#endif
189
190#ifdef DEBUG
191 show_eeprom();
192#endif
193
194 has_been_read = (ret == 0) ? 1 : 0;
195
196 return ret;
197}
198
199
200
201
202
203
204
205static void update_crc(void)
206{
207 u32 crc;
208
209 crc = crc32(0, (void *)&e, sizeof(e) - 4);
210 e.crc = cpu_to_be32(crc);
211}
212
213
214
215
216static int prog_eeprom(void)
217{
218 int ret = 0;
219 int i;
220 void *p;
221#ifdef CONFIG_SYS_EEPROM_BUS_NUM
222#ifndef CONFIG_DM_I2C
223 unsigned int bus;
224#endif
225#endif
226
227
228#ifdef CONFIG_SYS_I2C_EEPROM_NXID
229 e.res_0 = 0xFF;
230 memset(e.res_1, 0xFF, sizeof(e.res_1));
231#else
232 memset(e.res_0, 0xFF, sizeof(e.res_0));
233#endif
234 update_crc();
235
236#ifndef CONFIG_DM_I2C
237#ifdef CONFIG_SYS_EEPROM_BUS_NUM
238 bus = i2c_get_bus_num();
239 i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
240#endif
241#endif
242
243
244
245
246
247
248 for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
249#ifndef CONFIG_DM_I2C
250 ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i,
251 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
252 p, min((int)(sizeof(e) - i), 8));
253#else
254 struct udevice *dev;
255#ifdef CONFIG_SYS_EEPROM_BUS_NUM
256 ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
257 CONFIG_SYS_I2C_EEPROM_ADDR,
258 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
259 &dev);
260#else
261 ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
262 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
263 &dev);
264#endif
265 if (!ret)
266 ret = dm_i2c_write(dev, i, p, min((int)(sizeof(e) - i),
267 8));
268#endif
269 if (ret)
270 break;
271 udelay(5000);
272 }
273
274 if (!ret) {
275
276 struct eeprom e2;
277
278#ifndef CONFIG_DM_I2C
279 ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
280 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
281 (void *)&e2, sizeof(e2));
282#else
283 struct udevice *dev;
284#ifdef CONFIG_SYS_EEPROM_BUS_NUM
285 ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
286 CONFIG_SYS_I2C_EEPROM_ADDR,
287 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
288 &dev);
289#else
290 ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
291 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
292 &dev);
293#endif
294 if (!ret)
295 ret = dm_i2c_read(dev, 0, (void *)&e2, sizeof(e2));
296#endif
297 if (!ret && memcmp(&e, &e2, sizeof(e)))
298 ret = -1;
299 }
300
301#ifndef CONFIG_DM_I2C
302#ifdef CONFIG_SYS_EEPROM_BUS_NUM
303 i2c_set_bus_num(bus);
304#endif
305#endif
306
307 if (ret) {
308 printf("Programming failed.\n");
309 has_been_read = 0;
310 return -1;
311 }
312
313 printf("Programming passed.\n");
314 return 0;
315}
316
317
318
319
320
321
322
323static inline u8 h2i(char p)
324{
325 if ((p >= '0') && (p <= '9'))
326 return p - '0';
327
328 if ((p >= 'A') && (p <= 'F'))
329 return (p - 'A') + 10;
330
331 if ((p >= 'a') && (p <= 'f'))
332 return (p - 'a') + 10;
333
334 return 0;
335}
336
337
338
339
340
341
342
343
344static void set_date(const char *string)
345{
346 unsigned int i;
347
348 if (strlen(string) != 12) {
349 printf("Usage: mac date YYMMDDhhmmss\n");
350 return;
351 }
352
353 for (i = 0; i < 6; i++)
354 e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
355
356 update_crc();
357}
358
359
360
361
362
363
364
365
366static void set_mac_address(unsigned int index, const char *string)
367{
368 char *p = (char *) string;
369 unsigned int i;
370
371 if ((index >= MAX_NUM_PORTS) || !string) {
372 printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n");
373 return;
374 }
375
376 for (i = 0; *p && (i < 6); i++) {
377 e.mac[index][i] = simple_strtoul(p, &p, 16);
378 if (*p == ':')
379 p++;
380 }
381
382 update_crc();
383}
384
385int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
386{
387 char cmd;
388
389 if (argc == 1) {
390 show_eeprom();
391 return 0;
392 }
393
394 cmd = argv[1][0];
395
396 if (cmd == 'r') {
397 read_eeprom();
398 return 0;
399 }
400
401 if (cmd == 'i') {
402#ifdef CONFIG_SYS_I2C_EEPROM_NXID
403 memcpy(e.id, "NXID", sizeof(e.id));
404 e.version = cpu_to_be32(NXID_VERSION);
405#else
406 memcpy(e.id, "CCID", sizeof(e.id));
407#endif
408 update_crc();
409 return 0;
410 }
411
412 if (!is_valid) {
413 printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n");
414 return 0;
415 }
416
417 if (argc == 2) {
418 switch (cmd) {
419 case 's':
420 prog_eeprom();
421 break;
422 default:
423 return cmd_usage(cmdtp);
424 }
425
426 return 0;
427 }
428
429
430
431 switch (cmd) {
432 case 'n':
433 memset(e.sn, 0, sizeof(e.sn));
434 strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
435 update_crc();
436 break;
437 case 'e':
438#ifdef CONFIG_SYS_I2C_EEPROM_NXID
439 memset(e.errata, 0, 5);
440 strncpy((char *)e.errata, argv[2], 4);
441#else
442 e.errata[0] = argv[2][0];
443 e.errata[1] = argv[2][1];
444#endif
445 update_crc();
446 break;
447 case 'd':
448 set_date(argv[2]);
449 break;
450 case 'p':
451 e.mac_count = simple_strtoul(argv[2], NULL, 16);
452 update_crc();
453 break;
454 case '0' ... '9':
455 set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]);
456 break;
457 case 'h':
458 default:
459 return cmd_usage(cmdtp);
460 }
461
462 return 0;
463}
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480int mac_read_from_eeprom(void)
481{
482 unsigned int i;
483 u32 crc, crc_offset = offsetof(struct eeprom, crc);
484 u32 *crcp;
485
486 puts("EEPROM: ");
487
488 if (read_eeprom()) {
489 printf("Read failed.\n");
490 return 0;
491 }
492
493 if (!is_valid) {
494 printf("Invalid ID (%02x %02x %02x %02x)\n",
495 e.id[0], e.id[1], e.id[2], e.id[3]);
496 return 0;
497 }
498
499#ifdef CONFIG_SYS_I2C_EEPROM_NXID
500
501
502
503
504 if (e.version == 0)
505 crc_offset = 0x72;
506#endif
507
508 crc = crc32(0, (void *)&e, crc_offset);
509 crcp = (void *)&e + crc_offset;
510 if (crc != be32_to_cpu(*crcp)) {
511 printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc));
512 return 0;
513 }
514
515#ifdef CONFIG_SYS_I2C_EEPROM_NXID
516
517
518
519
520
521 if (e.version == 0)
522 memset(e.mac[8], 0xff, 6);
523#endif
524
525 for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) {
526 if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
527 memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
528 char ethaddr[18];
529 char enetvar[9];
530
531 sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
532 e.mac[i][0],
533 e.mac[i][1],
534 e.mac[i][2],
535 e.mac[i][3],
536 e.mac[i][4],
537 e.mac[i][5]);
538 sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
539
540
541
542 if (!env_get(enetvar))
543 env_set(enetvar, ethaddr);
544 }
545 }
546
547#ifdef CONFIG_SYS_I2C_EEPROM_NXID
548 printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
549 be32_to_cpu(e.version));
550#else
551 printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
552#endif
553
554#ifdef CONFIG_SYS_I2C_EEPROM_NXID
555
556
557
558
559 if (e.version == 0) {
560 e.version = cpu_to_be32(NXID_VERSION);
561 update_crc();
562 }
563#endif
564
565 return 0;
566}
567
568#ifdef CONFIG_SYS_I2C_EEPROM_CCID
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585unsigned int get_cpu_board_revision(void)
586{
587 struct board_eeprom {
588 u32 id;
589 u8 major;
590 u8 minor;
591 } be;
592
593#ifndef CONFIG_DM_I2C
594 i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
595 (void *)&be, sizeof(be));
596#else
597 struct udevice *dev;
598#ifdef CONFIG_SYS_EEPROM_BUS_NUM
599 ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
600 CONFIG_SYS_I2C_EEPROM_ADDR,
601 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
602 &dev);
603#else
604 ret = i2c_get_chip_for_busnum(0, CONFIG_SYS_I2C_EEPROM_ADDR,
605 CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
606 &dev)
607#endif
608 if (!ret)
609 dm_i2c_read(dev, 0, (void *)&be, sizeof(be));
610#endif
611
612 if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D'))
613 return MPC85XX_CPU_BOARD_REV(0, 0);
614
615 if ((be.major == 0xff) && (be.minor == 0xff))
616 return MPC85XX_CPU_BOARD_REV(0, 0);
617
618 return MPC85XX_CPU_BOARD_REV(be.major, be.minor);
619}
620#endif
621