Blame view

examples/standalone/smc91111_eeprom.c 7.17 KB
5a95f6fbd   wdenk   * Patch by Robin ...
1
2
3
4
  /*
   * (C) Copyright 2004
   * Robin Getz rgetz@blacfin.uclinux.org
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
5a95f6fbd   wdenk   * Patch by Robin ...
6
7
8
   *
   * Heavily borrowed from the following peoples GPL'ed software:
   *  - Wolfgang Denk, DENX Software Engineering, wd@denx.de
a187559e3   Bin Meng   Use correct spell...
9
   *       Das U-Boot
5a95f6fbd   wdenk   * Patch by Robin ...
10
11
12
13
14
15
   *  - Ladislav Michl ladis@linux-mips.org
   *       A rejected patch on the U-Boot mailing list
   */
  
  #include <common.h>
  #include <exports.h>
2439e4bfa   Jean-Christophe PLAGNIOL-VILLARD   drivers/net : mov...
16
  #include "../drivers/net/smc91111.h"
5a95f6fbd   wdenk   * Patch by Robin ...
17

b196ca755   Mike Frysinger   smc91111_eeprom: ...
18
19
  #ifndef SMC91111_EEPROM_INIT
  # define SMC91111_EEPROM_INIT()
6b9097e5e   Mike Frysinger   use C code rather...
20
  #endif
5a95f6fbd   wdenk   * Patch by Robin ...
21
  #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
b196ca755   Mike Frysinger   smc91111_eeprom: ...
22
23
24
  #define EEPROM		0x1
  #define MAC		0x2
  #define UNKNOWN		0x4
5a95f6fbd   wdenk   * Patch by Robin ...
25

7194ab809   Ben Warren   Convert SMC91111 ...
26
27
28
29
30
31
32
  void dump_reg (struct eth_device *dev);
  void dump_eeprom (struct eth_device *dev);
  int write_eeprom_reg (struct eth_device *dev, int value, int reg);
  void copy_from_eeprom (struct eth_device *dev);
  void print_MAC (struct eth_device *dev);
  int read_eeprom_reg (struct eth_device *dev, int reg);
  void print_macaddr (struct eth_device *dev);
5a95f6fbd   wdenk   * Patch by Robin ...
33

54841ab50   Wolfgang Denk   Make sure that ar...
34
  int smc91111_eeprom (int argc, char * const argv[])
5a95f6fbd   wdenk   * Patch by Robin ...
35
36
37
  {
  	int c, i, j, done, line, reg, value, start, what;
  	char input[50];
c4168af3b   Mike Frysinger   smc91111_eeprom: ...
38
39
  	struct eth_device dev;
  	dev.iobase = CONFIG_SMC91111_BASE;
7194ab809   Ben Warren   Convert SMC91111 ...
40

5a95f6fbd   wdenk   * Patch by Robin ...
41
42
43
44
45
46
47
48
49
50
51
52
53
  	/* Print the ABI version */
  	app_startup (argv);
  	if (XF_VERSION != (int) get_version ()) {
  		printf ("Expects ABI version %d
  ", XF_VERSION);
  		printf ("Actual U-Boot ABI version %d
  ",
  			(int) get_version ());
  		printf ("Can't run
  
  ");
  		return (0);
  	}
b196ca755   Mike Frysinger   smc91111_eeprom: ...
54
  	SMC91111_EEPROM_INIT();
5a95f6fbd   wdenk   * Patch by Robin ...
55

7194ab809   Ben Warren   Convert SMC91111 ...
56
  	if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
5a95f6fbd   wdenk   * Patch by Robin ...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  		printf ("Can't find SMSC91111
  ");
  		return (0);
  	}
  
  	done = 0;
  	what = UNKNOWN;
  	printf ("
  ");
  	while (!done) {
  		/* print the prompt */
  		printf ("SMC91111> ");
  		line = 0;
  		i = 0;
  		start = 1;
  		while (!line) {
  			/* Wait for a keystroke */
  			while (!tstc ());
  
  			c = getc ();
  			/* Make Uppercase */
  			if (c >= 'Z')
  				c -= ('a' - 'A');
  			/* printf(" |%02x| ",c); */
  
  			switch (c) {
  			case '\r':	/* Enter                */
  			case '
  ':
  				input[i] = 0;
  				puts ("\r
  ");
  				line = 1;
  				break;
  			case '\0':	/* nul                  */
  				continue;
  
  			case 0x03:	/* ^C - break           */
  				input[0] = 0;
  				i = 0;
  				line = 1;
  				done = 1;
  				break;
  
  			case 0x5F:
  			case 0x08:	/* ^H  - backspace      */
  			case 0x7F:	/* DEL - backspace      */
  				if (i > 0) {
  					puts ("\b \b");
  					i--;
  				}
  				break;
  			default:
  				if (start) {
  					if ((c == 'W') || (c == 'D')
  					    || (c == 'M') || (c == 'C')
  					    || (c == 'P')) {
  						putc (c);
  						input[i] = c;
  						if (i <= 45)
  							i++;
  						start = 0;
  					}
  				} else {
  					if ((c >= '0' && c <= '9')
  					    || (c >= 'A' && c <= 'F')
  					    || (c == 'E') || (c == 'M')
  					    || (c == ' ')) {
  						putc (c);
  						input[i] = c;
  						if (i <= 45)
  							i++;
  						break;
  					}
  				}
  				break;
  			}
  		}
  
  		for (; i < 49; i++)
  			input[i] = 0;
  
  		switch (input[0]) {
  		case ('W'):
  			/* Line should be w reg value */
  			i = 0;
  			reg = 0;
  			value = 0;
  			/* Skip to the next space or end) */
  			while ((input[i] != ' ') && (input[i] != 0))
  				i++;
  
  			if (input[i] != 0)
  				i++;
  
  			/* Are we writing to EEPROM or MAC */
  			switch (input[i]) {
  			case ('E'):
  				what = EEPROM;
  				break;
  			case ('M'):
  				what = MAC;
  				break;
  			default:
  				what = UNKNOWN;
  				break;
  			}
  
  			/* skip to the next space or end */
  			while ((input[i] != ' ') && (input[i] != 0))
  				i++;
  			if (input[i] != 0)
  				i++;
  
  			/* Find register to write into */
  			j = 0;
  			while ((input[i] != ' ') && (input[i] != 0)) {
  				j = input[i] - 0x30;
  				if (j >= 0xA) {
  					j -= 0x07;
  				}
  				reg = (reg * 0x10) + j;
  				i++;
  			}
  
  			while ((input[i] != ' ') && (input[i] != 0))
  				i++;
  
  			if (input[i] != 0)
  				i++;
  			else
  				what = UNKNOWN;
  
  			/* Get the value to write */
  			j = 0;
  			while ((input[i] != ' ') && (input[i] != 0)) {
  				j = input[i] - 0x30;
  				if (j >= 0xA) {
  					j -= 0x07;
  				}
  				value = (value * 0x10) + j;
  				i++;
  			}
  
  			switch (what) {
  			case 1:
0afe519a4   Wolfgang Denk   Add ADI Blackfin ...
203
204
  				printf ("Writing EEPROM register %02x with %04x
  ", reg, value);
7194ab809   Ben Warren   Convert SMC91111 ...
205
  				write_eeprom_reg (&dev, value, reg);
5a95f6fbd   wdenk   * Patch by Robin ...
206
207
  				break;
  			case 2:
0afe519a4   Wolfgang Denk   Add ADI Blackfin ...
208
209
  				printf ("Writing MAC register bank %i, reg %02x with %04x
  ", reg >> 4, reg & 0xE, value);
7194ab809   Ben Warren   Convert SMC91111 ...
210
211
  				SMC_SELECT_BANK (&dev, reg >> 4);
  				SMC_outw (&dev, value, reg & 0xE);
5a95f6fbd   wdenk   * Patch by Robin ...
212
213
214
215
216
217
218
219
  				break;
  			default:
  				printf ("Wrong
  ");
  				break;
  			}
  			break;
  		case ('D'):
7194ab809   Ben Warren   Convert SMC91111 ...
220
  			dump_eeprom (&dev);
5a95f6fbd   wdenk   * Patch by Robin ...
221
222
  			break;
  		case ('M'):
7194ab809   Ben Warren   Convert SMC91111 ...
223
  			dump_reg (&dev);
5a95f6fbd   wdenk   * Patch by Robin ...
224
225
  			break;
  		case ('C'):
7194ab809   Ben Warren   Convert SMC91111 ...
226
  			copy_from_eeprom (&dev);
5a95f6fbd   wdenk   * Patch by Robin ...
227
228
  			break;
  		case ('P'):
7194ab809   Ben Warren   Convert SMC91111 ...
229
  			print_macaddr (&dev);
5a95f6fbd   wdenk   * Patch by Robin ...
230
231
232
233
234
235
236
237
238
  			break;
  		default:
  			break;
  		}
  
  	}
  
  	return (0);
  }
7194ab809   Ben Warren   Convert SMC91111 ...
239
  void copy_from_eeprom (struct eth_device *dev)
5a95f6fbd   wdenk   * Patch by Robin ...
240
241
  {
  	int i;
7194ab809   Ben Warren   Convert SMC91111 ...
242
243
244
  	SMC_SELECT_BANK (dev, 1);
  	SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
  		CTL_RELOAD, CTL_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
245
  	i = 100;
7194ab809   Ben Warren   Convert SMC91111 ...
246
  	while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
5a95f6fbd   wdenk   * Patch by Robin ...
247
248
249
250
251
252
253
254
255
256
  		udelay (100);
  	if (i == 0) {
  		printf ("Timeout Refreshing EEPROM registers
  ");
  	} else {
  		printf ("EEPROM contents copied to MAC
  ");
  	}
  
  }
7194ab809   Ben Warren   Convert SMC91111 ...
257
  void print_macaddr (struct eth_device *dev)
5a95f6fbd   wdenk   * Patch by Robin ...
258
259
260
261
  {
  	int i, j, k, mac[6];
  
  	printf ("Current MAC Address in SMSC91111 ");
7194ab809   Ben Warren   Convert SMC91111 ...
262
  	SMC_SELECT_BANK (dev, 1);
5a95f6fbd   wdenk   * Patch by Robin ...
263
  	for (i = 0; i < 5; i++) {
7194ab809   Ben Warren   Convert SMC91111 ...
264
  		printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
5a95f6fbd   wdenk   * Patch by Robin ...
265
  	}
7194ab809   Ben Warren   Convert SMC91111 ...
266
267
  	printf ("%02x
  ", SMC_inb (dev, ADDR0_REG + 5));
5a95f6fbd   wdenk   * Patch by Robin ...
268
269
270
  
  	i = 0;
  	for (j = 0x20; j < 0x23; j++) {
7194ab809   Ben Warren   Convert SMC91111 ...
271
  		k = read_eeprom_reg (dev, j);
5a95f6fbd   wdenk   * Patch by Robin ...
272
273
274
275
276
277
278
279
280
281
282
283
284
  		mac[i] = k & 0xFF;
  		i++;
  		mac[i] = k >> 8;
  		i++;
  	}
  
  	printf ("Current MAC Address in EEPROM    ");
  	for (i = 0; i < 5; i++)
  		printf ("%02x:", mac[i]);
  	printf ("%02x
  ", mac[5]);
  
  }
7194ab809   Ben Warren   Convert SMC91111 ...
285
  void dump_eeprom (struct eth_device *dev)
5a95f6fbd   wdenk   * Patch by Robin ...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  {
  	int j, k;
  
  	printf ("IOS2-0    ");
  	for (j = 0; j < 8; j++) {
  		printf ("%03x     ", j);
  	}
  	printf ("
  ");
  
  	for (k = 0; k < 4; k++) {
  		if (k == 0)
  			printf ("CONFIG ");
  		if (k == 1)
  			printf ("BASE   ");
  		if ((k == 2) || (k == 3))
  			printf ("       ");
  		for (j = 0; j < 0x20; j += 4) {
7194ab809   Ben Warren   Convert SMC91111 ...
304
305
  			printf ("%02x:%04x ", j + k,
  				read_eeprom_reg (dev, j + k));
5a95f6fbd   wdenk   * Patch by Robin ...
306
307
308
309
310
311
312
313
314
  		}
  		printf ("
  ");
  	}
  
  	for (j = 0x20; j < 0x40; j++) {
  		if ((j & 0x07) == 0)
  			printf ("
  ");
7194ab809   Ben Warren   Convert SMC91111 ...
315
  		printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
5a95f6fbd   wdenk   * Patch by Robin ...
316
317
318
319
320
  	}
  	printf ("
  ");
  
  }
7194ab809   Ben Warren   Convert SMC91111 ...
321
  int read_eeprom_reg (struct eth_device *dev, int reg)
5a95f6fbd   wdenk   * Patch by Robin ...
322
323
  {
  	int timeout;
7194ab809   Ben Warren   Convert SMC91111 ...
324
325
  	SMC_SELECT_BANK (dev, 2);
  	SMC_outw (dev, reg, PTR_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
326

7194ab809   Ben Warren   Convert SMC91111 ...
327
328
329
  	SMC_SELECT_BANK (dev, 1);
  	SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
  		CTL_RELOAD, CTL_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
330
  	timeout = 100;
7194ab809   Ben Warren   Convert SMC91111 ...
331
  	while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
5a95f6fbd   wdenk   * Patch by Robin ...
332
333
334
335
336
337
  		udelay (100);
  	if (timeout == 0) {
  		printf ("Timeout Reading EEPROM register %02x
  ", reg);
  		return 0;
  	}
7194ab809   Ben Warren   Convert SMC91111 ...
338
  	return SMC_inw (dev, GP_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
339
340
  
  }
7194ab809   Ben Warren   Convert SMC91111 ...
341
  int write_eeprom_reg (struct eth_device *dev, int value, int reg)
5a95f6fbd   wdenk   * Patch by Robin ...
342
343
  {
  	int timeout;
7194ab809   Ben Warren   Convert SMC91111 ...
344
345
  	SMC_SELECT_BANK (dev, 2);
  	SMC_outw (dev, reg, PTR_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
346

7194ab809   Ben Warren   Convert SMC91111 ...
347
348
349
350
  	SMC_SELECT_BANK (dev, 1);
  	SMC_outw (dev, value, GP_REG);
  	SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
  		CTL_STORE, CTL_REG);
5a95f6fbd   wdenk   * Patch by Robin ...
351
  	timeout = 100;
7194ab809   Ben Warren   Convert SMC91111 ...
352
  	while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
5a95f6fbd   wdenk   * Patch by Robin ...
353
354
355
356
357
358
359
360
361
362
  		udelay (100);
  	if (timeout == 0) {
  		printf ("Timeout Writing EEPROM register %02x
  ", reg);
  		return 0;
  	}
  
  	return 1;
  
  }
7194ab809   Ben Warren   Convert SMC91111 ...
363
  void dump_reg (struct eth_device *dev)
5a95f6fbd   wdenk   * Patch by Robin ...
364
365
366
367
368
369
370
371
372
373
374
375
  {
  	int i, j;
  
  	printf ("    ");
  	for (j = 0; j < 4; j++) {
  		printf ("Bank%i ", j);
  	}
  	printf ("
  ");
  	for (i = 0; i < 0xF; i += 2) {
  		printf ("%02x  ", i);
  		for (j = 0; j < 4; j++) {
7194ab809   Ben Warren   Convert SMC91111 ...
376
377
  			SMC_SELECT_BANK (dev, j);
  			printf ("%04x  ", SMC_inw (dev, i));
5a95f6fbd   wdenk   * Patch by Robin ...
378
379
380
381
382
  		}
  		printf ("
  ");
  	}
  }