mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-11 13:56:30 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
371 lines
7.2 KiB
C
371 lines
7.2 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* (C) Copyright 2004
|
|
* Robin Getz rgetz@blacfin.uclinux.org
|
|
*
|
|
* 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/net/smc91111.h"
|
|
|
|
#ifndef SMC91111_EEPROM_INIT
|
|
# define SMC91111_EEPROM_INIT()
|
|
#endif
|
|
|
|
#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
|
|
#define EEPROM 0x1
|
|
#define MAC 0x2
|
|
#define UNKNOWN 0x4
|
|
|
|
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);
|
|
|
|
int smc91111_eeprom (int argc, char * const argv[])
|
|
{
|
|
int c, i, j, done, line, reg, value, start, what;
|
|
char input[50];
|
|
|
|
struct eth_device dev;
|
|
dev.iobase = CONFIG_SMC91111_BASE;
|
|
|
|
/* 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);
|
|
}
|
|
|
|
SMC91111_EEPROM_INIT();
|
|
|
|
if ((SMC_inw (&dev, 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 (&dev, value, reg);
|
|
break;
|
|
case 2:
|
|
printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
|
|
SMC_SELECT_BANK (&dev, reg >> 4);
|
|
SMC_outw (&dev, value, reg & 0xE);
|
|
break;
|
|
default:
|
|
printf ("Wrong\n");
|
|
break;
|
|
}
|
|
break;
|
|
case ('D'):
|
|
dump_eeprom (&dev);
|
|
break;
|
|
case ('M'):
|
|
dump_reg (&dev);
|
|
break;
|
|
case ('C'):
|
|
copy_from_eeprom (&dev);
|
|
break;
|
|
case ('P'):
|
|
print_macaddr (&dev);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
void copy_from_eeprom (struct eth_device *dev)
|
|
{
|
|
int i;
|
|
|
|
SMC_SELECT_BANK (dev, 1);
|
|
SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
|
|
CTL_RELOAD, CTL_REG);
|
|
i = 100;
|
|
while ((SMC_inw (dev, 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 (struct eth_device *dev)
|
|
{
|
|
int i, j, k, mac[6];
|
|
|
|
printf ("Current MAC Address in SMSC91111 ");
|
|
SMC_SELECT_BANK (dev, 1);
|
|
for (i = 0; i < 5; i++) {
|
|
printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
|
|
}
|
|
|
|
printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
|
|
|
|
i = 0;
|
|
for (j = 0x20; j < 0x23; j++) {
|
|
k = read_eeprom_reg (dev, 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 (struct eth_device *dev)
|
|
{
|
|
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 (dev, j + k));
|
|
}
|
|
printf ("\n");
|
|
}
|
|
|
|
for (j = 0x20; j < 0x40; j++) {
|
|
if ((j & 0x07) == 0)
|
|
printf ("\n");
|
|
printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
|
|
}
|
|
printf ("\n");
|
|
|
|
}
|
|
|
|
int read_eeprom_reg (struct eth_device *dev, int reg)
|
|
{
|
|
int timeout;
|
|
|
|
SMC_SELECT_BANK (dev, 2);
|
|
SMC_outw (dev, reg, PTR_REG);
|
|
|
|
SMC_SELECT_BANK (dev, 1);
|
|
SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
|
|
CTL_RELOAD, CTL_REG);
|
|
timeout = 100;
|
|
while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
|
|
udelay (100);
|
|
if (timeout == 0) {
|
|
printf ("Timeout Reading EEPROM register %02x\n", reg);
|
|
return 0;
|
|
}
|
|
|
|
return SMC_inw (dev, GP_REG);
|
|
|
|
}
|
|
|
|
int write_eeprom_reg (struct eth_device *dev, int value, int reg)
|
|
{
|
|
int timeout;
|
|
|
|
SMC_SELECT_BANK (dev, 2);
|
|
SMC_outw (dev, reg, PTR_REG);
|
|
|
|
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);
|
|
timeout = 100;
|
|
while ((SMC_inw (dev, 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 (struct eth_device *dev)
|
|
{
|
|
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 (dev, j);
|
|
printf ("%04x ", SMC_inw (dev, i));
|
|
}
|
|
printf ("\n");
|
|
}
|
|
}
|