]> git.ipfire.org Git - people/ms/u-boot.git/blob - examples/standalone/smc91111_eeprom.c
Merge branch 'master' of git://git.denx.de/u-boot-net
[people/ms/u-boot.git] / examples / standalone / smc91111_eeprom.c
1 /*
2 * (C) Copyright 2004
3 * Robin Getz rgetz@blacfin.uclinux.org
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 * Heavily borrowed from the following peoples GPL'ed software:
24 * - Wolfgang Denk, DENX Software Engineering, wd@denx.de
25 * Das U-boot
26 * - Ladislav Michl ladis@linux-mips.org
27 * A rejected patch on the U-Boot mailing list
28 */
29
30 #include <common.h>
31 #include <exports.h>
32 #include "../drivers/net/smc91111.h"
33
34 #ifndef SMC91111_EEPROM_INIT
35 # define SMC91111_EEPROM_INIT()
36 #endif
37
38 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
39 #define EEPROM 0x1
40 #define MAC 0x2
41 #define UNKNOWN 0x4
42
43 void dump_reg (struct eth_device *dev);
44 void dump_eeprom (struct eth_device *dev);
45 int write_eeprom_reg (struct eth_device *dev, int value, int reg);
46 void copy_from_eeprom (struct eth_device *dev);
47 void print_MAC (struct eth_device *dev);
48 int read_eeprom_reg (struct eth_device *dev, int reg);
49 void print_macaddr (struct eth_device *dev);
50
51 int smc91111_eeprom (int argc, char *argv[])
52 {
53 int c, i, j, done, line, reg, value, start, what;
54 char input[50];
55
56 struct eth_device dev;
57 dev.iobase = CONFIG_SMC91111_BASE;
58
59 /* Print the ABI version */
60 app_startup (argv);
61 if (XF_VERSION != (int) get_version ()) {
62 printf ("Expects ABI version %d\n", XF_VERSION);
63 printf ("Actual U-Boot ABI version %d\n",
64 (int) get_version ());
65 printf ("Can't run\n\n");
66 return (0);
67 }
68
69 SMC91111_EEPROM_INIT();
70
71 if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
72 printf ("Can't find SMSC91111\n");
73 return (0);
74 }
75
76 done = 0;
77 what = UNKNOWN;
78 printf ("\n");
79 while (!done) {
80 /* print the prompt */
81 printf ("SMC91111> ");
82 line = 0;
83 i = 0;
84 start = 1;
85 while (!line) {
86 /* Wait for a keystroke */
87 while (!tstc ());
88
89 c = getc ();
90 /* Make Uppercase */
91 if (c >= 'Z')
92 c -= ('a' - 'A');
93 /* printf(" |%02x| ",c); */
94
95 switch (c) {
96 case '\r': /* Enter */
97 case '\n':
98 input[i] = 0;
99 puts ("\r\n");
100 line = 1;
101 break;
102 case '\0': /* nul */
103 continue;
104
105 case 0x03: /* ^C - break */
106 input[0] = 0;
107 i = 0;
108 line = 1;
109 done = 1;
110 break;
111
112 case 0x5F:
113 case 0x08: /* ^H - backspace */
114 case 0x7F: /* DEL - backspace */
115 if (i > 0) {
116 puts ("\b \b");
117 i--;
118 }
119 break;
120 default:
121 if (start) {
122 if ((c == 'W') || (c == 'D')
123 || (c == 'M') || (c == 'C')
124 || (c == 'P')) {
125 putc (c);
126 input[i] = c;
127 if (i <= 45)
128 i++;
129 start = 0;
130 }
131 } else {
132 if ((c >= '0' && c <= '9')
133 || (c >= 'A' && c <= 'F')
134 || (c == 'E') || (c == 'M')
135 || (c == ' ')) {
136 putc (c);
137 input[i] = c;
138 if (i <= 45)
139 i++;
140 break;
141 }
142 }
143 break;
144 }
145 }
146
147 for (; i < 49; i++)
148 input[i] = 0;
149
150 switch (input[0]) {
151 case ('W'):
152 /* Line should be w reg value */
153 i = 0;
154 reg = 0;
155 value = 0;
156 /* Skip to the next space or end) */
157 while ((input[i] != ' ') && (input[i] != 0))
158 i++;
159
160 if (input[i] != 0)
161 i++;
162
163 /* Are we writing to EEPROM or MAC */
164 switch (input[i]) {
165 case ('E'):
166 what = EEPROM;
167 break;
168 case ('M'):
169 what = MAC;
170 break;
171 default:
172 what = UNKNOWN;
173 break;
174 }
175
176 /* skip to the next space or end */
177 while ((input[i] != ' ') && (input[i] != 0))
178 i++;
179 if (input[i] != 0)
180 i++;
181
182 /* Find register to write into */
183 j = 0;
184 while ((input[i] != ' ') && (input[i] != 0)) {
185 j = input[i] - 0x30;
186 if (j >= 0xA) {
187 j -= 0x07;
188 }
189 reg = (reg * 0x10) + j;
190 i++;
191 }
192
193 while ((input[i] != ' ') && (input[i] != 0))
194 i++;
195
196 if (input[i] != 0)
197 i++;
198 else
199 what = UNKNOWN;
200
201 /* Get the value to write */
202 j = 0;
203 while ((input[i] != ' ') && (input[i] != 0)) {
204 j = input[i] - 0x30;
205 if (j >= 0xA) {
206 j -= 0x07;
207 }
208 value = (value * 0x10) + j;
209 i++;
210 }
211
212 switch (what) {
213 case 1:
214 printf ("Writing EEPROM register %02x with %04x\n", reg, value);
215 write_eeprom_reg (&dev, value, reg);
216 break;
217 case 2:
218 printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
219 SMC_SELECT_BANK (&dev, reg >> 4);
220 SMC_outw (&dev, value, reg & 0xE);
221 break;
222 default:
223 printf ("Wrong\n");
224 break;
225 }
226 break;
227 case ('D'):
228 dump_eeprom (&dev);
229 break;
230 case ('M'):
231 dump_reg (&dev);
232 break;
233 case ('C'):
234 copy_from_eeprom (&dev);
235 break;
236 case ('P'):
237 print_macaddr (&dev);
238 break;
239 default:
240 break;
241 }
242
243 }
244
245 return (0);
246 }
247
248 void copy_from_eeprom (struct eth_device *dev)
249 {
250 int i;
251
252 SMC_SELECT_BANK (dev, 1);
253 SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
254 CTL_RELOAD, CTL_REG);
255 i = 100;
256 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
257 udelay (100);
258 if (i == 0) {
259 printf ("Timeout Refreshing EEPROM registers\n");
260 } else {
261 printf ("EEPROM contents copied to MAC\n");
262 }
263
264 }
265
266 void print_macaddr (struct eth_device *dev)
267 {
268 int i, j, k, mac[6];
269
270 printf ("Current MAC Address in SMSC91111 ");
271 SMC_SELECT_BANK (dev, 1);
272 for (i = 0; i < 5; i++) {
273 printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
274 }
275
276 printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
277
278 i = 0;
279 for (j = 0x20; j < 0x23; j++) {
280 k = read_eeprom_reg (dev, j);
281 mac[i] = k & 0xFF;
282 i++;
283 mac[i] = k >> 8;
284 i++;
285 }
286
287 printf ("Current MAC Address in EEPROM ");
288 for (i = 0; i < 5; i++)
289 printf ("%02x:", mac[i]);
290 printf ("%02x\n", mac[5]);
291
292 }
293 void dump_eeprom (struct eth_device *dev)
294 {
295 int j, k;
296
297 printf ("IOS2-0 ");
298 for (j = 0; j < 8; j++) {
299 printf ("%03x ", j);
300 }
301 printf ("\n");
302
303 for (k = 0; k < 4; k++) {
304 if (k == 0)
305 printf ("CONFIG ");
306 if (k == 1)
307 printf ("BASE ");
308 if ((k == 2) || (k == 3))
309 printf (" ");
310 for (j = 0; j < 0x20; j += 4) {
311 printf ("%02x:%04x ", j + k,
312 read_eeprom_reg (dev, j + k));
313 }
314 printf ("\n");
315 }
316
317 for (j = 0x20; j < 0x40; j++) {
318 if ((j & 0x07) == 0)
319 printf ("\n");
320 printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
321 }
322 printf ("\n");
323
324 }
325
326 int read_eeprom_reg (struct eth_device *dev, int reg)
327 {
328 int timeout;
329
330 SMC_SELECT_BANK (dev, 2);
331 SMC_outw (dev, reg, PTR_REG);
332
333 SMC_SELECT_BANK (dev, 1);
334 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
335 CTL_RELOAD, CTL_REG);
336 timeout = 100;
337 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
338 udelay (100);
339 if (timeout == 0) {
340 printf ("Timeout Reading EEPROM register %02x\n", reg);
341 return 0;
342 }
343
344 return SMC_inw (dev, GP_REG);
345
346 }
347
348 int write_eeprom_reg (struct eth_device *dev, int value, int reg)
349 {
350 int timeout;
351
352 SMC_SELECT_BANK (dev, 2);
353 SMC_outw (dev, reg, PTR_REG);
354
355 SMC_SELECT_BANK (dev, 1);
356 SMC_outw (dev, value, GP_REG);
357 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
358 CTL_STORE, CTL_REG);
359 timeout = 100;
360 while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
361 udelay (100);
362 if (timeout == 0) {
363 printf ("Timeout Writing EEPROM register %02x\n", reg);
364 return 0;
365 }
366
367 return 1;
368
369 }
370
371 void dump_reg (struct eth_device *dev)
372 {
373 int i, j;
374
375 printf (" ");
376 for (j = 0; j < 4; j++) {
377 printf ("Bank%i ", j);
378 }
379 printf ("\n");
380 for (i = 0; i < 0xF; i += 2) {
381 printf ("%02x ", i);
382 for (j = 0; j < 4; j++) {
383 SMC_SELECT_BANK (dev, j);
384 printf ("%04x ", SMC_inw (dev, i));
385 }
386 printf ("\n");
387 }
388 }