~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to examples/standalone/smc91111_eeprom.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}