]>
Commit | Line | Data |
---|---|---|
c7db9a38 WD |
1 | /* |
2 | * (C) Copyright 2000, 2001, 2002 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * (C) Copyright 2005 | |
6 | * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de | |
7 | * | |
8 | * See file CREDITS for list of people who contributed to this | |
9 | * project. | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU General Public License as | |
13 | * published by the Free Software Foundation; either version 2 of | |
14 | * the License, or (at your option) any later version. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License | |
22 | * along with this program; if not, write to the Free Software | |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
24 | * MA 02111-1307 USA | |
25 | */ | |
26 | ||
27 | /* #define DEBUG */ | |
28 | ||
29 | #include <common.h> | |
30 | ||
31 | #define I2C_CHIP 0x50 /* I2C bus address of onboard EEPROM */ | |
32 | #define I2C_ALEN 1 /* length of EEPROM addresses in bytes */ | |
33 | #define I2C_OFFSET 0x0 /* start address of manufacturere data block | |
34 | * in EEPROM */ | |
35 | ||
36 | /* 64 Byte manufacturer data block in EEPROM */ | |
37 | struct manufacturer_data { | |
38 | unsigned int serial_number; /* serial number (0...999999) */ | |
39 | unsigned short hardware; /* hardware version (e.g. V1.02) */ | |
40 | unsigned short manuf_date; /* manufacture date (e.g. 25/02) */ | |
41 | unsigned char name[20]; /* device name (in CHIP.INI) */ | |
42 | unsigned char macadr[6]; /* MAC address */ | |
43 | signed char a_kal[4]; /* calibration value for U */ | |
44 | signed char i_kal[4]; /* calibration value for I */ | |
45 | unsigned char reserve[18]; /* reserved */ | |
46 | unsigned short save_nr; /* save count */ | |
47 | unsigned short chksum; /* checksum */ | |
48 | }; | |
49 | ||
50 | ||
51 | int i2c_read (unsigned char chip, unsigned int addr, int alen, | |
52 | unsigned char *buffer, int len); | |
53 | ||
54 | /*----------------------------------------------------------------------- | |
55 | * Process manufacturer data block in EEPROM: | |
56 | * | |
57 | * If we boot on a system fresh from factory, check if the manufacturer data | |
58 | * in the EEPROM is valid and save some information it contains. | |
59 | * | |
60 | * CMC manufacturer data is defined as follows: | |
61 | * | |
62 | * - located in the onboard EEPROM | |
63 | * - starts at offset 0x0 | |
64 | * - size 0x00000040 | |
65 | * | |
66 | * Internal structure: see struct definition | |
67 | */ | |
68 | ||
69 | void load_sernum_ethaddr (void) | |
70 | { | |
71 | struct manufacturer_data data; | |
d52fb7e3 WD |
72 | char ethaddr[18]; |
73 | char serial [9]; | |
c7db9a38 WD |
74 | unsigned short chksum; |
75 | unsigned char *p; | |
76 | unsigned short i, is, id; | |
77 | ||
78 | #if !defined(CONFIG_HARD_I2C) && !defined(CONFIG_SOFT_I2C) | |
79 | #error you must define some I2C support (CONFIG_HARD_I2C or CONFIG_SOFT_I2C) | |
80 | #endif | |
81 | if (i2c_read(I2C_CHIP, I2C_OFFSET, I2C_ALEN, (unsigned char *)&data, | |
82 | sizeof(data)) != 0) { | |
83 | puts ("Error reading manufacturer data from EEPROM\n"); | |
84 | return; | |
85 | } | |
86 | ||
87 | /* check if manufacturer data block is valid */ | |
88 | p = (unsigned char *)&data; | |
89 | chksum = 0; | |
90 | for (i = 0; i < (sizeof(data) - sizeof(data.chksum)); i++) | |
91 | chksum += *p++; | |
92 | ||
93 | debug ("checksum of manufacturer data block: %#.4x\n", chksum); | |
94 | ||
95 | if (chksum != data.chksum) { | |
96 | puts ("Error: manufacturer data block has invalid checksum\n"); | |
97 | return; | |
98 | } | |
99 | ||
100 | /* copy MAC address */ | |
101 | is = 0; | |
102 | id = 0; | |
103 | for (i = 0; i < 6; i++) { | |
104 | sprintf (ðaddr[id], "%02x", data.macadr[is++]); | |
105 | id += 2; | |
106 | if (is < 6) | |
107 | ethaddr[id++] = ':'; | |
108 | } | |
109 | ethaddr[id] = '\0'; /* just to be sure */ | |
110 | ||
111 | /* copy serial number */ | |
112 | sprintf (serial, "%d", data.serial_number); | |
113 | ||
114 | /* set serial# and ethaddr if not yet defined */ | |
115 | if (getenv("serial#") == NULL) { | |
116 | setenv ("serial#", serial); | |
117 | } | |
118 | ||
119 | if (getenv("ethaddr") == NULL) { | |
120 | setenv ("ethaddr", ethaddr); | |
121 | } | |
122 | } |