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