Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / v38b / ethaddr.c
diff --git a/qemu/roms/u-boot/board/v38b/ethaddr.c b/qemu/roms/u-boot/board/v38b/ethaddr.c
new file mode 100644 (file)
index 0000000..982998f
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+
+/* For the V38B board the pin is GPIO_PSC_6 */
+#define GPIO_PIN       GPIO_PSC6_0
+
+#define NO_ERROR       0
+#define ERR_NO_NUMBER  1
+#define ERR_BAD_NUMBER 2
+
+static int is_high(void);
+static int check_device(void);
+static void io_out(int value);
+static void io_input(void);
+static void io_output(void);
+static void init_gpio(void);
+static void read_byte(unsigned char *data);
+static void write_byte(unsigned char command);
+
+void read_2501_memory(unsigned char *psernum, unsigned char *perr);
+void board_get_enetaddr(uchar *enetaddr);
+
+
+static int is_high()
+{
+       return (*((vu_long *) MPC5XXX_WU_GPIO_DATA_I) & GPIO_PIN);
+}
+
+static void io_out(int value)
+{
+       if (value)
+               *((vu_long *) MPC5XXX_WU_GPIO_DATA_O) |= GPIO_PIN;
+       else
+               *((vu_long *) MPC5XXX_WU_GPIO_DATA_O) &= ~GPIO_PIN;
+}
+
+static void io_input()
+{
+       *((vu_long *) MPC5XXX_WU_GPIO_DIR) &= ~GPIO_PIN;
+       udelay(3);      /* allow input to settle */
+}
+
+static void io_output()
+{
+       *((vu_long *) MPC5XXX_WU_GPIO_DIR) |= GPIO_PIN;
+}
+
+static void init_gpio()
+{
+       *((vu_long *) MPC5XXX_WU_GPIO_ENABLE) |= GPIO_PIN;      /* Enable appropriate pin */
+}
+
+void read_2501_memory(unsigned char *psernum, unsigned char *perr)
+{
+#define NBYTES 28
+       unsigned char crcval, i;
+       unsigned char buf[NBYTES];
+
+       *perr = 0;
+       crcval = 0;
+
+       for (i = 0; i < NBYTES; i++)
+               buf[i] = 0;
+
+       if (!check_device())
+               *perr = ERR_NO_NUMBER;
+       else {
+               *perr = NO_ERROR;
+               write_byte(0xCC);               /* skip ROM (0xCC) */
+               write_byte(0xF0);               /* Read memory command 0xF0 */
+               write_byte(0x00);               /* Address TA1=0, TA2=0 */
+               write_byte(0x00);
+               read_byte(&crcval);             /* Read CRC of address and command */
+
+               for (i = 0; i < NBYTES; i++)
+                       read_byte(&buf[i]);
+       }
+       if (strncmp((const char *) &buf[11], "MAREL IEEE 802.3", 16)) {
+               *perr = ERR_BAD_NUMBER;
+               psernum[0] = 0x00;
+               psernum[1] = 0xE0;
+               psernum[2] = 0xEE;
+               psernum[3] = 0xFF;
+               psernum[4] = 0xFF;
+               psernum[5] = 0xFF;
+       } else {
+               psernum[0] = 0x00;
+               psernum[1] = 0xE0;
+               psernum[2] = 0xEE;
+               psernum[3] = buf[7];
+               psernum[4] = buf[6];
+               psernum[5] = buf[5];
+       }
+}
+
+static int check_device()
+{
+       int found;
+
+       io_output();
+       io_out(0);
+       udelay(500);  /* must be at least 480 us low pulse */
+
+       io_input();
+       udelay(60);
+
+       found = (is_high() == 0) ? 1 : 0;
+       udelay(500);  /* must be at least 480 us low pulse */
+
+       return found;
+}
+
+static void write_byte(unsigned char command)
+{
+       char i;
+
+       for (i = 0; i < 8; i++) {
+               /* 1 us to 15 us low pulse starts bit slot */
+               /* Start with high pulse for 3 us */
+               io_input();
+               udelay(3);
+
+               io_out(0);
+               io_output();
+               udelay(3);
+
+               if (command & 0x01) {
+                       /* 60 us high for 1-bit */
+                       io_input();
+                       udelay(60);
+               } else
+                       /* 60 us low for 0-bit */
+                       udelay(60);
+               /*  Leave pin as input */
+               io_input();
+
+               command = command >> 1;
+       }
+}
+
+static void read_byte(unsigned char *data)
+{
+       unsigned char i, rdat = 0;
+
+       for (i = 0; i < 8; i++) {
+               /* read one bit from one-wire device */
+
+               /* 1 - 15 us low starts bit slot */
+               io_out(0);
+               io_output();
+               udelay(0);
+
+               /* allow line to be pulled high */
+               io_input();
+
+               /* delay 10 us */
+               udelay(10);
+
+               /* now sample input status */
+               if (is_high())
+                       rdat = (rdat >> 1) | 0x80;
+               else
+                       rdat = rdat >> 1;
+
+               udelay(60);     /* at least 60 us */
+       }
+       /* copy the return value */
+       *data = rdat;
+}
+
+void board_get_enetaddr(uchar *enetaddr)
+{
+       unsigned char sn[6], err = NO_ERROR;
+
+       init_gpio();
+
+       read_2501_memory(sn, &err);
+
+       if (err == NO_ERROR) {
+               sprintf((char *)enetaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+                               sn[0], sn[1], sn[2], sn[3], sn[4], sn[5]);
+               printf("MAC address: %s\n", enetaddr);
+               setenv("ethaddr", (char *)enetaddr);
+       } else {
+               sprintf((char *)enetaddr, "00:01:02:03:04:05");
+               printf("Error reading MAC address.\n");
+               printf("Setting default to %s\n", enetaddr);
+               setenv("ethaddr", (char *)enetaddr);
+       }
+}