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 #ifndef SMC91111_EEPROM_INIT 35 # define SMC91111_EEPROM_INIT() 36 #endif 37 38 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE 39 #define EEPROM 0x1 40 #define MAC 0x2 41 #define UNKNOWN 0x4 42 43 void dump_reg (struct eth_device *dev); 44 void dump_eeprom (struct eth_device *dev); 45 int write_eeprom_reg (struct eth_device *dev, int value, int reg); 46 void copy_from_eeprom (struct eth_device *dev); 47 void print_MAC (struct eth_device *dev); 48 int read_eeprom_reg (struct eth_device *dev, int reg); 49 void print_macaddr (struct eth_device *dev); 50 51 int smc91111_eeprom (int argc, char *argv[]) 52 { 53 int c, i, j, done, line, reg, value, start, what; 54 char input[50]; 55 56 struct eth_device dev = { 57 .iobase = CONFIG_SMC91111_BASE 58 }; 59 60 /* Print the ABI version */ 61 app_startup (argv); 62 if (XF_VERSION != (int) get_version ()) { 63 printf ("Expects ABI version %d\n", XF_VERSION); 64 printf ("Actual U-Boot ABI version %d\n", 65 (int) get_version ()); 66 printf ("Can't run\n\n"); 67 return (0); 68 } 69 70 SMC91111_EEPROM_INIT(); 71 72 if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) { 73 printf ("Can't find SMSC91111\n"); 74 return (0); 75 } 76 77 done = 0; 78 what = UNKNOWN; 79 printf ("\n"); 80 while (!done) { 81 /* print the prompt */ 82 printf ("SMC91111> "); 83 line = 0; 84 i = 0; 85 start = 1; 86 while (!line) { 87 /* Wait for a keystroke */ 88 while (!tstc ()); 89 90 c = getc (); 91 /* Make Uppercase */ 92 if (c >= 'Z') 93 c -= ('a' - 'A'); 94 /* printf(" |%02x| ",c); */ 95 96 switch (c) { 97 case '\r': /* Enter */ 98 case '\n': 99 input[i] = 0; 100 puts ("\r\n"); 101 line = 1; 102 break; 103 case '\0': /* nul */ 104 continue; 105 106 case 0x03: /* ^C - break */ 107 input[0] = 0; 108 i = 0; 109 line = 1; 110 done = 1; 111 break; 112 113 case 0x5F: 114 case 0x08: /* ^H - backspace */ 115 case 0x7F: /* DEL - backspace */ 116 if (i > 0) { 117 puts ("\b \b"); 118 i--; 119 } 120 break; 121 default: 122 if (start) { 123 if ((c == 'W') || (c == 'D') 124 || (c == 'M') || (c == 'C') 125 || (c == 'P')) { 126 putc (c); 127 input[i] = c; 128 if (i <= 45) 129 i++; 130 start = 0; 131 } 132 } else { 133 if ((c >= '0' && c <= '9') 134 || (c >= 'A' && c <= 'F') 135 || (c == 'E') || (c == 'M') 136 || (c == ' ')) { 137 putc (c); 138 input[i] = c; 139 if (i <= 45) 140 i++; 141 break; 142 } 143 } 144 break; 145 } 146 } 147 148 for (; i < 49; i++) 149 input[i] = 0; 150 151 switch (input[0]) { 152 case ('W'): 153 /* Line should be w reg value */ 154 i = 0; 155 reg = 0; 156 value = 0; 157 /* Skip to the next space or end) */ 158 while ((input[i] != ' ') && (input[i] != 0)) 159 i++; 160 161 if (input[i] != 0) 162 i++; 163 164 /* Are we writing to EEPROM or MAC */ 165 switch (input[i]) { 166 case ('E'): 167 what = EEPROM; 168 break; 169 case ('M'): 170 what = MAC; 171 break; 172 default: 173 what = UNKNOWN; 174 break; 175 } 176 177 /* skip to the next space or end */ 178 while ((input[i] != ' ') && (input[i] != 0)) 179 i++; 180 if (input[i] != 0) 181 i++; 182 183 /* Find register to write into */ 184 j = 0; 185 while ((input[i] != ' ') && (input[i] != 0)) { 186 j = input[i] - 0x30; 187 if (j >= 0xA) { 188 j -= 0x07; 189 } 190 reg = (reg * 0x10) + j; 191 i++; 192 } 193 194 while ((input[i] != ' ') && (input[i] != 0)) 195 i++; 196 197 if (input[i] != 0) 198 i++; 199 else 200 what = UNKNOWN; 201 202 /* Get the value to write */ 203 j = 0; 204 while ((input[i] != ' ') && (input[i] != 0)) { 205 j = input[i] - 0x30; 206 if (j >= 0xA) { 207 j -= 0x07; 208 } 209 value = (value * 0x10) + j; 210 i++; 211 } 212 213 switch (what) { 214 case 1: 215 printf ("Writing EEPROM register %02x with %04x\n", reg, value); 216 write_eeprom_reg (&dev, value, reg); 217 break; 218 case 2: 219 printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value); 220 SMC_SELECT_BANK (&dev, reg >> 4); 221 SMC_outw (&dev, value, reg & 0xE); 222 break; 223 default: 224 printf ("Wrong\n"); 225 break; 226 } 227 break; 228 case ('D'): 229 dump_eeprom (&dev); 230 break; 231 case ('M'): 232 dump_reg (&dev); 233 break; 234 case ('C'): 235 copy_from_eeprom (&dev); 236 break; 237 case ('P'): 238 print_macaddr (&dev); 239 break; 240 default: 241 break; 242 } 243 244 } 245 246 return (0); 247 } 248 249 void copy_from_eeprom (struct eth_device *dev) 250 { 251 int i; 252 253 SMC_SELECT_BANK (dev, 1); 254 SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) | 255 CTL_RELOAD, CTL_REG); 256 i = 100; 257 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i) 258 udelay (100); 259 if (i == 0) { 260 printf ("Timeout Refreshing EEPROM registers\n"); 261 } else { 262 printf ("EEPROM contents copied to MAC\n"); 263 } 264 265 } 266 267 void print_macaddr (struct eth_device *dev) 268 { 269 int i, j, k, mac[6]; 270 271 printf ("Current MAC Address in SMSC91111 "); 272 SMC_SELECT_BANK (dev, 1); 273 for (i = 0; i < 5; i++) { 274 printf ("%02x:", SMC_inb (dev, ADDR0_REG + i)); 275 } 276 277 printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5)); 278 279 i = 0; 280 for (j = 0x20; j < 0x23; j++) { 281 k = read_eeprom_reg (dev, j); 282 mac[i] = k & 0xFF; 283 i++; 284 mac[i] = k >> 8; 285 i++; 286 } 287 288 printf ("Current MAC Address in EEPROM "); 289 for (i = 0; i < 5; i++) 290 printf ("%02x:", mac[i]); 291 printf ("%02x\n", mac[5]); 292 293 } 294 void dump_eeprom (struct eth_device *dev) 295 { 296 int j, k; 297 298 printf ("IOS2-0 "); 299 for (j = 0; j < 8; j++) { 300 printf ("%03x ", j); 301 } 302 printf ("\n"); 303 304 for (k = 0; k < 4; k++) { 305 if (k == 0) 306 printf ("CONFIG "); 307 if (k == 1) 308 printf ("BASE "); 309 if ((k == 2) || (k == 3)) 310 printf (" "); 311 for (j = 0; j < 0x20; j += 4) { 312 printf ("%02x:%04x ", j + k, 313 read_eeprom_reg (dev, j + k)); 314 } 315 printf ("\n"); 316 } 317 318 for (j = 0x20; j < 0x40; j++) { 319 if ((j & 0x07) == 0) 320 printf ("\n"); 321 printf ("%02x:%04x ", j, read_eeprom_reg (dev, j)); 322 } 323 printf ("\n"); 324 325 } 326 327 int read_eeprom_reg (struct eth_device *dev, int reg) 328 { 329 int timeout; 330 331 SMC_SELECT_BANK (dev, 2); 332 SMC_outw (dev, reg, PTR_REG); 333 334 SMC_SELECT_BANK (dev, 1); 335 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 336 CTL_RELOAD, CTL_REG); 337 timeout = 100; 338 while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout) 339 udelay (100); 340 if (timeout == 0) { 341 printf ("Timeout Reading EEPROM register %02x\n", reg); 342 return 0; 343 } 344 345 return SMC_inw (dev, GP_REG); 346 347 } 348 349 int write_eeprom_reg (struct eth_device *dev, int value, int reg) 350 { 351 int timeout; 352 353 SMC_SELECT_BANK (dev, 2); 354 SMC_outw (dev, reg, PTR_REG); 355 356 SMC_SELECT_BANK (dev, 1); 357 SMC_outw (dev, value, GP_REG); 358 SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT | 359 CTL_STORE, CTL_REG); 360 timeout = 100; 361 while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout) 362 udelay (100); 363 if (timeout == 0) { 364 printf ("Timeout Writing EEPROM register %02x\n", reg); 365 return 0; 366 } 367 368 return 1; 369 370 } 371 372 void dump_reg (struct eth_device *dev) 373 { 374 int i, j; 375 376 printf (" "); 377 for (j = 0; j < 4; j++) { 378 printf ("Bank%i ", j); 379 } 380 printf ("\n"); 381 for (i = 0; i < 0xF; i += 2) { 382 printf ("%02x ", i); 383 for (j = 0; j < 4; j++) { 384 SMC_SELECT_BANK (dev, j); 385 printf ("%04x ", SMC_inw (dev, i)); 386 } 387 printf ("\n"); 388 } 389 } 390