1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <common.h>
15#include <exports.h>
16#include "../drivers/net/smc91111.h"
17
18#ifndef SMC91111_EEPROM_INIT
19# define SMC91111_EEPROM_INIT()
20#endif
21
22#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
23#define EEPROM 0x1
24#define MAC 0x2
25#define UNKNOWN 0x4
26
27void dump_reg (struct eth_device *dev);
28void dump_eeprom (struct eth_device *dev);
29int write_eeprom_reg (struct eth_device *dev, int value, int reg);
30void copy_from_eeprom (struct eth_device *dev);
31void print_MAC (struct eth_device *dev);
32int read_eeprom_reg (struct eth_device *dev, int reg);
33void print_macaddr (struct eth_device *dev);
34
35int smc91111_eeprom (int argc, char * const argv[])
36{
37 int c, i, j, done, line, reg, value, start, what;
38 char input[50];
39
40 struct eth_device dev;
41 dev.iobase = CONFIG_SMC91111_BASE;
42
43
44 app_startup (argv);
45 if (XF_VERSION != (int) get_version ()) {
46 printf ("Expects ABI version %d\n", XF_VERSION);
47 printf ("Actual U-Boot ABI version %d\n",
48 (int) get_version ());
49 printf ("Can't run\n\n");
50 return (0);
51 }
52
53 SMC91111_EEPROM_INIT();
54
55 if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
56 printf ("Can't find SMSC91111\n");
57 return (0);
58 }
59
60 done = 0;
61 what = UNKNOWN;
62 printf ("\n");
63 while (!done) {
64
65 printf ("SMC91111> ");
66 line = 0;
67 i = 0;
68 start = 1;
69 while (!line) {
70
71 while (!tstc ());
72
73 c = getc ();
74
75 if (c >= 'Z')
76 c -= ('a' - 'A');
77
78
79 switch (c) {
80 case '\r':
81 case '\n':
82 input[i] = 0;
83 puts ("\r\n");
84 line = 1;
85 break;
86 case '\0':
87 continue;
88
89 case 0x03:
90 input[0] = 0;
91 i = 0;
92 line = 1;
93 done = 1;
94 break;
95
96 case 0x5F:
97 case 0x08:
98 case 0x7F:
99 if (i > 0) {
100 puts ("\b \b");
101 i--;
102 }
103 break;
104 default:
105 if (start) {
106 if ((c == 'W') || (c == 'D')
107 || (c == 'M') || (c == 'C')
108 || (c == 'P')) {
109 putc (c);
110 input[i] = c;
111 if (i <= 45)
112 i++;
113 start = 0;
114 }
115 } else {
116 if ((c >= '0' && c <= '9')
117 || (c >= 'A' && c <= 'F')
118 || (c == 'E') || (c == 'M')
119 || (c == ' ')) {
120 putc (c);
121 input[i] = c;
122 if (i <= 45)
123 i++;
124 break;
125 }
126 }
127 break;
128 }
129 }
130
131 for (; i < 49; i++)
132 input[i] = 0;
133
134 switch (input[0]) {
135 case ('W'):
136
137 i = 0;
138 reg = 0;
139 value = 0;
140
141 while ((input[i] != ' ') && (input[i] != 0))
142 i++;
143
144 if (input[i] != 0)
145 i++;
146
147
148 switch (input[i]) {
149 case ('E'):
150 what = EEPROM;
151 break;
152 case ('M'):
153 what = MAC;
154 break;
155 default:
156 what = UNKNOWN;
157 break;
158 }
159
160
161 while ((input[i] != ' ') && (input[i] != 0))
162 i++;
163 if (input[i] != 0)
164 i++;
165
166
167 j = 0;
168 while ((input[i] != ' ') && (input[i] != 0)) {
169 j = input[i] - 0x30;
170 if (j >= 0xA) {
171 j -= 0x07;
172 }
173 reg = (reg * 0x10) + j;
174 i++;
175 }
176
177 while ((input[i] != ' ') && (input[i] != 0))
178 i++;
179
180 if (input[i] != 0)
181 i++;
182 else
183 what = UNKNOWN;
184
185
186 j = 0;
187 while ((input[i] != ' ') && (input[i] != 0)) {
188 j = input[i] - 0x30;
189 if (j >= 0xA) {
190 j -= 0x07;
191 }
192 value = (value * 0x10) + j;
193 i++;
194 }
195
196 switch (what) {
197 case 1:
198 printf ("Writing EEPROM register %02x with %04x\n", reg, value);
199 write_eeprom_reg (&dev, value, reg);
200 break;
201 case 2:
202 printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
203 SMC_SELECT_BANK (&dev, reg >> 4);
204 SMC_outw (&dev, value, reg & 0xE);
205 break;
206 default:
207 printf ("Wrong\n");
208 break;
209 }
210 break;
211 case ('D'):
212 dump_eeprom (&dev);
213 break;
214 case ('M'):
215 dump_reg (&dev);
216 break;
217 case ('C'):
218 copy_from_eeprom (&dev);
219 break;
220 case ('P'):
221 print_macaddr (&dev);
222 break;
223 default:
224 break;
225 }
226
227 }
228
229 return (0);
230}
231
232void copy_from_eeprom (struct eth_device *dev)
233{
234 int i;
235
236 SMC_SELECT_BANK (dev, 1);
237 SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
238 CTL_RELOAD, CTL_REG);
239 i = 100;
240 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
241 udelay (100);
242 if (i == 0) {
243 printf ("Timeout Refreshing EEPROM registers\n");
244 } else {
245 printf ("EEPROM contents copied to MAC\n");
246 }
247
248}
249
250void print_macaddr (struct eth_device *dev)
251{
252 int i, j, k, mac[6];
253
254 printf ("Current MAC Address in SMSC91111 ");
255 SMC_SELECT_BANK (dev, 1);
256 for (i = 0; i < 5; i++) {
257 printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
258 }
259
260 printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
261
262 i = 0;
263 for (j = 0x20; j < 0x23; j++) {
264 k = read_eeprom_reg (dev, j);
265 mac[i] = k & 0xFF;
266 i++;
267 mac[i] = k >> 8;
268 i++;
269 }
270
271 printf ("Current MAC Address in EEPROM ");
272 for (i = 0; i < 5; i++)
273 printf ("%02x:", mac[i]);
274 printf ("%02x\n", mac[5]);
275
276}
277void dump_eeprom (struct eth_device *dev)
278{
279 int j, k;
280
281 printf ("IOS2-0 ");
282 for (j = 0; j < 8; j++) {
283 printf ("%03x ", j);
284 }
285 printf ("\n");
286
287 for (k = 0; k < 4; k++) {
288 if (k == 0)
289 printf ("CONFIG ");
290 if (k == 1)
291 printf ("BASE ");
292 if ((k == 2) || (k == 3))
293 printf (" ");
294 for (j = 0; j < 0x20; j += 4) {
295 printf ("%02x:%04x ", j + k,
296 read_eeprom_reg (dev, j + k));
297 }
298 printf ("\n");
299 }
300
301 for (j = 0x20; j < 0x40; j++) {
302 if ((j & 0x07) == 0)
303 printf ("\n");
304 printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
305 }
306 printf ("\n");
307
308}
309
310int read_eeprom_reg (struct eth_device *dev, int reg)
311{
312 int timeout;
313
314 SMC_SELECT_BANK (dev, 2);
315 SMC_outw (dev, reg, PTR_REG);
316
317 SMC_SELECT_BANK (dev, 1);
318 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
319 CTL_RELOAD, CTL_REG);
320 timeout = 100;
321 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
322 udelay (100);
323 if (timeout == 0) {
324 printf ("Timeout Reading EEPROM register %02x\n", reg);
325 return 0;
326 }
327
328 return SMC_inw (dev, GP_REG);
329
330}
331
332int write_eeprom_reg (struct eth_device *dev, int value, int reg)
333{
334 int timeout;
335
336 SMC_SELECT_BANK (dev, 2);
337 SMC_outw (dev, reg, PTR_REG);
338
339 SMC_SELECT_BANK (dev, 1);
340 SMC_outw (dev, value, GP_REG);
341 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
342 CTL_STORE, CTL_REG);
343 timeout = 100;
344 while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
345 udelay (100);
346 if (timeout == 0) {
347 printf ("Timeout Writing EEPROM register %02x\n", reg);
348 return 0;
349 }
350
351 return 1;
352
353}
354
355void dump_reg (struct eth_device *dev)
356{
357 int i, j;
358
359 printf (" ");
360 for (j = 0; j < 4; j++) {
361 printf ("Bank%i ", j);
362 }
363 printf ("\n");
364 for (i = 0; i < 0xF; i += 2) {
365 printf ("%02x ", i);
366 for (j = 0; j < 4; j++) {
367 SMC_SELECT_BANK (dev, j);
368 printf ("%04x ", SMC_inw (dev, i));
369 }
370 printf ("\n");
371 }
372}
373