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> 321bc15386SPeter Tyser #include "../drivers/net/smc91111.h" 331bc15386SPeter Tyser 341bc15386SPeter Tyser #ifndef SMC91111_EEPROM_INIT 351bc15386SPeter Tyser # define SMC91111_EEPROM_INIT() 361bc15386SPeter Tyser #endif 371bc15386SPeter Tyser 381bc15386SPeter Tyser #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE 391bc15386SPeter Tyser #define EEPROM 0x1 401bc15386SPeter Tyser #define MAC 0x2 411bc15386SPeter Tyser #define UNKNOWN 0x4 421bc15386SPeter Tyser 437194ab80SBen Warren void dump_reg (struct eth_device *dev); 447194ab80SBen Warren void dump_eeprom (struct eth_device *dev); 457194ab80SBen Warren int write_eeprom_reg (struct eth_device *dev, int value, int reg); 467194ab80SBen Warren void copy_from_eeprom (struct eth_device *dev); 477194ab80SBen Warren void print_MAC (struct eth_device *dev); 487194ab80SBen Warren int read_eeprom_reg (struct eth_device *dev, int reg); 497194ab80SBen Warren void print_macaddr (struct eth_device *dev); 501bc15386SPeter Tyser 511bc15386SPeter Tyser int smc91111_eeprom (int argc, char *argv[]) 521bc15386SPeter Tyser { 531bc15386SPeter Tyser int c, i, j, done, line, reg, value, start, what; 541bc15386SPeter Tyser char input[50]; 551bc15386SPeter Tyser 56*c4168af3SMike Frysinger struct eth_device dev; 57*c4168af3SMike Frysinger dev.iobase = CONFIG_SMC91111_BASE; 587194ab80SBen Warren 591bc15386SPeter Tyser /* Print the ABI version */ 601bc15386SPeter Tyser app_startup (argv); 611bc15386SPeter Tyser if (XF_VERSION != (int) get_version ()) { 621bc15386SPeter Tyser printf ("Expects ABI version %d\n", XF_VERSION); 631bc15386SPeter Tyser printf ("Actual U-Boot ABI version %d\n", 641bc15386SPeter Tyser (int) get_version ()); 651bc15386SPeter Tyser printf ("Can't run\n\n"); 661bc15386SPeter Tyser return (0); 671bc15386SPeter Tyser } 681bc15386SPeter Tyser 691bc15386SPeter Tyser SMC91111_EEPROM_INIT(); 701bc15386SPeter Tyser 717194ab80SBen Warren if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) { 721bc15386SPeter Tyser printf ("Can't find SMSC91111\n"); 731bc15386SPeter Tyser return (0); 741bc15386SPeter Tyser } 751bc15386SPeter Tyser 761bc15386SPeter Tyser done = 0; 771bc15386SPeter Tyser what = UNKNOWN; 781bc15386SPeter Tyser printf ("\n"); 791bc15386SPeter Tyser while (!done) { 801bc15386SPeter Tyser /* print the prompt */ 811bc15386SPeter Tyser printf ("SMC91111> "); 821bc15386SPeter Tyser line = 0; 831bc15386SPeter Tyser i = 0; 841bc15386SPeter Tyser start = 1; 851bc15386SPeter Tyser while (!line) { 861bc15386SPeter Tyser /* Wait for a keystroke */ 871bc15386SPeter Tyser while (!tstc ()); 881bc15386SPeter Tyser 891bc15386SPeter Tyser c = getc (); 901bc15386SPeter Tyser /* Make Uppercase */ 911bc15386SPeter Tyser if (c >= 'Z') 921bc15386SPeter Tyser c -= ('a' - 'A'); 931bc15386SPeter Tyser /* printf(" |%02x| ",c); */ 941bc15386SPeter Tyser 951bc15386SPeter Tyser switch (c) { 961bc15386SPeter Tyser case '\r': /* Enter */ 971bc15386SPeter Tyser case '\n': 981bc15386SPeter Tyser input[i] = 0; 991bc15386SPeter Tyser puts ("\r\n"); 1001bc15386SPeter Tyser line = 1; 1011bc15386SPeter Tyser break; 1021bc15386SPeter Tyser case '\0': /* nul */ 1031bc15386SPeter Tyser continue; 1041bc15386SPeter Tyser 1051bc15386SPeter Tyser case 0x03: /* ^C - break */ 1061bc15386SPeter Tyser input[0] = 0; 1071bc15386SPeter Tyser i = 0; 1081bc15386SPeter Tyser line = 1; 1091bc15386SPeter Tyser done = 1; 1101bc15386SPeter Tyser break; 1111bc15386SPeter Tyser 1121bc15386SPeter Tyser case 0x5F: 1131bc15386SPeter Tyser case 0x08: /* ^H - backspace */ 1141bc15386SPeter Tyser case 0x7F: /* DEL - backspace */ 1151bc15386SPeter Tyser if (i > 0) { 1161bc15386SPeter Tyser puts ("\b \b"); 1171bc15386SPeter Tyser i--; 1181bc15386SPeter Tyser } 1191bc15386SPeter Tyser break; 1201bc15386SPeter Tyser default: 1211bc15386SPeter Tyser if (start) { 1221bc15386SPeter Tyser if ((c == 'W') || (c == 'D') 1231bc15386SPeter Tyser || (c == 'M') || (c == 'C') 1241bc15386SPeter Tyser || (c == 'P')) { 1251bc15386SPeter Tyser putc (c); 1261bc15386SPeter Tyser input[i] = c; 1271bc15386SPeter Tyser if (i <= 45) 1281bc15386SPeter Tyser i++; 1291bc15386SPeter Tyser start = 0; 1301bc15386SPeter Tyser } 1311bc15386SPeter Tyser } else { 1321bc15386SPeter Tyser if ((c >= '0' && c <= '9') 1331bc15386SPeter Tyser || (c >= 'A' && c <= 'F') 1341bc15386SPeter Tyser || (c == 'E') || (c == 'M') 1351bc15386SPeter Tyser || (c == ' ')) { 1361bc15386SPeter Tyser putc (c); 1371bc15386SPeter Tyser input[i] = c; 1381bc15386SPeter Tyser if (i <= 45) 1391bc15386SPeter Tyser i++; 1401bc15386SPeter Tyser break; 1411bc15386SPeter Tyser } 1421bc15386SPeter Tyser } 1431bc15386SPeter Tyser break; 1441bc15386SPeter Tyser } 1451bc15386SPeter Tyser } 1461bc15386SPeter Tyser 1471bc15386SPeter Tyser for (; i < 49; i++) 1481bc15386SPeter Tyser input[i] = 0; 1491bc15386SPeter Tyser 1501bc15386SPeter Tyser switch (input[0]) { 1511bc15386SPeter Tyser case ('W'): 1521bc15386SPeter Tyser /* Line should be w reg value */ 1531bc15386SPeter Tyser i = 0; 1541bc15386SPeter Tyser reg = 0; 1551bc15386SPeter Tyser value = 0; 1561bc15386SPeter Tyser /* Skip to the next space or end) */ 1571bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1581bc15386SPeter Tyser i++; 1591bc15386SPeter Tyser 1601bc15386SPeter Tyser if (input[i] != 0) 1611bc15386SPeter Tyser i++; 1621bc15386SPeter Tyser 1631bc15386SPeter Tyser /* Are we writing to EEPROM or MAC */ 1641bc15386SPeter Tyser switch (input[i]) { 1651bc15386SPeter Tyser case ('E'): 1661bc15386SPeter Tyser what = EEPROM; 1671bc15386SPeter Tyser break; 1681bc15386SPeter Tyser case ('M'): 1691bc15386SPeter Tyser what = MAC; 1701bc15386SPeter Tyser break; 1711bc15386SPeter Tyser default: 1721bc15386SPeter Tyser what = UNKNOWN; 1731bc15386SPeter Tyser break; 1741bc15386SPeter Tyser } 1751bc15386SPeter Tyser 1761bc15386SPeter Tyser /* skip to the next space or end */ 1771bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1781bc15386SPeter Tyser i++; 1791bc15386SPeter Tyser if (input[i] != 0) 1801bc15386SPeter Tyser i++; 1811bc15386SPeter Tyser 1821bc15386SPeter Tyser /* Find register to write into */ 1831bc15386SPeter Tyser j = 0; 1841bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) { 1851bc15386SPeter Tyser j = input[i] - 0x30; 1861bc15386SPeter Tyser if (j >= 0xA) { 1871bc15386SPeter Tyser j -= 0x07; 1881bc15386SPeter Tyser } 1891bc15386SPeter Tyser reg = (reg * 0x10) + j; 1901bc15386SPeter Tyser i++; 1911bc15386SPeter Tyser } 1921bc15386SPeter Tyser 1931bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) 1941bc15386SPeter Tyser i++; 1951bc15386SPeter Tyser 1961bc15386SPeter Tyser if (input[i] != 0) 1971bc15386SPeter Tyser i++; 1981bc15386SPeter Tyser else 1991bc15386SPeter Tyser what = UNKNOWN; 2001bc15386SPeter Tyser 2011bc15386SPeter Tyser /* Get the value to write */ 2021bc15386SPeter Tyser j = 0; 2031bc15386SPeter Tyser while ((input[i] != ' ') && (input[i] != 0)) { 2041bc15386SPeter Tyser j = input[i] - 0x30; 2051bc15386SPeter Tyser if (j >= 0xA) { 2061bc15386SPeter Tyser j -= 0x07; 2071bc15386SPeter Tyser } 2081bc15386SPeter Tyser value = (value * 0x10) + j; 2091bc15386SPeter Tyser i++; 2101bc15386SPeter Tyser } 2111bc15386SPeter Tyser 2121bc15386SPeter Tyser switch (what) { 2131bc15386SPeter Tyser case 1: 2141bc15386SPeter Tyser printf ("Writing EEPROM register %02x with %04x\n", reg, value); 2157194ab80SBen Warren write_eeprom_reg (&dev, value, reg); 2161bc15386SPeter Tyser break; 2171bc15386SPeter Tyser case 2: 2181bc15386SPeter Tyser printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value); 2197194ab80SBen Warren SMC_SELECT_BANK (&dev, reg >> 4); 2207194ab80SBen Warren SMC_outw (&dev, value, reg & 0xE); 2211bc15386SPeter Tyser break; 2221bc15386SPeter Tyser default: 2231bc15386SPeter Tyser printf ("Wrong\n"); 2241bc15386SPeter Tyser break; 2251bc15386SPeter Tyser } 2261bc15386SPeter Tyser break; 2271bc15386SPeter Tyser case ('D'): 2287194ab80SBen Warren dump_eeprom (&dev); 2291bc15386SPeter Tyser break; 2301bc15386SPeter Tyser case ('M'): 2317194ab80SBen Warren dump_reg (&dev); 2321bc15386SPeter Tyser break; 2331bc15386SPeter Tyser case ('C'): 2347194ab80SBen Warren copy_from_eeprom (&dev); 2351bc15386SPeter Tyser break; 2361bc15386SPeter Tyser case ('P'): 2377194ab80SBen Warren print_macaddr (&dev); 2381bc15386SPeter Tyser break; 2391bc15386SPeter Tyser default: 2401bc15386SPeter Tyser break; 2411bc15386SPeter Tyser } 2421bc15386SPeter Tyser 2431bc15386SPeter Tyser } 2441bc15386SPeter Tyser 2451bc15386SPeter Tyser return (0); 2461bc15386SPeter Tyser } 2471bc15386SPeter Tyser 2487194ab80SBen Warren void copy_from_eeprom (struct eth_device *dev) 2491bc15386SPeter Tyser { 2501bc15386SPeter Tyser int i; 2511bc15386SPeter Tyser 2527194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 2537194ab80SBen Warren SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) | 2547194ab80SBen Warren CTL_RELOAD, CTL_REG); 2551bc15386SPeter Tyser i = 100; 2567194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i) 2571bc15386SPeter Tyser udelay (100); 2581bc15386SPeter Tyser if (i == 0) { 2591bc15386SPeter Tyser printf ("Timeout Refreshing EEPROM registers\n"); 2601bc15386SPeter Tyser } else { 2611bc15386SPeter Tyser printf ("EEPROM contents copied to MAC\n"); 2621bc15386SPeter Tyser } 2631bc15386SPeter Tyser 2641bc15386SPeter Tyser } 2651bc15386SPeter Tyser 2667194ab80SBen Warren void print_macaddr (struct eth_device *dev) 2671bc15386SPeter Tyser { 2681bc15386SPeter Tyser int i, j, k, mac[6]; 2691bc15386SPeter Tyser 2701bc15386SPeter Tyser printf ("Current MAC Address in SMSC91111 "); 2717194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 2721bc15386SPeter Tyser for (i = 0; i < 5; i++) { 2737194ab80SBen Warren printf ("%02x:", SMC_inb (dev, ADDR0_REG + i)); 2741bc15386SPeter Tyser } 2751bc15386SPeter Tyser 2767194ab80SBen Warren printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5)); 2771bc15386SPeter Tyser 2781bc15386SPeter Tyser i = 0; 2791bc15386SPeter Tyser for (j = 0x20; j < 0x23; j++) { 2807194ab80SBen Warren k = read_eeprom_reg (dev, j); 2811bc15386SPeter Tyser mac[i] = k & 0xFF; 2821bc15386SPeter Tyser i++; 2831bc15386SPeter Tyser mac[i] = k >> 8; 2841bc15386SPeter Tyser i++; 2851bc15386SPeter Tyser } 2861bc15386SPeter Tyser 2871bc15386SPeter Tyser printf ("Current MAC Address in EEPROM "); 2881bc15386SPeter Tyser for (i = 0; i < 5; i++) 2891bc15386SPeter Tyser printf ("%02x:", mac[i]); 2901bc15386SPeter Tyser printf ("%02x\n", mac[5]); 2911bc15386SPeter Tyser 2921bc15386SPeter Tyser } 2937194ab80SBen Warren void dump_eeprom (struct eth_device *dev) 2941bc15386SPeter Tyser { 2951bc15386SPeter Tyser int j, k; 2961bc15386SPeter Tyser 2971bc15386SPeter Tyser printf ("IOS2-0 "); 2981bc15386SPeter Tyser for (j = 0; j < 8; j++) { 2991bc15386SPeter Tyser printf ("%03x ", j); 3001bc15386SPeter Tyser } 3011bc15386SPeter Tyser printf ("\n"); 3021bc15386SPeter Tyser 3031bc15386SPeter Tyser for (k = 0; k < 4; k++) { 3041bc15386SPeter Tyser if (k == 0) 3051bc15386SPeter Tyser printf ("CONFIG "); 3061bc15386SPeter Tyser if (k == 1) 3071bc15386SPeter Tyser printf ("BASE "); 3081bc15386SPeter Tyser if ((k == 2) || (k == 3)) 3091bc15386SPeter Tyser printf (" "); 3101bc15386SPeter Tyser for (j = 0; j < 0x20; j += 4) { 3117194ab80SBen Warren printf ("%02x:%04x ", j + k, 3127194ab80SBen Warren read_eeprom_reg (dev, j + k)); 3131bc15386SPeter Tyser } 3141bc15386SPeter Tyser printf ("\n"); 3151bc15386SPeter Tyser } 3161bc15386SPeter Tyser 3171bc15386SPeter Tyser for (j = 0x20; j < 0x40; j++) { 3181bc15386SPeter Tyser if ((j & 0x07) == 0) 3191bc15386SPeter Tyser printf ("\n"); 3207194ab80SBen Warren printf ("%02x:%04x ", j, read_eeprom_reg (dev, j)); 3211bc15386SPeter Tyser } 3221bc15386SPeter Tyser printf ("\n"); 3231bc15386SPeter Tyser 3241bc15386SPeter Tyser } 3251bc15386SPeter Tyser 3267194ab80SBen Warren int read_eeprom_reg (struct eth_device *dev, int reg) 3271bc15386SPeter Tyser { 3281bc15386SPeter Tyser int timeout; 3291bc15386SPeter Tyser 3307194ab80SBen Warren SMC_SELECT_BANK (dev, 2); 3317194ab80SBen Warren SMC_outw (dev, reg, PTR_REG); 3321bc15386SPeter Tyser 3337194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 3347194ab80SBen Warren SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 3357194ab80SBen Warren CTL_RELOAD, CTL_REG); 3361bc15386SPeter Tyser timeout = 100; 3377194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout) 3381bc15386SPeter Tyser udelay (100); 3391bc15386SPeter Tyser if (timeout == 0) { 3401bc15386SPeter Tyser printf ("Timeout Reading EEPROM register %02x\n", reg); 3411bc15386SPeter Tyser return 0; 3421bc15386SPeter Tyser } 3431bc15386SPeter Tyser 3447194ab80SBen Warren return SMC_inw (dev, GP_REG); 3451bc15386SPeter Tyser 3461bc15386SPeter Tyser } 3471bc15386SPeter Tyser 3487194ab80SBen Warren int write_eeprom_reg (struct eth_device *dev, int value, int reg) 3491bc15386SPeter Tyser { 3501bc15386SPeter Tyser int timeout; 3511bc15386SPeter Tyser 3527194ab80SBen Warren SMC_SELECT_BANK (dev, 2); 3537194ab80SBen Warren SMC_outw (dev, reg, PTR_REG); 3541bc15386SPeter Tyser 3557194ab80SBen Warren SMC_SELECT_BANK (dev, 1); 3567194ab80SBen Warren SMC_outw (dev, value, GP_REG); 3577194ab80SBen Warren SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 3587194ab80SBen Warren CTL_STORE, CTL_REG); 3591bc15386SPeter Tyser timeout = 100; 3607194ab80SBen Warren while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout) 3611bc15386SPeter Tyser udelay (100); 3621bc15386SPeter Tyser if (timeout == 0) { 3631bc15386SPeter Tyser printf ("Timeout Writing EEPROM register %02x\n", reg); 3641bc15386SPeter Tyser return 0; 3651bc15386SPeter Tyser } 3661bc15386SPeter Tyser 3671bc15386SPeter Tyser return 1; 3681bc15386SPeter Tyser 3691bc15386SPeter Tyser } 3701bc15386SPeter Tyser 3717194ab80SBen Warren void dump_reg (struct eth_device *dev) 3721bc15386SPeter Tyser { 3731bc15386SPeter Tyser int i, j; 3741bc15386SPeter Tyser 3751bc15386SPeter Tyser printf (" "); 3761bc15386SPeter Tyser for (j = 0; j < 4; j++) { 3771bc15386SPeter Tyser printf ("Bank%i ", j); 3781bc15386SPeter Tyser } 3791bc15386SPeter Tyser printf ("\n"); 3801bc15386SPeter Tyser for (i = 0; i < 0xF; i += 2) { 3811bc15386SPeter Tyser printf ("%02x ", i); 3821bc15386SPeter Tyser for (j = 0; j < 4; j++) { 3837194ab80SBen Warren SMC_SELECT_BANK (dev, j); 3847194ab80SBen Warren printf ("%04x ", SMC_inw (dev, i)); 3851bc15386SPeter Tyser } 3861bc15386SPeter Tyser printf ("\n"); 3871bc15386SPeter Tyser } 3881bc15386SPeter Tyser } 389