11bc15386SPeter Tyser /* 21bc15386SPeter Tyser * (C) Copyright 2004 31bc15386SPeter Tyser * Robin Getz rgetz@blacfin.uclinux.org 41bc15386SPeter Tyser * 51bc15386SPeter Tyser * See file CREDITS for list of people who contributed to this 61bc15386SPeter Tyser * project. 71bc15386SPeter Tyser * 81bc15386SPeter Tyser * This program is free software; you can redistribute it and/or 91bc15386SPeter Tyser * modify it under the terms of the GNU General Public License as 101bc15386SPeter Tyser * published by the Free Software Foundation; either version 2 of 111bc15386SPeter Tyser * the License, or (at your option) any later version. 121bc15386SPeter Tyser * 131bc15386SPeter Tyser * This program is distributed in the hope that it will be useful, 141bc15386SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 151bc15386SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 161bc15386SPeter Tyser * GNU General Public License for more details. 171bc15386SPeter Tyser * 181bc15386SPeter Tyser * You should have received a copy of the GNU General Public License 191bc15386SPeter Tyser * along with this program; if not, write to the Free Software 201bc15386SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 211bc15386SPeter Tyser * MA 02111-1307 USA 221bc15386SPeter Tyser * 231bc15386SPeter Tyser * Heavily borrowed from the following peoples GPL'ed software: 241bc15386SPeter Tyser * - Wolfgang Denk, DENX Software Engineering, wd@denx.de 251bc15386SPeter Tyser * Das U-boot 261bc15386SPeter Tyser * - Ladislav Michl ladis@linux-mips.org 271bc15386SPeter Tyser * A rejected patch on the U-Boot mailing list 281bc15386SPeter Tyser */ 291bc15386SPeter Tyser 301bc15386SPeter Tyser #include <common.h> 311bc15386SPeter Tyser #include <exports.h> 32*7194ab80SBen Warren /* the smc91111.h gets base addr through eth_device' iobase */ 33*7194ab80SBen Warren struct eth_device { unsigned long iobase; }; 341bc15386SPeter Tyser #include "../drivers/net/smc91111.h" 351bc15386SPeter Tyser 36*7194ab80SBen Warren #ifdef CONFIG_SMC91111 371bc15386SPeter Tyser 381bc15386SPeter Tyser #ifndef SMC91111_EEPROM_INIT 391bc15386SPeter Tyser # define SMC91111_EEPROM_INIT() 401bc15386SPeter Tyser #endif 411bc15386SPeter Tyser 421bc15386SPeter Tyser #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE 431bc15386SPeter Tyser #define EEPROM 0x1 441bc15386SPeter Tyser #define MAC 0x2 451bc15386SPeter Tyser #define UNKNOWN 0x4 461bc15386SPeter Tyser 47*7194ab80SBen Warren void dump_reg (struct eth_device *dev); 48*7194ab80SBen Warren void dump_eeprom (struct eth_device *dev); 49*7194ab80SBen Warren int write_eeprom_reg (struct eth_device *dev, int value, int reg); 50*7194ab80SBen Warren void copy_from_eeprom (struct eth_device *dev); 51*7194ab80SBen Warren void print_MAC (struct eth_device *dev); 52*7194ab80SBen Warren int read_eeprom_reg (struct eth_device *dev, int reg); 53*7194ab80SBen Warren void print_macaddr (struct eth_device *dev); 541bc15386SPeter Tyser 551bc15386SPeter Tyser int smc91111_eeprom (int argc, char *argv[]) 561bc15386SPeter Tyser { 571bc15386SPeter Tyser int c, i, j, done, line, reg, value, start, what; 581bc15386SPeter Tyser char input[50]; 591bc15386SPeter Tyser 60*7194ab80SBen Warren struct eth_device dev = { 61*7194ab80SBen Warren .iobase = CONFIG_SMC91111_BASE 62*7194ab80SBen Warren }; 63*7194ab80SBen Warren 641bc15386SPeter Tyser /* Print the ABI version */ 651bc15386SPeter Tyser app_startup (argv); 661bc15386SPeter Tyser if (XF_VERSION != (int) get_version ()) { 671bc15386SPeter Tyser printf ("Expects ABI version %d\n", XF_VERSION); 681bc15386SPeter Tyser printf ("Actual U-Boot ABI version %d\n", 691bc15386SPeter Tyser (int) get_version ()); 701bc15386SPeter Tyser printf ("Can't run\n\n"); 711bc15386SPeter Tyser return (0); 721bc15386SPeter Tyser } 731bc15386SPeter Tyser 741bc15386SPeter Tyser SMC91111_EEPROM_INIT(); 751bc15386SPeter Tyser 76*7194ab80SBen Warren if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) { 771bc15386SPeter Tyser printf ("Can't find SMSC91111\n"); 781bc15386SPeter Tyser return (0); 791bc15386SPeter Tyser } 801bc15386SPeter Tyser 811bc15386SPeter Tyser done = 0; 821bc15386SPeter Tyser what = UNKNOWN; 831bc15386SPeter Tyser printf ("\n"); 841bc15386SPeter Tyser while (!done) { 851bc15386SPeter Tyser /* print the prompt */ 861bc15386SPeter Tyser printf ("SMC91111> "); 871bc15386SPeter Tyser line = 0; 881bc15386SPeter Tyser i = 0; 891bc15386SPeter Tyser start = 1; 901bc15386SPeter Tyser while (!line) { 911bc15386SPeter Tyser /* Wait for a keystroke */ 921bc15386SPeter Tyser while (!tstc ()); 931bc15386SPeter Tyser 941bc15386SPeter Tyser c = getc (); 951bc15386SPeter Tyser /* Make Uppercase */ 961bc15386SPeter Tyser if (c >= 'Z') 971bc15386SPeter Tyser c -= ('a' - 'A'); 981bc15386SPeter Tyser /* printf(" |%02x| ",c); */ 991bc15386SPeter Tyser 1001bc15386SPeter Tyser switch (c) { 1011bc15386SPeter Tyser case '\r': /* Enter */ 1021bc15386SPeter Tyser case '\n': 1031bc15386SPeter Tyser input[i] = 0; 1041bc15386SPeter Tyser puts ("\r\n"); 1051bc15386SPeter Tyser line = 1; 1061bc15386SPeter Tyser break; 1071bc15386SPeter Tyser case '\0': /* nul */ 1081bc15386SPeter Tyser continue; 1091bc15386SPeter Tyser 1101bc15386SPeter Tyser case 0x03: /* ^C - break */ 1111bc15386SPeter Tyser input[0] = 0; 1121bc15386SPeter Tyser i = 0; 1131bc15386SPeter Tyser line = 1; 1141bc15386SPeter Tyser done = 1; 1151bc15386SPeter Tyser break; 1161bc15386SPeter Tyser 1171bc15386SPeter Tyser case 0x5F: 1181bc15386SPeter Tyser case 0x08: /* ^H - backspace */ 1191bc15386SPeter Tyser case 0x7F: /* DEL - backspace */ 1201bc15386SPeter Tyser if (i > 0) { 1211bc15386SPeter Tyser puts ("\b \b"); 1221bc15386SPeter Tyser i--; 1231bc15386SPeter Tyser } 1241bc15386SPeter Tyser break; 1251bc15386SPeter Tyser default: 1261bc15386SPeter Tyser if (start) { 1271bc15386SPeter Tyser if ((c == 'W') || (c == 'D') 1281bc15386SPeter Tyser || (c == 'M') || (c == 'C') 1291bc15386SPeter Tyser || (c == 'P')) { 1301bc15386SPeter Tyser putc (c); 1311bc15386SPeter Tyser input[i] = c; 1321bc15386SPeter Tyser if (i <= 45) 1331bc15386SPeter Tyser i++; 1341bc15386SPeter Tyser start = 0; 1351bc15386SPeter Tyser } 1361bc15386SPeter Tyser } else { 1371bc15386SPeter Tyser if ((c >= '0' && c <= '9') 1381bc15386SPeter Tyser || (c >= 'A' && c <= 'F') 1391bc15386SPeter Tyser || (c == 'E') || (c == 'M') 1401bc15386SPeter Tyser || (c == ' ')) { 1411bc15386SPeter Tyser putc (c); 1421bc15386SPeter Tyser input[i] = c; 1431bc15386SPeter Tyser if (i <= 45) 1441bc15386SPeter Tyser i++; 1451bc15386SPeter Tyser break; 1461bc15386SPeter Tyser } 1471bc15386SPeter Tyser } 1481bc15386SPeter Tyser break; 1491bc15386SPeter Tyser } 1501bc15386SPeter Tyser } 1511bc15386SPeter Tyser 1521bc15386SPeter Tyser for (; i < 49; i++) 1531bc15386SPeter Tyser input[i] = 0; 1541bc15386SPeter Tyser 1551bc15386SPeter Tyser switch (input[0]) { 1561bc15386SPeter Tyser case ('W'): 1571bc15386SPeter Tyser /* Line should be w reg value */ 1581bc15386SPeter Tyser i = 0; 1591bc15386SPeter Tyser reg = 0; 1601bc15386SPeter Tyser value = 0; 1611bc15386SPeter Tyser /* Skip to the next space or end) */ 1621bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1631bc15386SPeter Tyser i++; 1641bc15386SPeter Tyser 1651bc15386SPeter Tyser if (input[i] != 0) 1661bc15386SPeter Tyser i++; 1671bc15386SPeter Tyser 1681bc15386SPeter Tyser /* Are we writing to EEPROM or MAC */ 1691bc15386SPeter Tyser switch (input[i]) { 1701bc15386SPeter Tyser case ('E'): 1711bc15386SPeter Tyser what = EEPROM; 1721bc15386SPeter Tyser break; 1731bc15386SPeter Tyser case ('M'): 1741bc15386SPeter Tyser what = MAC; 1751bc15386SPeter Tyser break; 1761bc15386SPeter Tyser default: 1771bc15386SPeter Tyser what = UNKNOWN; 1781bc15386SPeter Tyser break; 1791bc15386SPeter Tyser } 1801bc15386SPeter Tyser 1811bc15386SPeter Tyser /* skip to the next space or end */ 1821bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1831bc15386SPeter Tyser i++; 1841bc15386SPeter Tyser if (input[i] != 0) 1851bc15386SPeter Tyser i++; 1861bc15386SPeter Tyser 1871bc15386SPeter Tyser /* Find register to write into */ 1881bc15386SPeter Tyser j = 0; 1891bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) { 1901bc15386SPeter Tyser j = input[i] - 0x30; 1911bc15386SPeter Tyser if (j >= 0xA) { 1921bc15386SPeter Tyser j -= 0x07; 1931bc15386SPeter Tyser } 1941bc15386SPeter Tyser reg = (reg * 0x10) + j; 1951bc15386SPeter Tyser i++; 1961bc15386SPeter Tyser } 1971bc15386SPeter Tyser 1981bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1991bc15386SPeter Tyser i++; 2001bc15386SPeter Tyser 2011bc15386SPeter Tyser if (input[i] != 0) 2021bc15386SPeter Tyser i++; 2031bc15386SPeter Tyser else 2041bc15386SPeter Tyser what = UNKNOWN; 2051bc15386SPeter Tyser 2061bc15386SPeter Tyser /* Get the value to write */ 2071bc15386SPeter Tyser j = 0; 2081bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) { 2091bc15386SPeter Tyser j = input[i] - 0x30; 2101bc15386SPeter Tyser if (j >= 0xA) { 2111bc15386SPeter Tyser j -= 0x07; 2121bc15386SPeter Tyser } 2131bc15386SPeter Tyser value = (value * 0x10) + j; 2141bc15386SPeter Tyser i++; 2151bc15386SPeter Tyser } 2161bc15386SPeter Tyser 2171bc15386SPeter Tyser switch (what) { 2181bc15386SPeter Tyser case 1: 2191bc15386SPeter Tyser printf ("Writing EEPROM register %02x with %04x\n", reg, value); 220*7194ab80SBen Warren write_eeprom_reg (&dev, value, reg); 2211bc15386SPeter Tyser break; 2221bc15386SPeter Tyser case 2: 2231bc15386SPeter Tyser printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value); 224*7194ab80SBen Warren SMC_SELECT_BANK (&dev, reg >> 4); 225*7194ab80SBen Warren SMC_outw (&dev, value, reg & 0xE); 2261bc15386SPeter Tyser break; 2271bc15386SPeter Tyser default: 2281bc15386SPeter Tyser printf ("Wrong\n"); 2291bc15386SPeter Tyser break; 2301bc15386SPeter Tyser } 2311bc15386SPeter Tyser break; 2321bc15386SPeter Tyser case ('D'): 233*7194ab80SBen Warren dump_eeprom (&dev); 2341bc15386SPeter Tyser break; 2351bc15386SPeter Tyser case ('M'): 236*7194ab80SBen Warren dump_reg (&dev); 2371bc15386SPeter Tyser break; 2381bc15386SPeter Tyser case ('C'): 239*7194ab80SBen Warren copy_from_eeprom (&dev); 2401bc15386SPeter Tyser break; 2411bc15386SPeter Tyser case ('P'): 242*7194ab80SBen Warren print_macaddr (&dev); 2431bc15386SPeter Tyser break; 2441bc15386SPeter Tyser default: 2451bc15386SPeter Tyser break; 2461bc15386SPeter Tyser } 2471bc15386SPeter Tyser 2481bc15386SPeter Tyser } 2491bc15386SPeter Tyser 2501bc15386SPeter Tyser return (0); 2511bc15386SPeter Tyser } 2521bc15386SPeter Tyser 253*7194ab80SBen Warren void copy_from_eeprom (struct eth_device *dev) 2541bc15386SPeter Tyser { 2551bc15386SPeter Tyser int i; 2561bc15386SPeter Tyser 257*7194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 258*7194ab80SBen Warren SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) | 259*7194ab80SBen Warren CTL_RELOAD, CTL_REG); 2601bc15386SPeter Tyser i = 100; 261*7194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i) 2621bc15386SPeter Tyser udelay (100); 2631bc15386SPeter Tyser if (i == 0) { 2641bc15386SPeter Tyser printf ("Timeout Refreshing EEPROM registers\n"); 2651bc15386SPeter Tyser } else { 2661bc15386SPeter Tyser printf ("EEPROM contents copied to MAC\n"); 2671bc15386SPeter Tyser } 2681bc15386SPeter Tyser 2691bc15386SPeter Tyser } 2701bc15386SPeter Tyser 271*7194ab80SBen Warren void print_macaddr (struct eth_device *dev) 2721bc15386SPeter Tyser { 2731bc15386SPeter Tyser int i, j, k, mac[6]; 2741bc15386SPeter Tyser 2751bc15386SPeter Tyser printf ("Current MAC Address in SMSC91111 "); 276*7194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 2771bc15386SPeter Tyser for (i = 0; i < 5; i++) { 278*7194ab80SBen Warren printf ("%02x:", SMC_inb (dev, ADDR0_REG + i)); 2791bc15386SPeter Tyser } 2801bc15386SPeter Tyser 281*7194ab80SBen Warren printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5)); 2821bc15386SPeter Tyser 2831bc15386SPeter Tyser i = 0; 2841bc15386SPeter Tyser for (j = 0x20; j < 0x23; j++) { 285*7194ab80SBen Warren k = read_eeprom_reg (dev, j); 2861bc15386SPeter Tyser mac[i] = k & 0xFF; 2871bc15386SPeter Tyser i++; 2881bc15386SPeter Tyser mac[i] = k >> 8; 2891bc15386SPeter Tyser i++; 2901bc15386SPeter Tyser } 2911bc15386SPeter Tyser 2921bc15386SPeter Tyser printf ("Current MAC Address in EEPROM "); 2931bc15386SPeter Tyser for (i = 0; i < 5; i++) 2941bc15386SPeter Tyser printf ("%02x:", mac[i]); 2951bc15386SPeter Tyser printf ("%02x\n", mac[5]); 2961bc15386SPeter Tyser 2971bc15386SPeter Tyser } 298*7194ab80SBen Warren void dump_eeprom (struct eth_device *dev) 2991bc15386SPeter Tyser { 3001bc15386SPeter Tyser int j, k; 3011bc15386SPeter Tyser 3021bc15386SPeter Tyser printf ("IOS2-0 "); 3031bc15386SPeter Tyser for (j = 0; j < 8; j++) { 3041bc15386SPeter Tyser printf ("%03x ", j); 3051bc15386SPeter Tyser } 3061bc15386SPeter Tyser printf ("\n"); 3071bc15386SPeter Tyser 3081bc15386SPeter Tyser for (k = 0; k < 4; k++) { 3091bc15386SPeter Tyser if (k == 0) 3101bc15386SPeter Tyser printf ("CONFIG "); 3111bc15386SPeter Tyser if (k == 1) 3121bc15386SPeter Tyser printf ("BASE "); 3131bc15386SPeter Tyser if ((k == 2) || (k == 3)) 3141bc15386SPeter Tyser printf (" "); 3151bc15386SPeter Tyser for (j = 0; j < 0x20; j += 4) { 316*7194ab80SBen Warren printf ("%02x:%04x ", j + k, 317*7194ab80SBen Warren read_eeprom_reg (dev, j + k)); 3181bc15386SPeter Tyser } 3191bc15386SPeter Tyser printf ("\n"); 3201bc15386SPeter Tyser } 3211bc15386SPeter Tyser 3221bc15386SPeter Tyser for (j = 0x20; j < 0x40; j++) { 3231bc15386SPeter Tyser if ((j & 0x07) == 0) 3241bc15386SPeter Tyser printf ("\n"); 325*7194ab80SBen Warren printf ("%02x:%04x ", j, read_eeprom_reg (dev, j)); 3261bc15386SPeter Tyser } 3271bc15386SPeter Tyser printf ("\n"); 3281bc15386SPeter Tyser 3291bc15386SPeter Tyser } 3301bc15386SPeter Tyser 331*7194ab80SBen Warren int read_eeprom_reg (struct eth_device *dev, int reg) 3321bc15386SPeter Tyser { 3331bc15386SPeter Tyser int timeout; 3341bc15386SPeter Tyser 335*7194ab80SBen Warren SMC_SELECT_BANK (dev, 2); 336*7194ab80SBen Warren SMC_outw (dev, reg, PTR_REG); 3371bc15386SPeter Tyser 338*7194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 339*7194ab80SBen Warren SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 340*7194ab80SBen Warren CTL_RELOAD, CTL_REG); 3411bc15386SPeter Tyser timeout = 100; 342*7194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout) 3431bc15386SPeter Tyser udelay (100); 3441bc15386SPeter Tyser if (timeout == 0) { 3451bc15386SPeter Tyser printf ("Timeout Reading EEPROM register %02x\n", reg); 3461bc15386SPeter Tyser return 0; 3471bc15386SPeter Tyser } 3481bc15386SPeter Tyser 349*7194ab80SBen Warren return SMC_inw (dev, GP_REG); 3501bc15386SPeter Tyser 3511bc15386SPeter Tyser } 3521bc15386SPeter Tyser 353*7194ab80SBen Warren int write_eeprom_reg (struct eth_device *dev, int value, int reg) 3541bc15386SPeter Tyser { 3551bc15386SPeter Tyser int timeout; 3561bc15386SPeter Tyser 357*7194ab80SBen Warren SMC_SELECT_BANK (dev, 2); 358*7194ab80SBen Warren SMC_outw (dev, reg, PTR_REG); 3591bc15386SPeter Tyser 360*7194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 361*7194ab80SBen Warren SMC_outw (dev, value, GP_REG); 362*7194ab80SBen Warren SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 363*7194ab80SBen Warren CTL_STORE, CTL_REG); 3641bc15386SPeter Tyser timeout = 100; 365*7194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout) 3661bc15386SPeter Tyser udelay (100); 3671bc15386SPeter Tyser if (timeout == 0) { 3681bc15386SPeter Tyser printf ("Timeout Writing EEPROM register %02x\n", reg); 3691bc15386SPeter Tyser return 0; 3701bc15386SPeter Tyser } 3711bc15386SPeter Tyser 3721bc15386SPeter Tyser return 1; 3731bc15386SPeter Tyser 3741bc15386SPeter Tyser } 3751bc15386SPeter Tyser 376*7194ab80SBen Warren void dump_reg (struct eth_device *dev) 3771bc15386SPeter Tyser { 3781bc15386SPeter Tyser int i, j; 3791bc15386SPeter Tyser 3801bc15386SPeter Tyser printf (" "); 3811bc15386SPeter Tyser for (j = 0; j < 4; j++) { 3821bc15386SPeter Tyser printf ("Bank%i ", j); 3831bc15386SPeter Tyser } 3841bc15386SPeter Tyser printf ("\n"); 3851bc15386SPeter Tyser for (i = 0; i < 0xF; i += 2) { 3861bc15386SPeter Tyser printf ("%02x ", i); 3871bc15386SPeter Tyser for (j = 0; j < 4; j++) { 388*7194ab80SBen Warren SMC_SELECT_BANK (dev, j); 389*7194ab80SBen Warren printf ("%04x ", SMC_inw (dev, i)); 3901bc15386SPeter Tyser } 3911bc15386SPeter Tyser printf ("\n"); 3921bc15386SPeter Tyser } 3931bc15386SPeter Tyser } 3941bc15386SPeter Tyser 3951bc15386SPeter Tyser #else 3961bc15386SPeter Tyser 3971bc15386SPeter Tyser int smc91111_eeprom (int argc, char *argv[]) 3981bc15386SPeter Tyser { 3991bc15386SPeter Tyser printf("Not supported for this board\n"); 4001bc15386SPeter Tyser return 1; 4011bc15386SPeter Tyser } 4021bc15386SPeter Tyser 4031bc15386SPeter Tyser #endif 404