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