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