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 "../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
  26void dump_reg (struct eth_device *dev);
  27void dump_eeprom (struct eth_device *dev);
  28int write_eeprom_reg (struct eth_device *dev, int value, int reg);
  29void copy_from_eeprom (struct eth_device *dev);
  30void print_MAC (struct eth_device *dev);
  31int read_eeprom_reg (struct eth_device *dev, int reg);
  32void print_macaddr (struct eth_device *dev);
  33
  34int 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
 231void 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
 249void 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}
 276void 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
 309int 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
 331int 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
 354void 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