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