Add standalone application to change SMC91C111 MAC addresses, see examples/README.smc91111_eeprom * Patch by Xiaogeng (Shawn) Jin, 12 Oct 2004: Fix Flash support for ARM Integrator CP.master
parent
289f932c5f
commit
5a95f6fbd2
@ -0,0 +1,246 @@ |
||||
This is the readme for the Das U-Boot standalone program smc91111 |
||||
|
||||
The main purpose of this is to manage MAC addresses on platforms |
||||
which include the SMC91111 integrated 10/100 MAC Phy, with attached |
||||
EEPROMs. |
||||
|
||||
|
||||
Contents: |
||||
------------------------ |
||||
1. Ensuring U-boot's MAC address can be set in hardware |
||||
2. Running the smc91111_eeprom program |
||||
3. Setting MAC addresses |
||||
4. Other things you can do with this |
||||
5. Things to be done. |
||||
|
||||
|
||||
1. Ensuring U-boot's MAC address can be set in hardware |
||||
-------------------------------------------------------------------------- |
||||
|
||||
On the Internet - MAC addresses are very important. Short for Media |
||||
Access Control address, a hardware address that uniquely identifies |
||||
each node of a network. When things are not unique - bad things |
||||
can happen. This is why U-Boot makes it difficult to change MAC |
||||
addresses. |
||||
|
||||
To find out who has a MAC address, or to purchase MAC addresses, goto |
||||
the IEEE, at: |
||||
http://standards.ieee.org/regauth/oui/index.shtml |
||||
|
||||
To change your MAC address, there can not be a MAC address predefined in |
||||
U-Boot. To ensure that this does not occur, check your |
||||
include/configs/<board_name>.h file, and check to see that the following |
||||
settings are _not_ or commented out there. |
||||
|
||||
#define HARDCODE_MAC 1 |
||||
#define CONFIG_ETHADDR 02:80:ad:20:31:b8 |
||||
|
||||
The purpose of HARDCODE_MAC is to hardcode the MAC address in software, |
||||
(not what we want), or to preset it to 02:80:ad:20:31:b8 (not what we |
||||
want either). |
||||
|
||||
You can check this in a running U-Boot, by doing a power cycle, then |
||||
before U-Boot tries to do any networking, running the 'printenv' command |
||||
|
||||
BOOT> printenv |
||||
|
||||
ethaddr=02:80:ad:20:31:b8 |
||||
|
||||
If you see the 'ethaddr' variable show up, like the above, you need to |
||||
recompile U-Boot, with the above settings commented out of the |
||||
include/configs/<board_name>.h file. |
||||
|
||||
2. Running the smc91111_eeprom program |
||||
--------------------------------------------------------------------- |
||||
|
||||
After Uboot is compiled, there should be three files of interest: |
||||
-rwxr-xr-x 1 8806 2004-10-11 14:00 smc91111_eeprom <- ELF |
||||
-rwxr-xr-x 1 3440 2004-10-11 14:00 smc91111_eeprom.bin <- BIN |
||||
-rwxr-xr-x 1 9524 2004-10-11 14:00 smc91111_eeprom.srec <- SREC |
||||
|
||||
if there is not, check the examples/Makefile, and ensure there is something |
||||
like for your architecture: |
||||
|
||||
ifeq ($(ARCH),blackfin) |
||||
SREC += smc91111_eeprom.srec |
||||
BIN += smc91111_eeprom.bin smc91111_eeprom |
||||
endif |
||||
|
||||
To load the files: there are two methods: a) serial or b) network. Since |
||||
it is not a good idea to start doing things on the network before the |
||||
MAC address is set, this example will do things over serial. |
||||
|
||||
a) Loading the elf file via the serial port |
||||
-------------------------------------------- |
||||
Loading the elf is very easy - just ensure that the location |
||||
you specify things to load as is not the load address specified |
||||
in the Makefile. |
||||
|
||||
BOOT> loadb 0x1000000 |
||||
|
||||
## Ready for binary (kermit) download to 0x01000000 at 57600 bps... |
||||
|
||||
(type CNTL-\ then C) |
||||
(Back at local machine) |
||||
---------------------------------------------------- |
||||
Kermit>send ~/u-boot_1.1.1/examples/smc91111_eeprom |
||||
Kermit>connect |
||||
|
||||
Connecting to /dev/ttyS0, speed 57600 |
||||
Escape character: Ctrl-\ (ASCII 28, FS): enabled |
||||
Type the escape character followed by C to get back, |
||||
or followed by ? to see other options. |
||||
---------------------------------------------------- |
||||
## Total Size = 0x00002266 = 8806 Bytes |
||||
## Start Addr = 0x01000000 |
||||
|
||||
BOOT> bootelf 0x1000000 |
||||
|
||||
Loading .text @ 0x00001000 (3440 bytes) |
||||
## Starting application at 0x000010d8 ... |
||||
|
||||
SMC91111> |
||||
|
||||
b) Loading the binary file via the serial port |
||||
----------------------------------------------- |
||||
For many toolchains, the entry point is not the load point. |
||||
The Load point is a hard coded address from the |
||||
examples/Makefile. The entry point can be found by doing something |
||||
like: |
||||
|
||||
u-boot_1.1.1/examples> bfin-elf-objdump -d smc91111_eeprom |less |
||||
|
||||
smc91111_eeprom: file format elf32-bfin |
||||
|
||||
Disassembly of section .text: |
||||
|
||||
00001000 <smc91111_eeprom-0xd8>: |
||||
1000: |
||||
000010d8 <smc91111_eeprom>: |
||||
|
||||
You can see that the entry point (or the address that should be |
||||
jumped to is 0x10d8). This is also the same as the entry point |
||||
of the elf file. |
||||
|
||||
Now we load it to the actual load location: |
||||
|
||||
BOOT> loadb 0x1000 |
||||
|
||||
## Ready for binary (kermit) download to 0x00001000 at 57600 bps... |
||||
|
||||
(Back at pinky.dsl-only.net) |
||||
---------------------------------------------------- |
||||
Kermit>send /tftpboot/eeprom.bin |
||||
Kermit>connect |
||||
|
||||
Connecting to /dev/ttyS0, speed 57600 |
||||
Escape character: Ctrl-\ (ASCII 28, FS): enabled |
||||
Type the escape character followed by C to get back, |
||||
or followed by ? to see other options. |
||||
---------------------------------------------------- |
||||
## Total Size = 0x00000d70 = 3440 Bytes |
||||
## Start Addr = 0x00001000 |
||||
|
||||
BOOT> go 0x10D8 |
||||
|
||||
## Starting application at 0x000010D8 ... |
||||
|
||||
SMC91111> |
||||
|
||||
3. Setting MAC addresses |
||||
-------------------------------------------------------------------------- |
||||
|
||||
The MAC address can be stored in four locations: |
||||
|
||||
-Boot environmental variable in Flash <- can not change, without |
||||
re-flashing U-boot. |
||||
U-Boot environental variable <- can not change, without |
||||
resetting board/U-Boot |
||||
LAN91C111 Registers <- volitle |
||||
LAN91C111 EEPROM <- Non Volitle |
||||
|
||||
If you have not activated the network, and do not have a hardcoded |
||||
or pre-assigned MAC address in U-boot, the environmental variables |
||||
should be blank, and allow you to set things one time. |
||||
|
||||
To set the EEPROM MAC address to 12:34:56:78:9A:BC |
||||
|
||||
SMC91111> W E 20 3412 |
||||
|
||||
Writing EEPROM register 20 with 3412 |
||||
SMC91111> W E 21 7856 |
||||
|
||||
Writing EEPROM register 21 with 7856 |
||||
SMC91111> W E 22 BC9A |
||||
|
||||
Writing EEPROM register 22 with bc9a |
||||
EEPROM contents copied to MAC |
||||
SMC91111> P |
||||
|
||||
Current MAC Address in SMSC91111 12:34:56:78:9a:bc |
||||
Current MAC Address in EEPROM 12:34:56:78:9a:bc |
||||
|
||||
(CNTRL-C to exit) |
||||
SMC91111> ## Application terminated, rc = 0x0 |
||||
|
||||
BOOT> reset |
||||
U-Boot 1.1.1 (gcc version: 3.3.3) |
||||
Release Version Beta released on Oct 10 2004 - 00:34:35 |
||||
Blackfin support by LG Soft India |
||||
For further information please check this link http://www.blackfin.uclinux.org |
||||
BOOT> ping 192.168.0.4 |
||||
|
||||
Using MAC Address 12:34:56:78:9A:BC |
||||
host 192.168.0.4 is alive |
||||
|
||||
|
||||
4. Other things that you can do |
||||
-------------------------------------------------------------------------- |
||||
After the stand alone application is running, there are a few options: |
||||
- P : Print the MAC |
||||
- D : Dump the LAN91C111 EEPROM contents |
||||
- M : Dump the LAN91C111 MAC contents |
||||
- C : Copies the MAC address from the EEPROM to the LAN91C111 |
||||
- W : Write a register in the EEPROM or in the MAC |
||||
|
||||
SMC91111> P |
||||
|
||||
Current MAC Address in SMSC91111 12:34:56:78:9a:bc |
||||
Current MAC Address in EEPROM 12:34:56:78:9a:bc |
||||
|
||||
SMC91111> D |
||||
|
||||
IOS2-0 000 001 002 003 004 005 006 007 |
||||
CONFIG 00:ffff 04:ffff 08:ffff 0c:ffff 10:ffff 14:ffff 18:ffff 1c:ffff |
||||
BASE 01:ffff 05:ffff 09:ffff 0d:ffff 11:ffff 15:ffff 19:ffff 1d:ffff |
||||
02:ffff 06:ffff 0a:ffff 0e:0020 12:ffff 16:ffff 1a:ffff 1e:ffff |
||||
03:ffff 07:ffff 0b:ffff 0f:ffff 13:ffff 17:ffff 1b:ffff 1f:ffff |
||||
|
||||
20:3412 21:7856 22:bc9a 23:ffff 24:ffff 25:ffff 26:ffff 27:ffff |
||||
28:ffff 29:ffff 2a:ffff 2b:ffff 2c:ffff 2d:ffff 2e:ffff 2f:ffff |
||||
30:ffff 31:ffff 32:ffff 33:ffff 34:ffff 35:ffff 36:ffff 37:ffff |
||||
38:ffff 39:ffff 3a:ffff 3b:ffff 3c:ffff 3d:ffff 3e:ffff 3f:ffff |
||||
|
||||
SMC91111> M |
||||
|
||||
Bank0 Bank1 Bank2 Bank3 |
||||
00 0000 a0b1 3332 0000 |
||||
02 0000 1801 8000 0000 |
||||
04 0000 3412 8080 0000 |
||||
06 0000 7856 003f 0000 |
||||
08 0404 bc9a 02df 3332 |
||||
0a 0000 ffff 02df 3391 |
||||
0c 0000 1214 0004 001f |
||||
0e 3300 3301 3302 3303 |
||||
|
||||
SMC91111> C |
||||
|
||||
EEPROM contents copied to MAC |
||||
|
||||
SMC91111> W E 2A ABCD |
||||
|
||||
Writing EEPROM register 2a with abcd |
||||
|
||||
SMC91111> W M 14 FF00 |
||||
|
||||
Writing MAC register bank 1, reg 04 with ff00 |
@ -0,0 +1,391 @@ |
||||
/*
|
||||
* (C) Copyright 2004 |
||||
* Robin Getz rgetz@blacfin.uclinux.org |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Heavily borrowed from the following peoples GPL'ed software: |
||||
* - Wolfgang Denk, DENX Software Engineering, wd@denx.de |
||||
* Das U-boot |
||||
* - Ladislav Michl ladis@linux-mips.org |
||||
* A rejected patch on the U-Boot mailing list |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <exports.h> |
||||
#include "../drivers/smc91111.h" |
||||
|
||||
#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE |
||||
#define EEPROM 0x1; |
||||
#define MAC 0x2; |
||||
#define UNKNOWN 0x4; |
||||
|
||||
void dump_reg (void); |
||||
void dump_eeprom (void); |
||||
int write_eeprom_reg (int, int); |
||||
void copy_from_eeprom (void); |
||||
void print_MAC (void); |
||||
int read_eeprom_reg (int); |
||||
void print_macaddr (void); |
||||
|
||||
int smc91111_eeprom (int argc, char *argv[]) |
||||
{ |
||||
int c, i, j, done, line, reg, value, start, what; |
||||
char input[50]; |
||||
|
||||
/* Print the ABI version */ |
||||
app_startup (argv); |
||||
if (XF_VERSION != (int) get_version ()) { |
||||
printf ("Expects ABI version %d\n", XF_VERSION); |
||||
printf ("Actual U-Boot ABI version %d\n", |
||||
(int) get_version ()); |
||||
printf ("Can't run\n\n"); |
||||
return (0); |
||||
} |
||||
|
||||
asm ("p2.h = 0xFFC0;"); |
||||
asm ("p2.l = 0x0730;"); |
||||
asm ("r0 = 0x01;"); |
||||
asm ("w[p2] = r0;"); |
||||
asm ("ssync;"); |
||||
|
||||
asm ("p2.h = 0xffc0;"); |
||||
asm ("p2.l = 0x0708;"); |
||||
asm ("r0 = 0x01;"); |
||||
asm ("w[p2] = r0;"); |
||||
asm ("ssync;"); |
||||
|
||||
if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { |
||||
printf ("Can't find SMSC91111\n"); |
||||
return (0); |
||||
} |
||||
|
||||
done = 0; |
||||
what = UNKNOWN; |
||||
printf ("\n"); |
||||
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 '\n': |
||||
input[i] = 0; |
||||
puts ("\r\n"); |
||||
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: |
||||
printf ("Writing EEPROM register %02x with %04x\n", |
||||
reg, value); |
||||
write_eeprom_reg (value, reg); |
||||
break; |
||||
case 2: |
||||
printf ("Writing MAC register bank %i, |
||||
reg %02x with %04x\n", reg >> 4, reg & 0xE, value); |
||||
SMC_SELECT_BANK (reg >> 4); |
||||
SMC_outw (value, reg & 0xE); |
||||
break; |
||||
default: |
||||
printf ("Wrong\n"); |
||||
break; |
||||
} |
||||
break; |
||||
case ('D'): |
||||
dump_eeprom (); |
||||
break; |
||||
case ('M'): |
||||
dump_reg (); |
||||
break; |
||||
case ('C'): |
||||
copy_from_eeprom (); |
||||
break; |
||||
case ('P'): |
||||
print_macaddr (); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
} |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
void copy_from_eeprom (void) |
||||
{ |
||||
int i; |
||||
|
||||
SMC_SELECT_BANK (1); |
||||
SMC_outw ((SMC_inw (CTL_REG) & !CTL_EEPROM_SELECT) | CTL_RELOAD, |
||||
CTL_REG); |
||||
i = 100; |
||||
while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --i) |
||||
udelay (100); |
||||
if (i == 0) { |
||||
printf ("Timeout Refreshing EEPROM registers\n"); |
||||
} else { |
||||
printf ("EEPROM contents copied to MAC\n"); |
||||
} |
||||
|
||||
} |
||||
|
||||
void print_macaddr (void) |
||||
{ |
||||
int i, j, k, mac[6]; |
||||
|
||||
printf ("Current MAC Address in SMSC91111 "); |
||||
SMC_SELECT_BANK (1); |
||||
for (i = 0; i < 5; i++) { |
||||
printf ("%02x:", SMC_inb (ADDR0_REG + i)); |
||||
} |
||||
|
||||
printf ("%02x\n", SMC_inb (ADDR0_REG + 5)); |
||||
|
||||
i = 0; |
||||
for (j = 0x20; j < 0x23; j++) { |
||||
k = read_eeprom_reg (j); |
||||
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\n", mac[5]); |
||||
|
||||
} |
||||
void dump_eeprom (void) |
||||
{ |
||||
int j, k; |
||||
|
||||
printf ("IOS2-0 "); |
||||
for (j = 0; j < 8; j++) { |
||||
printf ("%03x ", j); |
||||
} |
||||
printf ("\n"); |
||||
|
||||
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) { |
||||
printf ("%02x:%04x ", j + k, read_eeprom_reg (j + k)); |
||||
} |
||||
printf ("\n"); |
||||
} |
||||
|
||||
for (j = 0x20; j < 0x40; j++) { |
||||
if ((j & 0x07) == 0) |
||||
printf ("\n"); |
||||
printf ("%02x:%04x ", j, read_eeprom_reg (j)); |
||||
} |
||||
printf ("\n"); |
||||
|
||||
} |
||||
|
||||
int read_eeprom_reg (int reg) |
||||
{ |
||||
int timeout; |
||||
|
||||
SMC_SELECT_BANK (2); |
||||
SMC_outw (reg, PTR_REG); |
||||
|
||||
SMC_SELECT_BANK (1); |
||||
SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD, |
||||
CTL_REG); |
||||
timeout = 100; |
||||
while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout) |
||||
udelay (100); |
||||
if (timeout == 0) { |
||||
printf ("Timeout Reading EEPROM register %02x\n", reg); |
||||
return 0; |
||||
} |
||||
|
||||
return SMC_inw (GP_REG); |
||||
|
||||
} |
||||
|
||||
int write_eeprom_reg (int value, int reg) |
||||
{ |
||||
int timeout; |
||||
|
||||
SMC_SELECT_BANK (2); |
||||
SMC_outw (reg, PTR_REG); |
||||
|
||||
SMC_SELECT_BANK (1); |
||||
SMC_outw (value, GP_REG); |
||||
SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG); |
||||
timeout = 100; |
||||
while ((SMC_inw (CTL_REG) & CTL_STORE) && --timeout) |
||||
udelay (100); |
||||
if (timeout == 0) { |
||||
printf ("Timeout Writing EEPROM register %02x\n", reg); |
||||
return 0; |
||||
} |
||||
|
||||
return 1; |
||||
|
||||
} |
||||
|
||||
void dump_reg (void) |
||||
{ |
||||
int i, j; |
||||
|
||||
printf (" "); |
||||
for (j = 0; j < 4; j++) { |
||||
printf ("Bank%i ", j); |
||||
} |
||||
printf ("\n"); |
||||
for (i = 0; i < 0xF; i += 2) { |
||||
printf ("%02x ", i); |
||||
for (j = 0; j < 4; j++) { |
||||
SMC_SELECT_BANK (j); |
||||
printf ("%04x ", SMC_inw (i)); |
||||
} |
||||
printf ("\n"); |
||||
} |
||||
} |
Loading…
Reference in new issue