Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / examples / standalone / smc91111_eeprom.c
diff --git a/qemu/roms/u-boot/examples/standalone/smc91111_eeprom.c b/qemu/roms/u-boot/examples/standalone/smc91111_eeprom.c
new file mode 100644 (file)
index 0000000..afecbb1
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * (C) Copyright 2004
+ * Robin Getz rgetz@blacfin.uclinux.org
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Heavily borrowed from the following peoples GPL'ed software:
+ *  - Wolfgang Denk, DENX Software Engineering, wd@denx.de
+ *       Das U-boot
+ *  - Ladislav Michl ladis@linux-mips.org
+ *       A rejected patch on the U-Boot mailing list
+ */
+
+#include <common.h>
+#include <exports.h>
+#include "../drivers/net/smc91111.h"
+
+#ifndef SMC91111_EEPROM_INIT
+# define SMC91111_EEPROM_INIT()
+#endif
+
+#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE
+#define EEPROM         0x1
+#define MAC            0x2
+#define UNKNOWN                0x4
+
+void dump_reg (struct eth_device *dev);
+void dump_eeprom (struct eth_device *dev);
+int write_eeprom_reg (struct eth_device *dev, int value, int reg);
+void copy_from_eeprom (struct eth_device *dev);
+void print_MAC (struct eth_device *dev);
+int read_eeprom_reg (struct eth_device *dev, int reg);
+void print_macaddr (struct eth_device *dev);
+
+int smc91111_eeprom (int argc, char * const argv[])
+{
+       int c, i, j, done, line, reg, value, start, what;
+       char input[50];
+
+       struct eth_device dev;
+       dev.iobase = CONFIG_SMC91111_BASE;
+
+       /* Print the ABI version */
+       app_startup (argv);
+       if (XF_VERSION != (int) get_version ()) {
+               printf ("Expects ABI version %d\n", XF_VERSION);
+               printf ("Actual U-Boot ABI version %d\n",
+                       (int) get_version ());
+               printf ("Can't run\n\n");
+               return (0);
+       }
+
+       SMC91111_EEPROM_INIT();
+
+       if ((SMC_inw (&dev, BANK_SELECT) & 0xFF00) != 0x3300) {
+               printf ("Can't find SMSC91111\n");
+               return (0);
+       }
+
+       done = 0;
+       what = UNKNOWN;
+       printf ("\n");
+       while (!done) {
+               /* print the prompt */
+               printf ("SMC91111> ");
+               line = 0;
+               i = 0;
+               start = 1;
+               while (!line) {
+                       /* Wait for a keystroke */
+                       while (!tstc ());
+
+                       c = getc ();
+                       /* Make Uppercase */
+                       if (c >= 'Z')
+                               c -= ('a' - 'A');
+                       /* printf(" |%02x| ",c); */
+
+                       switch (c) {
+                       case '\r':      /* Enter                */
+                       case '\n':
+                               input[i] = 0;
+                               puts ("\r\n");
+                               line = 1;
+                               break;
+                       case '\0':      /* nul                  */
+                               continue;
+
+                       case 0x03:      /* ^C - break           */
+                               input[0] = 0;
+                               i = 0;
+                               line = 1;
+                               done = 1;
+                               break;
+
+                       case 0x5F:
+                       case 0x08:      /* ^H  - backspace      */
+                       case 0x7F:      /* DEL - backspace      */
+                               if (i > 0) {
+                                       puts ("\b \b");
+                                       i--;
+                               }
+                               break;
+                       default:
+                               if (start) {
+                                       if ((c == 'W') || (c == 'D')
+                                           || (c == 'M') || (c == 'C')
+                                           || (c == 'P')) {
+                                               putc (c);
+                                               input[i] = c;
+                                               if (i <= 45)
+                                                       i++;
+                                               start = 0;
+                                       }
+                               } else {
+                                       if ((c >= '0' && c <= '9')
+                                           || (c >= 'A' && c <= 'F')
+                                           || (c == 'E') || (c == 'M')
+                                           || (c == ' ')) {
+                                               putc (c);
+                                               input[i] = c;
+                                               if (i <= 45)
+                                                       i++;
+                                               break;
+                                       }
+                               }
+                               break;
+                       }
+               }
+
+               for (; i < 49; i++)
+                       input[i] = 0;
+
+               switch (input[0]) {
+               case ('W'):
+                       /* Line should be w reg value */
+                       i = 0;
+                       reg = 0;
+                       value = 0;
+                       /* Skip to the next space or end) */
+                       while ((input[i] != ' ') && (input[i] != 0))
+                               i++;
+
+                       if (input[i] != 0)
+                               i++;
+
+                       /* Are we writing to EEPROM or MAC */
+                       switch (input[i]) {
+                       case ('E'):
+                               what = EEPROM;
+                               break;
+                       case ('M'):
+                               what = MAC;
+                               break;
+                       default:
+                               what = UNKNOWN;
+                               break;
+                       }
+
+                       /* skip to the next space or end */
+                       while ((input[i] != ' ') && (input[i] != 0))
+                               i++;
+                       if (input[i] != 0)
+                               i++;
+
+                       /* Find register to write into */
+                       j = 0;
+                       while ((input[i] != ' ') && (input[i] != 0)) {
+                               j = input[i] - 0x30;
+                               if (j >= 0xA) {
+                                       j -= 0x07;
+                               }
+                               reg = (reg * 0x10) + j;
+                               i++;
+                       }
+
+                       while ((input[i] != ' ') && (input[i] != 0))
+                               i++;
+
+                       if (input[i] != 0)
+                               i++;
+                       else
+                               what = UNKNOWN;
+
+                       /* Get the value to write */
+                       j = 0;
+                       while ((input[i] != ' ') && (input[i] != 0)) {
+                               j = input[i] - 0x30;
+                               if (j >= 0xA) {
+                                       j -= 0x07;
+                               }
+                               value = (value * 0x10) + j;
+                               i++;
+                       }
+
+                       switch (what) {
+                       case 1:
+                               printf ("Writing EEPROM register %02x with %04x\n", reg, value);
+                               write_eeprom_reg (&dev, value, reg);
+                               break;
+                       case 2:
+                               printf ("Writing MAC register bank %i, reg %02x with %04x\n", reg >> 4, reg & 0xE, value);
+                               SMC_SELECT_BANK (&dev, reg >> 4);
+                               SMC_outw (&dev, value, reg & 0xE);
+                               break;
+                       default:
+                               printf ("Wrong\n");
+                               break;
+                       }
+                       break;
+               case ('D'):
+                       dump_eeprom (&dev);
+                       break;
+               case ('M'):
+                       dump_reg (&dev);
+                       break;
+               case ('C'):
+                       copy_from_eeprom (&dev);
+                       break;
+               case ('P'):
+                       print_macaddr (&dev);
+                       break;
+               default:
+                       break;
+               }
+
+       }
+
+       return (0);
+}
+
+void copy_from_eeprom (struct eth_device *dev)
+{
+       int i;
+
+       SMC_SELECT_BANK (dev, 1);
+       SMC_outw (dev, (SMC_inw (dev, CTL_REG) & !CTL_EEPROM_SELECT) |
+               CTL_RELOAD, CTL_REG);
+       i = 100;
+       while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --i)
+               udelay (100);
+       if (i == 0) {
+               printf ("Timeout Refreshing EEPROM registers\n");
+       } else {
+               printf ("EEPROM contents copied to MAC\n");
+       }
+
+}
+
+void print_macaddr (struct eth_device *dev)
+{
+       int i, j, k, mac[6];
+
+       printf ("Current MAC Address in SMSC91111 ");
+       SMC_SELECT_BANK (dev, 1);
+       for (i = 0; i < 5; i++) {
+               printf ("%02x:", SMC_inb (dev, ADDR0_REG + i));
+       }
+
+       printf ("%02x\n", SMC_inb (dev, ADDR0_REG + 5));
+
+       i = 0;
+       for (j = 0x20; j < 0x23; j++) {
+               k = read_eeprom_reg (dev, j);
+               mac[i] = k & 0xFF;
+               i++;
+               mac[i] = k >> 8;
+               i++;
+       }
+
+       printf ("Current MAC Address in EEPROM    ");
+       for (i = 0; i < 5; i++)
+               printf ("%02x:", mac[i]);
+       printf ("%02x\n", mac[5]);
+
+}
+void dump_eeprom (struct eth_device *dev)
+{
+       int j, k;
+
+       printf ("IOS2-0    ");
+       for (j = 0; j < 8; j++) {
+               printf ("%03x     ", j);
+       }
+       printf ("\n");
+
+       for (k = 0; k < 4; k++) {
+               if (k == 0)
+                       printf ("CONFIG ");
+               if (k == 1)
+                       printf ("BASE   ");
+               if ((k == 2) || (k == 3))
+                       printf ("       ");
+               for (j = 0; j < 0x20; j += 4) {
+                       printf ("%02x:%04x ", j + k,
+                               read_eeprom_reg (dev, j + k));
+               }
+               printf ("\n");
+       }
+
+       for (j = 0x20; j < 0x40; j++) {
+               if ((j & 0x07) == 0)
+                       printf ("\n");
+               printf ("%02x:%04x ", j, read_eeprom_reg (dev, j));
+       }
+       printf ("\n");
+
+}
+
+int read_eeprom_reg (struct eth_device *dev, int reg)
+{
+       int timeout;
+
+       SMC_SELECT_BANK (dev, 2);
+       SMC_outw (dev, reg, PTR_REG);
+
+       SMC_SELECT_BANK (dev, 1);
+       SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
+               CTL_RELOAD, CTL_REG);
+       timeout = 100;
+       while ((SMC_inw (dev, CTL_REG) & CTL_RELOAD) && --timeout)
+               udelay (100);
+       if (timeout == 0) {
+               printf ("Timeout Reading EEPROM register %02x\n", reg);
+               return 0;
+       }
+
+       return SMC_inw (dev, GP_REG);
+
+}
+
+int write_eeprom_reg (struct eth_device *dev, int value, int reg)
+{
+       int timeout;
+
+       SMC_SELECT_BANK (dev, 2);
+       SMC_outw (dev, reg, PTR_REG);
+
+       SMC_SELECT_BANK (dev, 1);
+       SMC_outw (dev, value, GP_REG);
+       SMC_outw (dev, SMC_inw (dev, CTL_REG) | CTL_EEPROM_SELECT |
+               CTL_STORE, CTL_REG);
+       timeout = 100;
+       while ((SMC_inw (dev, CTL_REG) & CTL_STORE) && --timeout)
+               udelay (100);
+       if (timeout == 0) {
+               printf ("Timeout Writing EEPROM register %02x\n", reg);
+               return 0;
+       }
+
+       return 1;
+
+}
+
+void dump_reg (struct eth_device *dev)
+{
+       int i, j;
+
+       printf ("    ");
+       for (j = 0; j < 4; j++) {
+               printf ("Bank%i ", j);
+       }
+       printf ("\n");
+       for (i = 0; i < 0xF; i += 2) {
+               printf ("%02x  ", i);
+               for (j = 0; j < 4; j++) {
+                       SMC_SELECT_BANK (dev, j);
+                       printf ("%04x  ", SMC_inw (dev, i));
+               }
+               printf ("\n");
+       }
+}