1 /* 2 * (C) Copyright 2004 3 * Robin Getz rgetz@blacfin.uclinux.org 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 * 23 * Heavily borrowed from the following peoples GPL'ed software: 24 * - Wolfgang Denk, DENX Software Engineering, wd@denx.de 25 * Das U-boot 26 * - Ladislav Michl ladis@linux-mips.org 27 * A rejected patch on the U-Boot mailing list 28 */ 29 30 #include <common.h> 31 #include <exports.h> 32 #include "../drivers/net/smc91111.h" 33 34 #ifdef CONFIG_DRIVER_SMC91111 35 36 #ifndef SMC91111_EEPROM_INIT 37 # define SMC91111_EEPROM_INIT() 38 #endif 39 40 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE 41 #define EEPROM 0x1 42 #define MAC 0x2 43 #define UNKNOWN 0x4 44 45 void dump_reg (void); 46 void dump_eeprom (void); 47 int write_eeprom_reg (int, int); 48 void copy_from_eeprom (void); 49 void print_MAC (void); 50 int read_eeprom_reg (int); 51 void print_macaddr (void); 52 53 int smc91111_eeprom (int argc, char *argv[]) 54 { 55 int c, i, j, done, line, reg, value, start, what; 56 char input[50]; 57 58 /* Print the ABI version */ 59 app_startup (argv); 60 if (XF_VERSION != (int) get_version ()) { 61 printf ("Expects ABI version %d\n", XF_VERSION); 62 printf ("Actual U-Boot ABI version %d\n", 63 (int) get_version ()); 64 printf ("Can't run\n\n"); 65 return (0); 66 } 67 68 SMC91111_EEPROM_INIT(); 69 70 if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { 71 printf ("Can't find SMSC91111\n"); 72 return (0); 73 } 74 75 done = 0; 76 what = UNKNOWN; 77 printf ("\n"); 78 while (!done) { 79 /* print the prompt */ 80 printf ("SMC91111> "); 81 line = 0; 82 i = 0; 83 start = 1; 84 while (!line) { 85 /* Wait for a keystroke */ 86 while (!tstc ()); 87 88 c = getc (); 89 /* Make Uppercase */ 90 if (c >= 'Z') 91 c -= ('a' - 'A'); 92 /* printf(" |%02x| ",c); */ 93 94 switch (c) { 95 case '\r': /* Enter */ 96 case '\n': 97 input[i] = 0; 98 puts ("\r\n"); 99 line = 1; 100 break; 101 case '\0': /* nul */ 102 continue; 103 104 case 0x03: /* ^C - break */ 105 input[0] = 0; 106 i = 0; 107 line = 1; 108 done = 1; 109 break; 110 111 case 0x5F: 112 case 0x08: /* ^H - backspace */ 113 case 0x7F: /* DEL - backspace */ 114 if (i > 0) { 115 puts ("\b \b"); 116 i--; 117 } 118 break; 119 default: 120 if (start) { 121 if ((c == 'W') || (c == 'D') 122 || (c == 'M') || (c == 'C') 123 || (c == 'P')) { 124 putc (c); 125 input[i] = c; 126 if (i <= 45) 127 i++; 128 start = 0; 129 } 130 } else { 131 if ((c >= '0' && c <= '9') 132 || (c >= 'A' && c <= 'F') 133 || (c == 'E') || (c == 'M') 134 || (c == ' ')) { 135 putc (c); 136 input[i] = c; 137 if (i <= 45) 138 i++; 139 break; 140 } 141 } 142 break; 143 } 144 } 145 146 for (; i < 49; i++) 147 input[i] = 0; 148 149 switch (input[0]) { 150 case ('W'): 151 /* Line should be w reg value */ 152 i = 0; 153 reg = 0; 154 value = 0; 155 /* Skip to the next space or end) */ 156 while ((input[i] != ' ') && (input[i] != 0)) 157 i++; 158 159 if (input[i] != 0) 160 i++; 161 162 /* Are we writing to EEPROM or MAC */ 163 switch (input[i]) { 164 case ('E'): 165 what = EEPROM; 166 break; 167 case ('M'): 168 what = MAC; 169 break; 170 default: 171 what = UNKNOWN; 172 break; 173 } 174 175 /* skip to the next space or end */ 176 while ((input[i] != ' ') && (input[i] != 0)) 177 i++; 178 if (input[i] != 0) 179 i++; 180 181 /* Find register to write into */ 182 j = 0; 183 while ((input[i] != ' ') && (input[i] != 0)) { 184 j = input[i] - 0x30; 185 if (j >= 0xA) { 186 j -= 0x07; 187 } 188 reg = (reg * 0x10) + j; 189 i++; 190 } 191 192 while ((input[i] != ' ') && (input[i] != 0)) 193 i++; 194 195 if (input[i] != 0) 196 i++; 197 else 198 what = UNKNOWN; 199 200 /* Get the value to write */ 201 j = 0; 202 while ((input[i] != ' ') && (input[i] != 0)) { 203 j = input[i] - 0x30; 204 if (j >= 0xA) { 205 j -= 0x07; 206 } 207 value = (value * 0x10) + j; 208 i++; 209 } 210 211 switch (what) { 212 case 1: 213 printf ("Writing EEPROM register %02x with %04x\n", reg, value); 214 write_eeprom_reg (value, reg); 215 break; 216 case 2: 217 printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value); 218 SMC_SELECT_BANK (reg >> 4); 219 SMC_outw (value, reg & 0xE); 220 break; 221 default: 222 printf ("Wrong\n"); 223 break; 224 } 225 break; 226 case ('D'): 227 dump_eeprom (); 228 break; 229 case ('M'): 230 dump_reg (); 231 break; 232 case ('C'): 233 copy_from_eeprom (); 234 break; 235 case ('P'): 236 print_macaddr (); 237 break; 238 default: 239 break; 240 } 241 242 } 243 244 return (0); 245 } 246 247 void copy_from_eeprom (void) 248 { 249 int i; 250 251 SMC_SELECT_BANK (1); 252 SMC_outw ((SMC_inw (CTL_REG) & !CTL_EEPROM_SELECT) | CTL_RELOAD, 253 CTL_REG); 254 i = 100; 255 while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --i) 256 udelay (100); 257 if (i == 0) { 258 printf ("Timeout Refreshing EEPROM registers\n"); 259 } else { 260 printf ("EEPROM contents copied to MAC\n"); 261 } 262 263 } 264 265 void print_macaddr (void) 266 { 267 int i, j, k, mac[6]; 268 269 printf ("Current MAC Address in SMSC91111 "); 270 SMC_SELECT_BANK (1); 271 for (i = 0; i < 5; i++) { 272 printf ("%02x:", SMC_inb (ADDR0_REG + i)); 273 } 274 275 printf ("%02x\n", SMC_inb (ADDR0_REG + 5)); 276 277 i = 0; 278 for (j = 0x20; j < 0x23; j++) { 279 k = read_eeprom_reg (j); 280 mac[i] = k & 0xFF; 281 i++; 282 mac[i] = k >> 8; 283 i++; 284 } 285 286 printf ("Current MAC Address in EEPROM "); 287 for (i = 0; i < 5; i++) 288 printf ("%02x:", mac[i]); 289 printf ("%02x\n", mac[5]); 290 291 } 292 void dump_eeprom (void) 293 { 294 int j, k; 295 296 printf ("IOS2-0 "); 297 for (j = 0; j < 8; j++) { 298 printf ("%03x ", j); 299 } 300 printf ("\n"); 301 302 for (k = 0; k < 4; k++) { 303 if (k == 0) 304 printf ("CONFIG "); 305 if (k == 1) 306 printf ("BASE "); 307 if ((k == 2) || (k == 3)) 308 printf (" "); 309 for (j = 0; j < 0x20; j += 4) { 310 printf ("%02x:%04x ", j + k, read_eeprom_reg (j + k)); 311 } 312 printf ("\n"); 313 } 314 315 for (j = 0x20; j < 0x40; j++) { 316 if ((j & 0x07) == 0) 317 printf ("\n"); 318 printf ("%02x:%04x ", j, read_eeprom_reg (j)); 319 } 320 printf ("\n"); 321 322 } 323 324 int read_eeprom_reg (int reg) 325 { 326 int timeout; 327 328 SMC_SELECT_BANK (2); 329 SMC_outw (reg, PTR_REG); 330 331 SMC_SELECT_BANK (1); 332 SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD, 333 CTL_REG); 334 timeout = 100; 335 while ((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout) 336 udelay (100); 337 if (timeout == 0) { 338 printf ("Timeout Reading EEPROM register %02x\n", reg); 339 return 0; 340 } 341 342 return SMC_inw (GP_REG); 343 344 } 345 346 int write_eeprom_reg (int value, int reg) 347 { 348 int timeout; 349 350 SMC_SELECT_BANK (2); 351 SMC_outw (reg, PTR_REG); 352 353 SMC_SELECT_BANK (1); 354 SMC_outw (value, GP_REG); 355 SMC_outw (SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG); 356 timeout = 100; 357 while ((SMC_inw (CTL_REG) & CTL_STORE) && --timeout) 358 udelay (100); 359 if (timeout == 0) { 360 printf ("Timeout Writing EEPROM register %02x\n", reg); 361 return 0; 362 } 363 364 return 1; 365 366 } 367 368 void dump_reg (void) 369 { 370 int i, j; 371 372 printf (" "); 373 for (j = 0; j < 4; j++) { 374 printf ("Bank%i ", j); 375 } 376 printf ("\n"); 377 for (i = 0; i < 0xF; i += 2) { 378 printf ("%02x ", i); 379 for (j = 0; j < 4; j++) { 380 SMC_SELECT_BANK (j); 381 printf ("%04x ", SMC_inw (i)); 382 } 383 printf ("\n"); 384 } 385 } 386 387 #else 388 389 int smc91111_eeprom (int argc, char *argv[]) 390 { 391 printf("Not supported for this board\n"); 392 return 1; 393 } 394 395 #endif 396