Merge branch 'mpc86xx'
[oweals/u-boot.git] / board / mpc8641hpcn / sys_eeprom.c
1 /*
2  * Copyright 2006 Freescale Semiconductor
3  * York Sun (yorksun@freescale.com)
4  * Haiying Wang (haiying.wang@freescale.com)
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <command.h>
27 #include <i2c.h>
28 #include <linux/ctype.h>
29
30 #ifdef CFG_ID_EEPROM
31 typedef struct {
32         unsigned char id[4];    /* 0x0000 - 0x0003 */
33         unsigned char sn[12];   /* 0x0004 - 0x000F */
34         unsigned char errata[5];/* 0x0010 - 0x0014 */
35         unsigned char date[7];  /* 0x0015 - 0x001a */
36         unsigned char res_1[37];/* 0x001b - 0x003f */
37         unsigned char tab_size; /* 0x0040 */
38         unsigned char tab_flag; /* 0x0041 */
39         unsigned char mac[8][6];/* 0x0042 - 0x0071 */
40         unsigned char res_2[126];/* 0x0072 - 0x00ef */
41         unsigned int  crc;      /* 0x00f0 - 0x00f3 crc32 checksum */
42 } EEPROM_data;
43
44 static EEPROM_data mac_data;
45
46 int mac_show(void)
47 {
48         int i;
49         unsigned char ethaddr[8][18];
50
51         printf("ID %c%c%c%c\n", mac_data.id[0],\
52                                 mac_data.id[1],\
53                                 mac_data.id[2],\
54                                 mac_data.id[3]);
55         printf("Errata %c%c%c%c%c\n",   mac_data.errata[0],\
56                                 mac_data.errata[1],\
57                                 mac_data.errata[2],\
58                                 mac_data.errata[3],\
59                                 mac_data.errata[4]);
60         printf("Date %c%c%c%c%c%c%c\n", mac_data.date[0],\
61                                 mac_data.date[1],\
62                                 mac_data.date[2],\
63                                 mac_data.date[3],\
64                                 mac_data.date[4],\
65                                 mac_data.date[5],\
66                                 mac_data.date[6]);
67         for (i = 0; i < 8; i++) {
68                 sprintf(ethaddr[i],"%02x:%02x:%02x:%02x:%02x:%02x",\
69                                         mac_data.mac[i][0],\
70                                         mac_data.mac[i][1],\
71                                         mac_data.mac[i][2],\
72                                         mac_data.mac[i][3],\
73                                         mac_data.mac[i][4],\
74                                         mac_data.mac[i][5]);
75                 printf("MAC %d %s\n", i, ethaddr[i]);
76         }
77
78         setenv("ethaddr", ethaddr[0]);
79         setenv("eth1addr", ethaddr[1]);
80         setenv("eth2addr", ethaddr[2]);
81         setenv("eth3addr", ethaddr[3]);
82
83         return 0;
84 }
85
86 int mac_read(void)
87 {
88         int ret,length;
89         unsigned int crc = 0;
90         unsigned char dev = ID_EEPROM_ADDR, *data;
91
92         length = sizeof(EEPROM_data);
93         ret = i2c_read(dev, 0, 1, (unsigned char *)(&mac_data), length);
94         if (ret) {
95                 printf("Read failed.\n");
96                 return -1;
97         }
98
99         data = (unsigned char *)(&mac_data);
100         printf("Check CRC on reading ...");
101         crc = crc32(crc, data, length-4);
102         if (crc != mac_data.crc) {
103                 printf("CRC checksum is invalid, in EEPROM CRC is %x, calculated CRC is %x\n",mac_data.crc,crc);
104                 return -1;
105         }
106         else {
107                 printf("CRC OK\n");
108                 mac_show();
109         }
110         return 0;
111 }
112
113 int mac_prog(void)
114 {
115         int ret, i, length;
116         unsigned int crc = 0;
117         unsigned char dev = ID_EEPROM_ADDR,*ptr;
118         unsigned char * eeprom_data = (unsigned char *)(&mac_data);
119
120         for (i = 0; i < sizeof(mac_data.res_1); i++)
121                 mac_data.res_1[i] = 0;
122         for (i = 0;i < sizeof(mac_data.res_2); i++)
123                 mac_data.res_2[i] = 0;
124         length = sizeof(EEPROM_data);
125         crc = crc32 (crc, eeprom_data, length-4);
126         mac_data.crc = crc;
127         for (i = 0, ptr = eeprom_data; i < length; i += 8, ptr += 8) {
128                 ret = i2c_write(dev, i, 1, ptr, (length-i) <8 ? (length-i) : 8);
129                 udelay(5000);           /* 5ms write cycle timing */
130                 if (ret)
131                         break;
132         }
133         if (ret) {
134                 printf("Programming failed.\n");
135                 return -1;
136         }
137         else {
138                 printf("Programming %d bytes. Reading back ...\n",length);
139                 mac_read();
140         }
141         return 0;
142 }
143
144 int do_mac (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
145 {
146         int i;
147         char cmd = 's';
148         unsigned long long mac_val;
149
150         if(i2c_probe(ID_EEPROM_ADDR) != 0)
151                 return -1;
152
153         if(argc>1) {
154                 cmd = argv[1][0];
155                 switch (cmd) {
156                         case 'r':       /* display */
157                                 mac_read();
158                                 break;
159                         case 's':       /* save */
160                                 mac_prog();
161                                 break;
162                         case 'i':       /* id */
163                                 for (i=0; i<4; i++) {
164                                         mac_data.id[i] = argv[2][i];
165                                 }
166                                 break;
167                         case 'n':       /* serial number */
168                                 for (i=0; i<12; i++) {
169                                         mac_data.sn[i] = argv[2][i];
170                                 }
171                                 break;
172                         case 'e':       /* errata */
173                                 for (i=0; i<5; i++) {
174                                         mac_data.errata[i] = argv[2][i];
175                                 }
176                                 break;
177                         case 'd':       /* date */
178                                 for (i=0; i<7; i++) {
179                                         mac_data.date[i] = argv[2][i];
180                                 }
181                                 break;
182                         case 'p':       /* number of ports */
183                                 mac_data.tab_size = (unsigned char)simple_strtoul(argv[2],NULL,16);
184                                 break;
185                         case '0':       /* mac 0 */
186                         case '1':       /* mac 1 */
187                         case '2':       /* mac 2 */
188                         case '3':       /* mac 3 */
189                         case '4':       /* mac 4 */
190                         case '5':       /* mac 5 */
191                         case '6':       /* mac 6 */
192                         case '7':       /* mac 7 */
193                                 mac_val = simple_strtoull(argv[2],NULL,16);
194                                 for (i=0; i<6; i++) {
195                                         mac_data.mac[cmd-'0'][i] = *((unsigned char *)(((unsigned int)(&mac_val))+i+2));
196                                 }
197                                 break;
198                         case 'h':       /* help */
199                         default:
200                                 printf ("Usage:\n%s\n", cmdtp->usage);
201                                 break;
202                 }
203         }
204         else {
205                 mac_show();
206         }
207         return 0;
208 }
209
210 int mac_read_from_eeprom(void)
211 {
212         int length,i;
213         unsigned char dev = ID_EEPROM_ADDR, *data, ethaddr[4][18], enetvar[32];
214         unsigned int crc = 0;
215
216         length = sizeof(EEPROM_data);
217         if(i2c_read (dev, 0, 1, (unsigned char *)(&mac_data), length)) {
218                 printf("Read failed.\n");
219                 return -1;
220         }
221
222         data = (unsigned char *)(&mac_data);
223         crc = crc32(crc, data, length-4);
224         if (crc != mac_data.crc) {
225                 return -1;
226         }
227         else {
228                 for(i=0; i<4; i++) {
229                         if(memcmp(&mac_data.mac[i], "\0\0\0\0\0\0", 6)) {
230                                 sprintf(ethaddr[i], "%02x:%02x:%02x:%02x:%02x:%02x", \
231                                         mac_data.mac[i][0], \
232                                         mac_data.mac[i][1], \
233                                         mac_data.mac[i][2], \
234                                         mac_data.mac[i][3], \
235                                         mac_data.mac[i][4], \
236                                         mac_data.mac[i][5]);
237                                 sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
238                                 setenv(enetvar, ethaddr[i]);
239                         }
240                 }
241         }
242         return 0;
243 }
244 #endif  /* CFG_ID_EEPROM */