Merge branch 'master' of git://git.denx.de/u-boot-mpc83xx
authorWolfgang Denk <wd@denx.de>
Tue, 24 Feb 2009 21:52:16 +0000 (22:52 +0100)
committerWolfgang Denk <wd@denx.de>
Tue, 24 Feb 2009 21:52:16 +0000 (22:52 +0100)
board/freescale/mpc8641hpcn/mpc8641hpcn.c
common/cmd_nvedit.c
drivers/net/tsec.c
examples/.gitignore
examples/Makefile
examples/smc911x_eeprom.c [new file with mode: 0644]
include/asm-ppc/config.h
include/common.h
net/eth.c
net/net.c

index 49718da..c94fc3f 100644 (file)
@@ -46,6 +46,9 @@ int checkboard(void)
                "System Version: 0x%02x, FPGA Version: 0x%02x\n",
                in8(PIXIS_BASE + PIXIS_ID), in8(PIXIS_BASE + PIXIS_VER),
                in8(PIXIS_BASE + PIXIS_PVER));
+#ifdef CONFIG_PHYS_64BIT
+       printf ("       36-bit physical address map\n");
+#endif
        return 0;
 }
 
index 02b18ec..68c673e 100644 (file)
@@ -75,7 +75,12 @@ DECLARE_GLOBAL_DATA_PTR;
 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
 #define        N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))
 
+static int env_id = 1;
 
+int get_env_id (void)
+{
+       return env_id;
+}
 /************************************************************************
  * Command interface: print one or all environment variables
  */
@@ -160,6 +165,7 @@ int _do_setenv (int flag, int argc, char *argv[])
                return 1;
        }
 
+       env_id++;
        /*
         * search if variable with this name already exists
         */
index 9edba6a..1f5d1b4 100644 (file)
@@ -1332,6 +1332,35 @@ struct phy_info phy_info_cis8201 = {
                           {miim_end,}
                           },
 };
+struct phy_info phy_info_VSC8211 = {
+       0xfc4b,
+       "Vitesse VSC8211",
+       4,
+       (struct phy_cmd[]) { /* config */
+                          /* Override PHY config settings */
+                          {MIIM_CIS8201_AUX_CONSTAT,
+                           MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
+                          /* Set up the interface mode */
+                          {MIIM_CIS8201_EXT_CON1,
+                           MIIM_CIS8201_EXTCON1_INIT, NULL},
+                          /* Configure some basic stuff */
+                          {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]) { /* startup */
+                          /* Read the Status (2x to make sure link is right) */
+                          {MIIM_STATUS, miim_read, NULL},
+                          /* Auto-negotiate */
+                          {MIIM_STATUS, miim_read, &mii_parse_sr},
+                          /* Read the status */
+                          {MIIM_CIS8201_AUX_CONSTAT, miim_read,
+                           &mii_parse_cis8201},
+                          {miim_end,}
+                          },
+       (struct phy_cmd[]) { /* shutdown */
+                          {miim_end,}
+       },
+};
 struct phy_info phy_info_VSC8244 = {
        0x3f1b,
        "Vitesse VSC8244",
@@ -1590,6 +1619,7 @@ struct phy_info *phy_info[] = {
        &phy_info_M88E1149S,
        &phy_info_dm9161,
        &phy_info_lxt971,
+       &phy_info_VSC8211,
        &phy_info_VSC8244,
        &phy_info_VSC8601,
        &phy_info_dp83865,
index 806425f..0d1864c 100644 (file)
@@ -6,5 +6,6 @@
 /timer
 /sched
 /smc91111_eeprom
+/smc911x_eeprom
 *.bin
 *.srec
index 927010d..dbcfa92 100644 (file)
@@ -105,9 +105,10 @@ BIN        += sched.bin
 endif
 
 ifeq ($(ARCH),blackfin)
-ELF    += smc91111_eeprom
-SREC   += smc91111_eeprom.srec
-BIN    += smc91111_eeprom.bin
+BFIN_BIN = smc91111_eeprom smc911x_eeprom
+ELF    += $(BFIN_BIN)
+SREC   += $(addsuffix .srec,$(BFIN_BIN))
+BIN    += $(addsuffix .bin,$(BFIN_BIN))
 endif
 
 # The following example is pretty 8xx specific...
diff --git a/examples/smc911x_eeprom.c b/examples/smc911x_eeprom.c
new file mode 100644 (file)
index 0000000..3dac4d3
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * smc911x_eeprom.c - EEPROM interface to SMC911x parts.
+ * Only tested on SMSC9118 though ...
+ *
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ * Based on smc91111_eeprom.c which:
+ * 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>
+
+#ifdef CONFIG_DRIVER_SMC911X
+
+#include "../drivers/net/smc911x.h"
+
+/**
+ *     smsc_ctrlc - detect press of CTRL+C (common ctrlc() isnt exported!?)
+ */
+static int smsc_ctrlc(void)
+{
+       return (tstc() && getc() == 0x03);
+}
+
+/**
+ *     usage - dump usage information
+ */
+static void usage(void)
+{
+       puts(
+               "MAC/EEPROM Commands:\n"
+               " P : Print the MAC addresses\n"
+               " D : Dump the EEPROM contents\n"
+               " M : Dump the MAC contents\n"
+               " C : Copy the MAC address from the EEPROM to the MAC\n"
+               " W : Write a register in the EEPROM or in the MAC\n"
+               " Q : Quit\n"
+               "\n"
+               "Some commands take arguments:\n"
+               " W <E|M> <register> <value>\n"
+               "    E: EEPROM   M: MAC\n"
+       );
+}
+
+/**
+ *     dump_regs - dump the MAC registers
+ *
+ * Registers 0x00 - 0x50 are FIFOs.  The 0x50+ are the control registers
+ * and they're all 32bits long.  0xB8+ are reserved, so don't bother.
+ */
+static void dump_regs(void)
+{
+       u8 i, j = 0;
+       for (i = 0x50; i < 0xB8; i += sizeof(u32))
+               printf("%02x: 0x%08x %c", i, reg_read(CONFIG_DRIVER_SMC911X_BASE + i),
+                       (j++ % 2 ? '\n' : ' '));
+}
+
+/**
+ *     do_eeprom_cmd - handle eeprom communication
+ */
+static int do_eeprom_cmd(int cmd, u8 reg)
+{
+       if (reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY) {
+               printf("eeprom_cmd: busy at start (E2P_CMD = 0x%08x)\n",
+                       reg_read(E2P_CMD));
+               return -1;
+       }
+
+       reg_write(E2P_CMD, E2P_CMD_EPC_BUSY | cmd | reg);
+
+       while (reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY)
+               if (smsc_ctrlc()) {
+                       printf("eeprom_cmd: timeout (E2P_CMD = 0x%08x)\n",
+                               reg_read(E2P_CMD));
+                       return -1;
+               }
+
+       return 0;
+}
+
+/**
+ *     read_eeprom_reg - read specified register in EEPROM
+ */
+static u8 read_eeprom_reg(u8 reg)
+{
+       int ret = do_eeprom_cmd(E2P_CMD_EPC_CMD_READ, reg);
+       return (ret ? : reg_read(E2P_DATA));
+}
+
+/**
+ *     write_eeprom_reg - write specified value into specified register in EEPROM
+ */
+static int write_eeprom_reg(u8 value, u8 reg)
+{
+       int ret;
+
+       /* enable erasing/writing */
+       ret = do_eeprom_cmd(E2P_CMD_EPC_CMD_EWEN, reg);
+       if (ret)
+               goto done;
+
+       /* erase the eeprom reg */
+       ret = do_eeprom_cmd(E2P_CMD_EPC_CMD_ERASE, reg);
+       if (ret)
+               goto done;
+
+       /* write the eeprom reg */
+       reg_write(E2P_DATA, value);
+       ret = do_eeprom_cmd(E2P_CMD_EPC_CMD_WRITE, reg);
+       if (ret)
+               goto done;
+
+       /* disable erasing/writing */
+       ret = do_eeprom_cmd(E2P_CMD_EPC_CMD_EWDS, reg);
+
+ done:
+       return ret;
+}
+
+/**
+ *     skip_space - find first non-whitespace in given pointer
+ */
+static char *skip_space(char *buf)
+{
+       while (buf[0] == ' ' || buf[0] == '\t')
+               ++buf;
+       return buf;
+}
+
+/**
+ *     write_stuff - handle writing of MAC registers / eeprom
+ */
+static void write_stuff(char *line)
+{
+       char dest;
+       char *endp;
+       u8 reg;
+       u32 value;
+
+       /* Skip over the "W " part of the command */
+       line = skip_space(line + 1);
+
+       /* Figure out destination */
+       switch (line[0]) {
+       case 'E':
+       case 'M':
+               dest = line[0];
+               break;
+       default:
+       invalid_usage:
+               printf("ERROR: Invalid write usage\n");
+               usage();
+               return;
+       }
+
+       /* Get the register to write */
+       line = skip_space(line + 1);
+       reg = simple_strtoul(line, &endp, 16);
+       if (line == endp)
+               goto invalid_usage;
+
+       /* Get the value to write */
+       line = skip_space(endp);
+       value = simple_strtoul(line, &endp, 16);
+       if (line == endp)
+               goto invalid_usage;
+
+       /* Check for trailing cruft */
+       line = skip_space(endp);
+       if (line[0])
+               goto invalid_usage;
+
+       /* Finally, execute the command */
+       if (dest == 'E') {
+               printf("Writing EEPROM register %02x with %02x\n", reg, value);
+               write_eeprom_reg(value, reg);
+       } else {
+               printf("Writing MAC register %02x with %08x\n", reg, value);
+               reg_write(CONFIG_DRIVER_SMC911X_BASE + reg, value);
+       }
+}
+
+/**
+ *     copy_from_eeprom - copy MAC address in eeprom to address registers
+ */
+static void copy_from_eeprom(void)
+{
+       ulong addrl =
+               read_eeprom_reg(0x01) |
+               read_eeprom_reg(0x02) << 8 |
+               read_eeprom_reg(0x03) << 16 |
+               read_eeprom_reg(0x04) << 24;
+       ulong addrh =
+               read_eeprom_reg(0x05) |
+               read_eeprom_reg(0x06) << 8;
+       smc911x_set_mac_csr(ADDRL, addrl);
+       smc911x_set_mac_csr(ADDRH, addrh);
+       puts("EEPROM contents copied to MAC\n");
+}
+
+/**
+ *     print_macaddr - print MAC address registers and MAC address in eeprom
+ */
+static void print_macaddr(void)
+{
+       puts("Current MAC Address in MAC:     ");
+       ulong addrl = smc911x_get_mac_csr(ADDRL);
+       ulong addrh = smc911x_get_mac_csr(ADDRH);
+       printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+               (u8)(addrl), (u8)(addrl >> 8), (u8)(addrl >> 16),
+               (u8)(addrl >> 24), (u8)(addrh), (u8)(addrh >> 8));
+
+       puts("Current MAC Address in EEPROM:  ");
+       int i;
+       for (i = 1; i < 6; ++i)
+               printf("%02x:", read_eeprom_reg(i));
+       printf("%02x\n", read_eeprom_reg(i));
+}
+
+/**
+ *     dump_eeprom - dump the whole content of the EEPROM
+ */
+static void dump_eeprom(void)
+{
+       int i;
+       puts("EEPROM:\n");
+       for (i = 0; i < 7; ++i)
+               printf("%02x: 0x%02x\n", i, read_eeprom_reg(i));
+}
+
+/**
+ *     smc911x_init - get the MAC/EEPROM up and ready for use
+ */
+static int smc911x_init(void)
+{
+       /* See if there is anything there */
+       if (!smc911x_detect_chip())
+               return 1;
+
+       smc911x_reset();
+
+       /* Make sure we set EEDIO/EECLK to the EEPROM */
+       if (reg_read(GPIO_CFG) & GPIO_CFG_EEPR_EN) {
+               while (reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY)
+                       if (smsc_ctrlc()) {
+                               printf("init: timeout (E2P_CMD = 0x%08x)\n", reg_read(E2P_CMD));
+                               return 1;
+                       }
+               reg_write(GPIO_CFG, reg_read(GPIO_CFG) & ~GPIO_CFG_EEPR_EN);
+       }
+
+       return 0;
+}
+
+/**
+ *     getline - consume a line of input and handle some escape sequences
+ */
+static char *getline(void)
+{
+       static char buffer[100];
+       char c;
+       size_t i;
+
+       i = 0;
+       while (1) {
+               buffer[i] = '\0';
+               while (!tstc())
+                       continue;
+
+               c = getc();
+               /* Convert to uppercase */
+               if (c >= 'a' && c <= 'z')
+                       c -= ('a' - 'A');
+
+               switch (c) {
+               case '\r':      /* Enter/Return key */
+               case '\n':
+                       puts("\n");
+                       return buffer;
+
+               case 0x03:      /* ^C - break */
+                       return NULL;
+
+               case 0x5F:
+               case 0x08:      /* ^H  - backspace */
+               case 0x7F:      /* DEL - backspace */
+                       if (i) {
+                               puts("\b \b");
+                               i--;
+                       }
+                       break;
+
+               default:
+                       /* Ignore control characters */
+                       if (c < 0x20)
+                               break;
+                       /* Queue up all other characters */
+                       buffer[i++] = c;
+                       printf("%c", c);
+                       break;
+               }
+       }
+}
+
+/**
+ *     smc911x_eeprom - our application's main() function
+ */
+int smc911x_eeprom(int argc, char *argv[])
+{
+       /* Print the ABI version */
+       app_startup(argv);
+       if (XF_VERSION != get_version()) {
+               printf("Expects ABI version %d\n", XF_VERSION);
+               printf("Actual U-Boot ABI version %lu\n", get_version());
+               printf("Can't run\n\n");
+               return 1;
+       }
+
+       /* Initialize the MAC/EEPROM somewhat */
+       puts("\n");
+       if (smc911x_init())
+               return 1;
+
+       /* Dump helpful usage information */
+       puts("\n");
+       usage();
+       puts("\n");
+
+       while (1) {
+               char *line;
+
+               /* Send the prompt and wait for a line */
+               puts("eeprom> ");
+               line = getline();
+
+               /* Got a ctrl+c */
+               if (!line)
+                       return 0;
+
+               /* Eat leading space */
+               line = skip_space(line);
+
+               /* Empty line, try again */
+               if (!line[0])
+                       continue;
+
+               /* Only accept 1 letter commands */
+               if (line[0] && line[1] && line[1] != ' ' && line[1] != '\t')
+                       goto unknown_cmd;
+
+               /* Now parse the command */
+               switch (line[0]) {
+               case 'W': write_stuff(line);  break;
+               case 'D': dump_eeprom();      break;
+               case 'M': dump_regs();        break;
+               case 'C': copy_from_eeprom(); break;
+               case 'P': print_macaddr();    break;
+               unknown_cmd:
+               default:  puts("ERROR: Unknown command!\n\n");
+               case '?':
+               case 'H': usage();            break;
+               case 'Q': return 0;
+               }
+       }
+}
+
+#else
+int smc911x_eeprom(int argc, char *argv[])
+{
+       puts("Not supported for this board\n");
+       return 1;
+}
+#endif
index 275a7c8..0900f65 100644 (file)
@@ -22,7 +22,7 @@
 #define _ASM_CONFIG_H_
 
 #ifndef CONFIG_MAX_MEM_MAPPED
-#if defined(CONFIG_4xx) || defined(CONFIG_E500)
+#if defined(CONFIG_4xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
 #define CONFIG_MAX_MEM_MAPPED  ((phys_size_t)2 << 30)
 #else
 #define CONFIG_MAX_MEM_MAPPED  (256 << 20)
index afee188..b75ea60 100644 (file)
@@ -269,6 +269,7 @@ void        forceenv     (char *, char *);
 #ifdef CONFIG_AUTO_COMPLETE
 int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
 #endif
+int get_env_id (void);
 
 void   pci_init      (void);
 void   pci_init_board(void);
index ec2ef1a..217e885 100644 (file)
--- a/net/eth.c
+++ b/net/eth.c
@@ -28,6 +28,9 @@
 
 #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI)
 
+static char *act = NULL;
+static int  env_changed_id = 0;
+
 /*
  * CPU and board-specific Ethernet initializations.  Aliased function
  * signals caller to move on
@@ -461,13 +464,17 @@ void eth_try_another(int first_restart)
 #ifdef CONFIG_NET_MULTI
 void eth_set_current(void)
 {
-       char *act;
        struct eth_device* old_current;
+       int     env_id;
 
        if (!eth_current)       /* XXX no current */
                return;
 
-       act = getenv("ethact");
+       env_id = get_env_id();
+       if ((act == NULL) || (env_changed_id != env_id)) {
+               act = getenv("ethact");
+               env_changed_id = env_id;
+       }
        if (act != NULL) {
                old_current = eth_current;
                do {
index 459baf4..a55f4d3 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -209,6 +209,8 @@ uchar               NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
 ulong          NetArpWaitTimerStart;
 int            NetArpWaitTry;
 
+int            env_changed_id = 0;
+
 void ArpRequest (void)
 {
        int i;
@@ -276,6 +278,78 @@ void ArpTimeoutCheck(void)
        }
 }
 
+int
+NetInitLoop(proto_t protocol)
+{
+       bd_t *bd = gd->bd;
+       int env_id = get_env_id ();
+
+       /* update only when the environment has changed */
+       if (env_changed_id == env_id)
+               return 0;
+
+       switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+       case NFS:
+#endif
+#if defined(CONFIG_CMD_PING)
+       case PING:
+#endif
+#if defined(CONFIG_CMD_SNTP)
+       case SNTP:
+#endif
+       case NETCONS:
+       case TFTP:
+               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+               NetOurGatewayIP = getenv_IPaddr ("gatewayip");
+               NetOurSubnetMask= getenv_IPaddr ("netmask");
+               NetOurVLAN = getenv_VLAN("vlan");
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+
+               switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+               case NFS:
+#endif
+               case NETCONS:
+               case TFTP:
+                       NetServerIP = getenv_IPaddr ("serverip");
+                       break;
+#if defined(CONFIG_CMD_PING)
+               case PING:
+                       /* nothing */
+                       break;
+#endif
+#if defined(CONFIG_CMD_SNTP)
+               case SNTP:
+                       /* nothing */
+                       break;
+#endif
+               default:
+                       break;
+               }
+
+               break;
+       case BOOTP:
+       case RARP:
+               /*
+                * initialize our IP addr to 0 in order to accept ANY
+                * IP addr assigned to us by the BOOTP / RARP server
+                */
+               NetOurIP = 0;
+               NetServerIP = getenv_IPaddr ("serverip");
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+       case CDP:
+               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
+               NetOurNativeVLAN = getenv_VLAN("nvlan");
+               break;
+       default:
+               break;
+       }
+       env_changed_id = env_id;
+       return 0;
+}
+
 /**********************************************************************/
 /*
  *     Main network processing loop.
@@ -340,65 +414,7 @@ restart:
         *      here on, this code is a state machine driven by received
         *      packets and timer events.
         */
-
-       switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-       case NFS:
-#endif
-#if defined(CONFIG_CMD_PING)
-       case PING:
-#endif
-#if defined(CONFIG_CMD_SNTP)
-       case SNTP:
-#endif
-       case NETCONS:
-       case TFTP:
-               NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
-               NetOurGatewayIP = getenv_IPaddr ("gatewayip");
-               NetOurSubnetMask= getenv_IPaddr ("netmask");
-               NetOurVLAN = getenv_VLAN("vlan");
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
-
-               switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-               case NFS:
-#endif
-               case NETCONS:
-               case TFTP:
-                       NetServerIP = getenv_IPaddr ("serverip");
-                       break;
-#if defined(CONFIG_CMD_PING)
-               case PING:
-                       /* nothing */
-                       break;
-#endif
-#if defined(CONFIG_CMD_SNTP)
-               case SNTP:
-                       /* nothing */
-                       break;
-#endif
-               default:
-                       break;
-               }
-
-               break;
-       case BOOTP:
-       case RARP:
-               /*
-                * initialize our IP addr to 0 in order to accept ANY
-                * IP addr assigned to us by the BOOTP / RARP server
-                */
-               NetOurIP = 0;
-               NetServerIP = getenv_IPaddr ("serverip");
-               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
-       case CDP:
-               NetOurVLAN = getenv_VLAN("vlan");       /* VLANs must be read */
-               NetOurNativeVLAN = getenv_VLAN("nvlan");
-               break;
-       default:
-               break;
-       }
+       NetInitLoop(protocol);
 
        switch (net_check_prereq (protocol)) {
        case 1: