km/scripts: search for kernel/DTBs at serverip:/PRODUCTNAME via TFTP in develop mode
[oweals/u-boot.git] / examples / standalone / smc91111_eeprom.c
1 /*
2  * (C) Copyright 2004
3  * Robin Getz rgetz@blacfin.uclinux.org
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  *
7  * Heavily borrowed from the following peoples GPL'ed software:
8  *  - Wolfgang Denk, DENX Software Engineering, wd@denx.de
9  *       Das U-boot
10  *  - Ladislav Michl ladis@linux-mips.org
11  *       A rejected patch on the U-Boot mailing list
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
27 void dump_reg (struct eth_device *dev);
28 void dump_eeprom (struct eth_device *dev);
29 int write_eeprom_reg (struct eth_device *dev, int value, int reg);
30 void copy_from_eeprom (struct eth_device *dev);
31 void print_MAC (struct eth_device *dev);
32 int read_eeprom_reg (struct eth_device *dev, int reg);
33 void print_macaddr (struct eth_device *dev);
34
35 int 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         /* Print the ABI version */
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                 /* print the prompt */
65                 printf ("SMC91111> ");
66                 line = 0;
67                 i = 0;
68                 start = 1;
69                 while (!line) {
70                         /* Wait for a keystroke */
71                         while (!tstc ());
72
73                         c = getc ();
74                         /* Make Uppercase */
75                         if (c >= 'Z')
76                                 c -= ('a' - 'A');
77                         /* printf(" |%02x| ",c); */
78
79                         switch (c) {
80                         case '\r':      /* Enter                */
81                         case '\n':
82                                 input[i] = 0;
83                                 puts ("\r\n");
84                                 line = 1;
85                                 break;
86                         case '\0':      /* nul                  */
87                                 continue;
88
89                         case 0x03:      /* ^C - break           */
90                                 input[0] = 0;
91                                 i = 0;
92                                 line = 1;
93                                 done = 1;
94                                 break;
95
96                         case 0x5F:
97                         case 0x08:      /* ^H  - backspace      */
98                         case 0x7F:      /* DEL - backspace      */
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                         /* Line should be w reg value */
137                         i = 0;
138                         reg = 0;
139                         value = 0;
140                         /* Skip to the next space or end) */
141                         while ((input[i] != ' ') && (input[i] != 0))
142                                 i++;
143
144                         if (input[i] != 0)
145                                 i++;
146
147                         /* Are we writing to EEPROM or MAC */
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                         /* skip to the next space or end */
161                         while ((input[i] != ' ') && (input[i] != 0))
162                                 i++;
163                         if (input[i] != 0)
164                                 i++;
165
166                         /* Find register to write into */
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                         /* Get the value to write */
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
232 void 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
250 void 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 }
277 void 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
310 int 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
332 int 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
355 void 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 }