Merge https://gitlab.denx.de/u-boot/custodians/u-boot-sh
authorTom Rini <trini@konsulko.com>
Mon, 27 Jul 2020 13:41:18 +0000 (09:41 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 27 Jul 2020 13:41:18 +0000 (09:41 -0400)
- R8A774A1 / Beacon EmbeddedWorks RZG2M Dev Kit support

39 files changed:
README
cmd/Kconfig
cmd/nvedit.c
configs/integratorap_cm720t_defconfig
configs/integratorap_cm920t_defconfig
configs/integratorap_cm926ejs_defconfig
configs/integratorap_cm946es_defconfig
configs/sandbox64_defconfig
configs/sandbox_defconfig
configs/sandbox_flattree_defconfig
configs/sandbox_spl_defconfig
drivers/net/Kconfig
drivers/net/dc2114x.c
env/Kconfig
env/env.c
env/fat.c
env/mmc.c
include/configs/MPC8349EMDS.h
include/configs/MPC8349EMDS_SDRAM.h
include/configs/MPC8540ADS.h
include/configs/MPC8541CDS.h
include/configs/MPC8544DS.h
include/configs/MPC8548CDS.h
include/configs/MPC8555CDS.h
include/configs/MPC8560ADS.h
include/configs/MPC8568MDS.h
include/configs/MPC8569MDS.h
include/configs/MPC8572DS.h
include/configs/MPC8641HPCN.h
include/configs/TQM834x.h
include/configs/caddy2.h
include/configs/integratorap.h
include/configs/sbc8349.h
include/configs/sbc8548.h
include/configs/sbc8641d.h
include/configs/vme8349.h
include/env_internal.h
scripts/config_whitelist.txt
test/py/tests/test_env.py

diff --git a/README b/README
index 2384966..7ab7e37 100644 (file)
--- a/README
+++ b/README
@@ -871,9 +871,6 @@ The following options need to be configured:
                Allow generic access to the SPI bus on the Intel 8257x, for
                example with the "sspi" command.
 
-               CONFIG_TULIP
-               Support for Digital 2114x chips.
-
                CONFIG_NATSEMI
                Support for National dp83815 chips.
 
index bfe6c16..e2b0a4f 100644 (file)
@@ -601,6 +601,7 @@ config CMD_NVEDIT_INFO
          This command can be optionally used for evaluation in scripts:
          [-d] : evaluate whether default environment is used
          [-p] : evaluate whether environment can be persisted
+         [-q] : quiet output
          The result of multiple evaluations will be combined with AND.
 
 endmenu
index ca0be92..acd9f82 100644 (file)
@@ -1224,12 +1224,18 @@ static int print_env_info(void)
  * env info - display environment information
  * env info [-d] - evaluate whether default environment is used
  * env info [-p] - evaluate whether environment can be persisted
+ *      Add [-q] - quiet mode, use only for command result, for test by example:
+ *                 test env info -p -d -q
  */
 static int do_env_info(struct cmd_tbl *cmdtp, int flag,
                       int argc, char *const argv[])
 {
        int eval_flags = 0;
        int eval_results = 0;
+       bool quiet = false;
+#if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
+       enum env_location loc;
+#endif
 
        /* display environment information */
        if (argc <= 1)
@@ -1247,6 +1253,9 @@ static int do_env_info(struct cmd_tbl *cmdtp, int flag,
                        case 'p':
                                eval_flags |= ENV_INFO_IS_PERSISTED;
                                break;
+                       case 'q':
+                               quiet = true;
+                               break;
                        default:
                                return CMD_RET_USAGE;
                        }
@@ -1256,20 +1265,30 @@ static int do_env_info(struct cmd_tbl *cmdtp, int flag,
        /* evaluate whether default environment is used */
        if (eval_flags & ENV_INFO_IS_DEFAULT) {
                if (gd->flags & GD_FLG_ENV_DEFAULT) {
-                       printf("Default environment is used\n");
+                       if (!quiet)
+                               printf("Default environment is used\n");
                        eval_results |= ENV_INFO_IS_DEFAULT;
                } else {
-                       printf("Environment was loaded from persistent storage\n");
+                       if (!quiet)
+                               printf("Environment was loaded from persistent storage\n");
                }
        }
 
        /* evaluate whether environment can be persisted */
        if (eval_flags & ENV_INFO_IS_PERSISTED) {
 #if defined(CONFIG_CMD_SAVEENV) && defined(ENV_IS_IN_DEVICE)
-               printf("Environment can be persisted\n");
-               eval_results |= ENV_INFO_IS_PERSISTED;
+               loc = env_get_location(ENVOP_SAVE, gd->env_load_prio);
+               if (ENVL_NOWHERE != loc && ENVL_UNKNOWN != loc) {
+                       if (!quiet)
+                               printf("Environment can be persisted\n");
+                       eval_results |= ENV_INFO_IS_PERSISTED;
+               } else {
+                       if (!quiet)
+                               printf("Environment cannot be persisted\n");
+               }
 #else
-               printf("Environment cannot be persisted\n");
+               if (!quiet)
+                       printf("Environment cannot be persisted\n");
 #endif
        }
 
@@ -1326,7 +1345,7 @@ static struct cmd_tbl cmd_env_sub[] = {
        U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
 #endif
 #if defined(CONFIG_CMD_NVEDIT_INFO)
-       U_BOOT_CMD_MKENT(info, 2, 0, do_env_info, "", ""),
+       U_BOOT_CMD_MKENT(info, 3, 0, do_env_info, "", ""),
 #endif
        U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
 #if defined(CONFIG_CMD_RUN)
@@ -1405,8 +1424,10 @@ static char env_help_text[] =
 #endif
 #if defined(CONFIG_CMD_NVEDIT_INFO)
        "env info - display environment information\n"
-       "env info [-d] - whether default environment is used\n"
-       "env info [-p] - whether environment can be persisted\n"
+       "env info [-d] [-p] [-q] - evaluate environment information\n"
+       "      \"-d\": default environment is used\n"
+       "      \"-p\": environment can be persisted\n"
+       "      \"-q\": quiet output\n"
 #endif
        "env print [-a | name ...] - print environment\n"
 #if defined(CONFIG_CMD_NVEDIT_EFI)
index 1b7d672..0d9746b 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_EEPRO100=y
+CONFIG_TULIP=y
 CONFIG_PCI=y
 CONFIG_BAUDRATE=38400
 CONFIG_OF_LIBFDT=y
index 116ac01..7d71648 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_EEPRO100=y
+CONFIG_TULIP=y
 CONFIG_PCI=y
 CONFIG_BAUDRATE=38400
 CONFIG_OF_LIBFDT=y
index 9c1a3fa..921a75e 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_EEPRO100=y
+CONFIG_TULIP=y
 CONFIG_PCI=y
 CONFIG_BAUDRATE=38400
 CONFIG_OF_LIBFDT=y
index ee9c69b..4032da9 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_FLASH_CFI_DRIVER=y
 CONFIG_SYS_FLASH_PROTECTION=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_EEPRO100=y
+CONFIG_TULIP=y
 CONFIG_PCI=y
 CONFIG_BAUDRATE=38400
 CONFIG_OF_LIBFDT=y
index dcf2f44..45edd3b 100644 (file)
@@ -30,6 +30,7 @@ CONFIG_CMD_GREPENV=y
 CONFIG_CMD_ENV_CALLBACK=y
 CONFIG_CMD_ENV_FLAGS=y
 CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_NVEDIT_INFO=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MD5SUM=y
 CONFIG_CMD_MEMINFO=y
index 6059d66..9f3ac90 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_CMD_GREPENV=y
 CONFIG_CMD_ENV_CALLBACK=y
 CONFIG_CMD_ENV_FLAGS=y
 CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_NVEDIT_INFO=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MD5SUM=y
 CONFIG_CMD_MEMINFO=y
index 4158b9b..efdacef 100644 (file)
@@ -24,6 +24,7 @@ CONFIG_CMD_BOOTEFI_HELLO=y
 # CONFIG_CMD_ELF is not set
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
+CONFIG_CMD_NVEDIT_INFO=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MD5SUM=y
 CONFIG_CMD_MEMINFO=y
index b3274a9..c2f8732 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_ENV_CALLBACK=y
 CONFIG_CMD_ENV_FLAGS=y
+CONFIG_CMD_NVEDIT_INFO=y
 CONFIG_LOOPW=y
 CONFIG_CMD_MD5SUM=y
 CONFIG_CMD_MEMINFO=y
index ec3fb49..15030b8 100644 (file)
@@ -491,6 +491,12 @@ config SH_ETHER
 
 source "drivers/net/ti/Kconfig"
 
+config TULIP
+       bool "DEC Tulip DC2114x Ethernet support"
+       depends on (DM_ETH && DM_PCI) || !DM_ETH
+       help
+         This driver supports DEC DC2114x Fast ethernet chips.
+
 config XILINX_AXIEMAC
        depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
        select PHYLIB
index 0cb54e3..9f8c6c5 100644 (file)
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 
 #include <common.h>
-#include <env.h>
+#include <asm/io.h>
+#include <dm.h>
 #include <malloc.h>
 #include <net.h>
 #include <netdev.h>
@@ -11,8 +12,6 @@
 
 #define SROM_DLEVEL    0
 
-#undef UPDATE_SROM
-
 /* PCI Registers. */
 #define PCI_CFDA_PSM   0x43
 
 
 #define POLL_DEMAND    1
 
-#if defined(CONFIG_E500)
-#define phys_to_bus(a) (a)
+#if defined(CONFIG_DM_ETH)
+#define phys_to_bus(dev, a)    dm_pci_phys_to_mem((dev), (a))
+#elif defined(CONFIG_E500)
+#define phys_to_bus(dev, a)    (a)
 #else
-#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#define phys_to_bus(dev, a)    pci_phys_to_mem((dev), (a))
 #endif
 
 #define NUM_RX_DESC PKTBUFSRX
@@ -95,87 +96,97 @@ struct de4x5_desc {
        u32 next;
 };
 
-/* RX and TX descriptor ring */
-static struct de4x5_desc rx_ring[NUM_RX_DESC] __aligned(32);
-static struct de4x5_desc tx_ring[NUM_TX_DESC] __aligned(32);
-static int rx_new;     /* RX descriptor ring pointer */
-static int tx_new;     /* TX descriptor ring pointer */
-
-static char rx_ring_size;
-static char tx_ring_size;
+struct dc2114x_priv {
+       struct de4x5_desc rx_ring[NUM_RX_DESC] __aligned(32);
+       struct de4x5_desc tx_ring[NUM_TX_DESC] __aligned(32);
+       int rx_new;     /* RX descriptor ring pointer */
+       int tx_new;     /* TX descriptor ring pointer */
+       char rx_ring_size;
+       char tx_ring_size;
+#ifdef CONFIG_DM_ETH
+       struct udevice          *devno;
+#else
+       struct eth_device       dev;
+       pci_dev_t               devno;
+#endif
+       char                    *name;
+       void __iomem            *iobase;
+       u8                      *enetaddr;
+};
 
-static u32 dc2114x_inl(struct eth_device *dev, u32 addr)
+/* RX and TX descriptor ring */
+static u32 dc2114x_inl(struct dc2114x_priv *priv, u32 addr)
 {
-       return le32_to_cpu(*(volatile u32 *)(addr + dev->iobase));
+       return le32_to_cpu(readl(priv->iobase + addr));
 }
 
-static void dc2114x_outl(struct eth_device *dev, u32 command, u32 addr)
+static void dc2114x_outl(struct dc2114x_priv *priv, u32 command, u32 addr)
 {
-       *(volatile u32 *)(addr + dev->iobase) = cpu_to_le32(command);
+       writel(cpu_to_le32(command), priv->iobase + addr);
 }
 
-static void reset_de4x5(struct eth_device *dev)
+static void reset_de4x5(struct dc2114x_priv *priv)
 {
        u32 i;
 
-       i = dc2114x_inl(dev, DE4X5_BMR);
+       i = dc2114x_inl(priv, DE4X5_BMR);
        mdelay(1);
-       dc2114x_outl(dev, i | BMR_SWR, DE4X5_BMR);
+       dc2114x_outl(priv, i | BMR_SWR, DE4X5_BMR);
        mdelay(1);
-       dc2114x_outl(dev, i, DE4X5_BMR);
+       dc2114x_outl(priv, i, DE4X5_BMR);
        mdelay(1);
 
        for (i = 0; i < 5; i++) {
-               dc2114x_inl(dev, DE4X5_BMR);
+               dc2114x_inl(priv, DE4X5_BMR);
                mdelay(10);
        }
 
        mdelay(1);
 }
 
-static void start_de4x5(struct eth_device *dev)
+static void start_de4x5(struct dc2114x_priv *priv)
 {
        u32 omr;
 
-       omr = dc2114x_inl(dev, DE4X5_OMR);
+       omr = dc2114x_inl(priv, DE4X5_OMR);
        omr |= OMR_ST | OMR_SR;
-       dc2114x_outl(dev, omr, DE4X5_OMR);      /* Enable the TX and/or RX */
+       dc2114x_outl(priv, omr, DE4X5_OMR);     /* Enable the TX and/or RX */
 }
 
-static void stop_de4x5(struct eth_device *dev)
+static void stop_de4x5(struct dc2114x_priv *priv)
 {
        u32 omr;
 
-       omr = dc2114x_inl(dev, DE4X5_OMR);
+       omr = dc2114x_inl(priv, DE4X5_OMR);
        omr &= ~(OMR_ST | OMR_SR);
-       dc2114x_outl(dev, omr, DE4X5_OMR);      /* Disable the TX and/or RX */
+       dc2114x_outl(priv, omr, DE4X5_OMR);     /* Disable the TX and/or RX */
 }
 
 /* SROM Read and write routines. */
-static void sendto_srom(struct eth_device *dev, u_int command, u_long addr)
+static void sendto_srom(struct dc2114x_priv *priv, u_int command, u_long addr)
 {
-       dc2114x_outl(dev, command, addr);
+       dc2114x_outl(priv, command, addr);
        udelay(1);
 }
 
-static int getfrom_srom(struct eth_device *dev, u_long addr)
+static int getfrom_srom(struct dc2114x_priv *priv, u_long addr)
 {
-       u32 tmp = dc2114x_inl(dev, addr);
+       u32 tmp = dc2114x_inl(priv, addr);
 
        udelay(1);
        return tmp;
 }
 
 /* Note: this routine returns extra data bits for size detection. */
-static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location,
+static int do_read_eeprom(struct dc2114x_priv *priv, u_long ioaddr, int location,
                          int addr_len)
 {
        int read_cmd = location | (SROM_READ_CMD << addr_len);
        unsigned int retval = 0;
        int i;
 
-       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr);
 
        debug_cond(SROM_DLEVEL >= 1, " EEPROM read at %d ", location);
 
@@ -183,35 +194,35 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location,
        for (i = 4 + addr_len; i >= 0; i--) {
                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
 
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval,
+               sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | dataval,
                            ioaddr);
                udelay(10);
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK,
+               sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK,
                            ioaddr);
                udelay(10);
                debug_cond(SROM_DLEVEL >= 2, "%X",
-                          getfrom_srom(dev, ioaddr) & 15);
+                          getfrom_srom(priv, ioaddr) & 15);
                retval = (retval << 1) |
-                        !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ);
+                        !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ);
        }
 
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr);
 
-       debug_cond(SROM_DLEVEL >= 2, " :%X:", getfrom_srom(dev, ioaddr) & 15);
+       debug_cond(SROM_DLEVEL >= 2, " :%X:", getfrom_srom(priv, ioaddr) & 15);
 
        for (i = 16; i > 0; i--) {
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+               sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
                udelay(10);
                debug_cond(SROM_DLEVEL >= 2, "%X",
-                          getfrom_srom(dev, ioaddr) & 15);
+                          getfrom_srom(priv, ioaddr) & 15);
                retval = (retval << 1) |
-                        !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ);
-               sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+                        !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ);
+               sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr);
                udelay(10);
        }
 
        /* Terminate the EEPROM access. */
-       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR, ioaddr);
 
        debug_cond(SROM_DLEVEL >= 2, " EEPROM value at %d is %5.5x.\n",
                   location, retval);
@@ -224,139 +235,53 @@ static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location,
  * enable. It returns the data output from the EEPROM, and thus may
  * also be used for reads.
  */
-static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd,
+static int do_eeprom_cmd(struct dc2114x_priv *priv, u_long ioaddr, int cmd,
                         int cmd_len)
 {
        unsigned int retval = 0;
 
        debug_cond(SROM_DLEVEL >= 1, " EEPROM op 0x%x: ", cmd);
 
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
 
        /* Shift the command bits out. */
        do {
                short dataval = (cmd & BIT(cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
 
-               sendto_srom(dev, dataval, ioaddr);
+               sendto_srom(priv, dataval, ioaddr);
                udelay(10);
 
                debug_cond(SROM_DLEVEL >= 2, "%X",
-                          getfrom_srom(dev, ioaddr) & 15);
+                          getfrom_srom(priv, ioaddr) & 15);
 
-               sendto_srom(dev, dataval | DT_CLK, ioaddr);
+               sendto_srom(priv, dataval | DT_CLK, ioaddr);
                udelay(10);
                retval = (retval << 1) |
-                        !!(getfrom_srom(dev, ioaddr) & EE_DATA_READ);
+                        !!(getfrom_srom(priv, ioaddr) & EE_DATA_READ);
        } while (--cmd_len >= 0);
 
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR | DT_CS, ioaddr);
 
        /* Terminate the EEPROM access. */
-       sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+       sendto_srom(priv, SROM_RD | SROM_SR, ioaddr);
 
        debug_cond(SROM_DLEVEL >= 1, " EEPROM result is 0x%5.5x.\n", retval);
 
        return retval;
 }
 
-static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
+static int read_srom(struct dc2114x_priv *priv, u_long ioaddr, int index)
 {
        int ee_addr_size;
 
-       ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6;
+       ee_addr_size = (do_read_eeprom(priv, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6;
 
-       return do_eeprom_cmd(dev, ioaddr, 0xffff |
+       return do_eeprom_cmd(priv, ioaddr, 0xffff |
                             (((SROM_READ_CMD << ee_addr_size) | index) << 16),
                             3 + ee_addr_size + 16);
 }
 
-#ifdef UPDATE_SROM
-static int write_srom(struct eth_device *dev, u_long ioaddr, int index,
-                     int new_value)
-{
-       unsigned short newval;
-       int ee_addr_size;
-       int i;
-
-       ee_addr_size = (do_read_eeprom(dev, ioaddr, 0xff, 8) & BIT(18)) ? 8 : 6;
-
-       udelay(10 * 1000); /* test-only */
-
-       debug_cond(SROM_DLEVEL >= 1, "ee_addr_size=%d.\n", ee_addr_size);
-       debug_cond(SROM_DLEVEL >= 1,
-                  "Writing new entry 0x%4.4x to offset %d.\n",
-                  new_value, index);
-
-       /* Enable programming modes. */
-       do_eeprom_cmd(dev, ioaddr, 0x4f << (ee_addr_size - 4),
-                     3 + ee_addr_size);
-
-       /* Do the actual write. */
-       do_eeprom_cmd(dev, ioaddr, new_value |
-                     (((SROM_WRITE_CMD << ee_addr_size) | index) << 16),
-                     3 + ee_addr_size + 16);
-
-       /* Poll for write finished. */
-       sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
-       for (i = 0; i < 10000; i++) {   /* Typical 2000 ticks */
-               if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
-                       break;
-       }
-
-       debug_cond(SROM_DLEVEL >= 1, " Write finished after %d ticks.\n", i);
-
-       /* Disable programming. */
-       do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size - 4)),
-                     3 + ee_addr_size);
-
-       /* And read the result. */
-       newval = do_eeprom_cmd(dev, ioaddr,
-                              (((SROM_READ_CMD << ee_addr_size) | index) << 16)
-                              | 0xffff, 3 + ee_addr_size + 16);
-
-       debug_cond(SROM_DLEVEL >= 1, "  New value at offset %d is %4.4x.\n",
-                  index, newval);
-
-       return 1;
-}
-
-static void update_srom(struct eth_device *dev, struct bd_info *bis)
-{
-       static unsigned short eeprom[0x40] = {
-               0x140b, 0x6610, 0x0000, 0x0000, /* 00 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 04 */
-               0x00a3, 0x0103, 0x0000, 0x0000, /* 08 */
-               0x0000, 0x1f00, 0x0000, 0x0000, /* 0c */
-               0x0108, 0x038d, 0x0000, 0x0000, /* 10 */
-               0xe078, 0x0001, 0x0040, 0x0018, /* 14 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 18 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 1c */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 20 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 2c */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 30 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 34 */
-               0x0000, 0x0000, 0x0000, 0x0000, /* 38 */
-               0x0000, 0x0000, 0x0000, 0x4e07, /* 3c */
-       };
-       uchar enetaddr[6];
-       int i;
-
-       /* Ethernet Addr... */
-       if (!eth_env_get_enetaddr("ethaddr", enetaddr))
-               return;
-
-       eeprom[0x0a] = (enetaddr[1] << 8) | enetaddr[0];
-       eeprom[0x0b] = (enetaddr[3] << 8) | enetaddr[2];
-       eeprom[0x0c] = (enetaddr[5] << 8) | enetaddr[4];
-
-       for (i = 0; i < 0x40; i++)
-               write_srom(dev, DE4X5_APROM, i, eeprom[i]);
-}
-#endif /* UPDATE_SROM */
-
-static void send_setup_frame(struct eth_device *dev, struct bd_info *bis)
+static void send_setup_frame(struct dc2114x_priv *priv)
 {
        char setup_frame[SETUP_FRAME_LEN];
        char *pa = &setup_frame[0];
@@ -365,223 +290,267 @@ static void send_setup_frame(struct eth_device *dev, struct bd_info *bis)
        memset(pa, 0xff, SETUP_FRAME_LEN);
 
        for (i = 0; i < ETH_ALEN; i++) {
-               *(pa + (i & 1)) = dev->enetaddr[i];
+               *(pa + (i & 1)) = priv->enetaddr[i];
                if (i & 0x01)
                        pa += 4;
        }
 
-       for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+       for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) {
                if (i < TOUT_LOOP)
                        continue;
 
-               printf("%s: tx error buffer not ready\n", dev->name);
+               printf("%s: tx error buffer not ready\n", priv->name);
                return;
        }
 
-       tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32)&setup_frame[0]));
-       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN);
-       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+       priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno,
+                                                     (u32)&setup_frame[0]));
+       priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_SET | SETUP_FRAME_LEN);
+       priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN);
 
-       dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD);
+       dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD);
 
-       for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+       for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) {
                if (i < TOUT_LOOP)
                        continue;
 
-               printf("%s: tx buffer not ready\n", dev->name);
+               printf("%s: tx buffer not ready\n", priv->name);
                return;
        }
 
-       if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+       if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) != 0x7FFFFFFF) {
                printf("TX error status2 = 0x%08X\n",
-                      le32_to_cpu(tx_ring[tx_new].status));
+                      le32_to_cpu(priv->tx_ring[priv->tx_new].status));
        }
 
-       tx_new = (tx_new + 1) % NUM_TX_DESC;
+       priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC;
 }
 
-static int dc21x4x_send(struct eth_device *dev, void *packet, int length)
+static int dc21x4x_send_common(struct dc2114x_priv *priv, void *packet, int length)
 {
        int status = -1;
        int i;
 
        if (length <= 0) {
-               printf("%s: bad packet size: %d\n", dev->name, length);
+               printf("%s: bad packet size: %d\n", priv->name, length);
                goto done;
        }
 
-       for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+       for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) {
                if (i < TOUT_LOOP)
                        continue;
 
-               printf("%s: tx error buffer not ready\n", dev->name);
+               printf("%s: tx error buffer not ready\n", priv->name);
                goto done;
        }
 
-       tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32)packet));
-       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
-       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+       priv->tx_ring[priv->tx_new].buf = cpu_to_le32(phys_to_bus(priv->devno,
+                                                     (u32)packet));
+       priv->tx_ring[priv->tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+       priv->tx_ring[priv->tx_new].status = cpu_to_le32(T_OWN);
 
-       dc2114x_outl(dev, POLL_DEMAND, DE4X5_TPD);
+       dc2114x_outl(priv, POLL_DEMAND, DE4X5_TPD);
 
-       for (i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+       for (i = 0; priv->tx_ring[priv->tx_new].status & cpu_to_le32(T_OWN); i++) {
                if (i < TOUT_LOOP)
                        continue;
 
-               printf(".%s: tx buffer not ready\n", dev->name);
+               printf(".%s: tx buffer not ready\n", priv->name);
                goto done;
        }
 
-       if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
-               tx_ring[tx_new].status = 0x0;
+       if (le32_to_cpu(priv->tx_ring[priv->tx_new].status) & TD_ES) {
+               priv->tx_ring[priv->tx_new].status = 0x0;
                goto done;
        }
 
        status = length;
 
 done:
-       tx_new = (tx_new + 1) % NUM_TX_DESC;
+       priv->tx_new = (priv->tx_new + 1) % NUM_TX_DESC;
        return status;
 }
 
-static int dc21x4x_recv(struct eth_device *dev)
+static int dc21x4x_recv_check(struct dc2114x_priv *priv)
 {
        int length = 0;
        u32 status;
 
-       while (true) {
-               status = le32_to_cpu(rx_ring[rx_new].status);
+       status = le32_to_cpu(priv->rx_ring[priv->rx_new].status);
 
-               if (status & R_OWN)
-                       break;
+       if (status & R_OWN)
+               return 0;
 
-               if (status & RD_LS) {
-                       /* Valid frame status. */
-                       if (status & RD_ES) {
-                               /* There was an error. */
-                               printf("RX error status = 0x%08X\n", status);
-                       } else {
-                               /* A valid frame received. */
-                               length = (le32_to_cpu(rx_ring[rx_new].status)
-                                         >> 16);
-
-                               /* Pass the packet up to the protocol layers */
-                               net_process_received_packet
-                                       (net_rx_packets[rx_new], length - 4);
-                       }
-
-                       /*
-                        * Change buffer ownership for this frame,
-                        * back to the adapter.
-                        */
-                       rx_ring[rx_new].status = cpu_to_le32(R_OWN);
-               }
+       if (status & RD_LS) {
+               /* Valid frame status. */
+               if (status & RD_ES) {
+                       /* There was an error. */
+                       printf("RX error status = 0x%08X\n", status);
+                       return -EINVAL;
+               } else {
+                       /* A valid frame received. */
+                       length = (le32_to_cpu(priv->rx_ring[priv->rx_new].status)
+                                 >> 16);
 
-               /* Update entry information. */
-               rx_new = (rx_new + 1) % rx_ring_size;
+                       return length;
+               }
        }
 
-       return length;
+       return -EAGAIN;
 }
 
-static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis)
+static int dc21x4x_init_common(struct dc2114x_priv *priv)
 {
        int i;
-       int devbusfn = (int)dev->priv;
-
-       /* Ensure we're not sleeping. */
-       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
 
-       reset_de4x5(dev);
+       reset_de4x5(priv);
 
-       if (dc2114x_inl(dev, DE4X5_STS) & (STS_TS | STS_RS)) {
+       if (dc2114x_inl(priv, DE4X5_STS) & (STS_TS | STS_RS)) {
                printf("Error: Cannot reset ethernet controller.\n");
                return -1;
        }
 
-       dc2114x_outl(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+       dc2114x_outl(priv, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
 
        for (i = 0; i < NUM_RX_DESC; i++) {
-               rx_ring[i].status = cpu_to_le32(R_OWN);
-               rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
-               rx_ring[i].buf =
-                       cpu_to_le32(phys_to_bus((u32)net_rx_packets[i]));
-               rx_ring[i].next = 0;
+               priv->rx_ring[i].status = cpu_to_le32(R_OWN);
+               priv->rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+               priv->rx_ring[i].buf = cpu_to_le32(phys_to_bus(priv->devno,
+                                            (u32)net_rx_packets[i]));
+               priv->rx_ring[i].next = 0;
        }
 
        for (i = 0; i < NUM_TX_DESC; i++) {
-               tx_ring[i].status = 0;
-               tx_ring[i].des1 = 0;
-               tx_ring[i].buf = 0;
-               tx_ring[i].next = 0;
+               priv->tx_ring[i].status = 0;
+               priv->tx_ring[i].des1 = 0;
+               priv->tx_ring[i].buf = 0;
+               priv->tx_ring[i].next = 0;
        }
 
-       rx_ring_size = NUM_RX_DESC;
-       tx_ring_size = NUM_TX_DESC;
+       priv->rx_ring_size = NUM_RX_DESC;
+       priv->tx_ring_size = NUM_TX_DESC;
 
        /* Write the end of list marker to the descriptor lists. */
-       rx_ring[rx_ring_size - 1].des1 |= cpu_to_le32(RD_RER);
-       tx_ring[tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER);
+       priv->rx_ring[priv->rx_ring_size - 1].des1 |= cpu_to_le32(RD_RER);
+       priv->tx_ring[priv->tx_ring_size - 1].des1 |= cpu_to_le32(TD_TER);
 
        /* Tell the adapter where the TX/RX rings are located. */
-       dc2114x_outl(dev, phys_to_bus((u32)&rx_ring), DE4X5_RRBA);
-       dc2114x_outl(dev, phys_to_bus((u32)&tx_ring), DE4X5_TRBA);
+       dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&priv->rx_ring),
+                    DE4X5_RRBA);
+       dc2114x_outl(priv, phys_to_bus(priv->devno, (u32)&priv->tx_ring),
+                    DE4X5_TRBA);
 
-       start_de4x5(dev);
+       start_de4x5(priv);
 
-       tx_new = 0;
-       rx_new = 0;
+       priv->tx_new = 0;
+       priv->rx_new = 0;
 
-       send_setup_frame(dev, bis);
+       send_setup_frame(priv);
 
        return 0;
 }
 
-static void dc21x4x_halt(struct eth_device *dev)
+static void dc21x4x_halt_common(struct dc2114x_priv *priv)
 {
-       int devbusfn = (int)dev->priv;
-
-       stop_de4x5(dev);
-       dc2114x_outl(dev, 0, DE4X5_SICR);
-
-       pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
+       stop_de4x5(priv);
+       dc2114x_outl(priv, 0, DE4X5_SICR);
 }
 
-static void read_hw_addr(struct eth_device *dev, struct bd_info *bis)
+static void read_hw_addr(struct dc2114x_priv *priv)
 {
-       u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
+       u_short tmp, *p = (u_short *)(&priv->enetaddr[0]);
        int i, j = 0;
 
        for (i = 0; i < (ETH_ALEN >> 1); i++) {
-               tmp = read_srom(dev, DE4X5_APROM, (SROM_HWADD >> 1) + i);
+               tmp = read_srom(priv, DE4X5_APROM, (SROM_HWADD >> 1) + i);
                *p = le16_to_cpu(tmp);
                j += *p++;
        }
 
        if (!j || j == 0x2fffd) {
-               memset(dev->enetaddr, 0, ETH_ALEN);
+               memset(priv->enetaddr, 0, ETH_ALEN);
                debug("Warning: can't read HW address from SROM.\n");
-#ifdef UPDATE_SROM
-               update_srom(dev, bis);
-#endif
        }
 }
 
 static struct pci_device_id supported[] = {
-       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
-       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+       { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142) },
        { }
 };
 
+#ifndef CONFIG_DM_ETH
+static int dc21x4x_init(struct eth_device *dev, struct bd_info *bis)
+{
+       struct dc2114x_priv *priv =
+               container_of(dev, struct dc2114x_priv, dev);
+
+       /* Ensure we're not sleeping. */
+       pci_write_config_byte(priv->devno, PCI_CFDA_PSM, WAKEUP);
+
+       return dc21x4x_init_common(priv);
+}
+
+static void dc21x4x_halt(struct eth_device *dev)
+{
+       struct dc2114x_priv *priv =
+               container_of(dev, struct dc2114x_priv, dev);
+
+       dc21x4x_halt_common(priv);
+
+       pci_write_config_byte(priv->devno, PCI_CFDA_PSM, SLEEP);
+}
+
+static int dc21x4x_send(struct eth_device *dev, void *packet, int length)
+{
+       struct dc2114x_priv *priv =
+               container_of(dev, struct dc2114x_priv, dev);
+
+       return dc21x4x_send_common(priv, packet, length);
+}
+
+static int dc21x4x_recv(struct eth_device *dev)
+{
+       struct dc2114x_priv *priv =
+               container_of(dev, struct dc2114x_priv, dev);
+       int length = 0;
+       int ret;
+
+       while (true) {
+               ret = dc21x4x_recv_check(priv);
+               if (!ret)
+                       break;
+
+               if (ret > 0) {
+                       length = ret;
+                       /* Pass the packet up to the protocol layers */
+                       net_process_received_packet
+                               (net_rx_packets[priv->rx_new], length - 4);
+               }
+
+               /*
+                * Change buffer ownership for this frame,
+                * back to the adapter.
+                */
+               if (ret != -EAGAIN)
+                       priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN);
+
+               /* Update entry information. */
+               priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size;
+       }
+
+       return length;
+}
+
 int dc21x4x_initialize(struct bd_info *bis)
 {
+       struct dc2114x_priv *priv;
        struct eth_device *dev;
        unsigned short status;
        unsigned char timer;
        unsigned int iobase;
        int card_number = 0;
        pci_dev_t devbusfn;
-       unsigned int cfrv;
        int idx = 0;
 
        while (1) {
@@ -589,14 +558,6 @@ int dc21x4x_initialize(struct bd_info *bis)
                if (devbusfn == -1)
                        break;
 
-               /* Get the chip configuration revision register. */
-               pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
-
-               if ((cfrv & CFRV_RN) < DC2114x_BRK) {
-                       printf("Error: The chip is not DC21143.\n");
-                       continue;
-               }
-
                pci_read_config_word(devbusfn, PCI_COMMAND, &status);
                status |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
                pci_write_config_word(devbusfn, PCI_COMMAND, status);
@@ -625,15 +586,19 @@ int dc21x4x_initialize(struct bd_info *bis)
                iobase &= PCI_BASE_ADDRESS_MEM_MASK;
                debug("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
 
-               dev = (struct eth_device *)malloc(sizeof(*dev));
-               if (!dev) {
+               priv = memalign(32, sizeof(*priv));
+               if (!priv) {
                        printf("Can not allocalte memory of dc21x4x\n");
                        break;
                }
+               memset(priv, 0, sizeof(*priv));
 
-               memset(dev, 0, sizeof(*dev));
+               dev = &priv->dev;
 
                sprintf(dev->name, "dc21x4x#%d", card_number);
+               priv->devno = devbusfn;
+               priv->name = dev->name;
+               priv->enetaddr = dev->enetaddr;
 
                dev->iobase = pci_mem_to_phys(devbusfn, iobase);
                dev->priv = (void *)devbusfn;
@@ -647,7 +612,7 @@ int dc21x4x_initialize(struct bd_info *bis)
 
                udelay(10 * 1000);
 
-               read_hw_addr(dev, bis);
+               read_hw_addr(priv);
 
                eth_register(dev);
 
@@ -656,3 +621,139 @@ int dc21x4x_initialize(struct bd_info *bis)
 
        return card_number;
 }
+
+#else  /* DM_ETH */
+static int dc2114x_start(struct udevice *dev)
+{
+       struct eth_pdata *plat = dev_get_platdata(dev);
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+
+       memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr));
+
+       /* Ensure we're not sleeping. */
+       dm_pci_write_config8(dev, PCI_CFDA_PSM, WAKEUP);
+
+       return dc21x4x_init_common(priv);
+}
+
+static void dc2114x_stop(struct udevice *dev)
+{
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+
+       dc21x4x_halt_common(priv);
+
+       dm_pci_write_config8(dev, PCI_CFDA_PSM, SLEEP);
+}
+
+static int dc2114x_send(struct udevice *dev, void *packet, int length)
+{
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = dc21x4x_send_common(priv, packet, length);
+
+       return ret ? 0 : -ETIMEDOUT;
+}
+
+static int dc2114x_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = dc21x4x_recv_check(priv);
+
+       if (ret < 0) {
+               /* Update entry information. */
+               priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size;
+               ret = 0;
+       }
+
+       if (!ret)
+               return 0;
+
+       *packetp = net_rx_packets[priv->rx_new];
+
+       return ret - 4;
+}
+
+static int dc2114x_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+
+       priv->rx_ring[priv->rx_new].status = cpu_to_le32(R_OWN);
+
+       /* Update entry information. */
+       priv->rx_new = (priv->rx_new + 1) % priv->rx_ring_size;
+
+       return 0;
+}
+
+static int dc2114x_read_rom_hwaddr(struct udevice *dev)
+{
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+
+       read_hw_addr(priv);
+
+       return 0;
+}
+
+static int dc2114x_bind(struct udevice *dev)
+{
+       static int card_number;
+       char name[16];
+
+       sprintf(name, "dc2114x#%u", card_number++);
+
+       return device_set_name(dev, name);
+}
+
+static int dc2114x_probe(struct udevice *dev)
+{
+       struct eth_pdata *plat = dev_get_platdata(dev);
+       struct dc2114x_priv *priv = dev_get_priv(dev);
+       u16 command, status;
+       u32 iobase;
+
+       dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase);
+       iobase &= ~0xf;
+
+       debug("dc2114x: DEC 2114x PCI Device @0x%x\n", iobase);
+
+       priv->devno = dev;
+       priv->enetaddr = plat->enetaddr;
+       priv->iobase = (void __iomem *)dm_pci_mem_to_phys(dev, iobase);
+
+       command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+       dm_pci_write_config16(dev, PCI_COMMAND, command);
+       dm_pci_read_config16(dev, PCI_COMMAND, &status);
+       if ((status & command) != command) {
+               printf("dc2114x: Couldn't enable IO access or Bus Mastering\n");
+               return -EINVAL;
+       }
+
+       dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x60);
+
+       return 0;
+}
+
+static const struct eth_ops dc2114x_ops = {
+       .start          = dc2114x_start,
+       .send           = dc2114x_send,
+       .recv           = dc2114x_recv,
+       .stop           = dc2114x_stop,
+       .free_pkt       = dc2114x_free_pkt,
+       .read_rom_hwaddr = dc2114x_read_rom_hwaddr,
+};
+
+U_BOOT_DRIVER(eth_dc2114x) = {
+       .name   = "eth_dc2114x",
+       .id     = UCLASS_ETH,
+       .bind   = dc2114x_bind,
+       .probe  = dc2114x_probe,
+       .ops    = &dc2114x_ops,
+       .priv_auto_alloc_size = sizeof(struct dc2114x_priv),
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+U_BOOT_PCI_DEVICE(eth_dc2114x, supported);
+#endif
index 38e7fad..5784136 100644 (file)
@@ -434,6 +434,10 @@ config ENV_FAT_DEVICE_AND_PART
                           If none, first valid partition in device D. If no
                           partition table then means device D.
 
+         If ENV_FAT_INTERFACE is set to "mmc" then device 'D' can be omitted,
+         leaving the string starting with a colon, and the boot device will
+         be used.
+
 config ENV_FAT_FILE
        string "Name of the FAT file to use for the environment"
        depends on ENV_IS_IN_FAT
index dcc25c0..2e64346 100644 (file)
--- a/env/env.c
+++ b/env/env.c
@@ -103,7 +103,7 @@ static void env_set_inited(enum env_location location)
         * using the above enum value as the bit index. We need to
         * make sure that we're not overflowing it.
         */
-       BUILD_BUG_ON(ARRAY_SIZE(env_locations) > BITS_PER_LONG);
+       BUILD_BUG_ON(ENVL_COUNT > BITS_PER_LONG);
 
        gd->env_has_init |= BIT(location);
 }
@@ -240,13 +240,17 @@ int env_save(void)
        if (drv) {
                int ret;
 
-               if (!drv->save)
+               printf("Saving Environment to %s... ", drv->name);
+               if (!drv->save) {
+                       printf("not possible\n");
                        return -ENODEV;
+               }
 
-               if (!env_has_inited(drv->location))
+               if (!env_has_inited(drv->location)) {
+                       printf("not initialized\n");
                        return -ENODEV;
+               }
 
-               printf("Saving Environment to %s... ", drv->name);
                ret = drv->save();
                if (ret)
                        printf("Failed (%d)\n", ret);
index 35a1955..63aced9 100644 (file)
--- a/env/fat.c
+++ b/env/fat.c
 # define LOADENV
 #endif
 
+__weak int mmc_get_env_dev(void)
+{
+#ifdef CONFIG_SYS_MMC_ENV_DEV
+       return CONFIG_SYS_MMC_ENV_DEV;
+#else
+       return 0;
+#endif
+}
+
+static char *env_fat_device_and_part(void)
+{
+#ifdef CONFIG_MMC
+       static char *part_str;
+
+       if (!part_str) {
+               part_str = CONFIG_ENV_FAT_DEVICE_AND_PART;
+               if (!strcmp(CONFIG_ENV_FAT_INTERFACE, "mmc") && part_str[0] == ':') {
+                       part_str = "0" CONFIG_ENV_FAT_DEVICE_AND_PART;
+                       part_str[0] += mmc_get_env_dev();
+               }
+       }
+
+       return part_str;
+#else
+       return CONFIG_ENV_FAT_DEVICE_AND_PART;
+#endif
+}
+
 static int env_fat_save(void)
 {
        env_t __aligned(ARCH_DMA_MINALIGN) env_new;
@@ -43,7 +71,7 @@ static int env_fat_save(void)
                return err;
 
        part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
-                                       CONFIG_ENV_FAT_DEVICE_AND_PART,
+                                       env_fat_device_and_part(),
                                        &dev_desc, &info, 1);
        if (part < 0)
                return 1;
@@ -89,7 +117,7 @@ static int env_fat_load(void)
 #endif
 
        part = blk_get_device_part_str(CONFIG_ENV_FAT_INTERFACE,
-                                       CONFIG_ENV_FAT_DEVICE_AND_PART,
+                                       env_fat_device_and_part(),
                                        &dev_desc, &info, 1);
        if (part < 0)
                goto err_env_relocate;
index a8b661d..aca61b7 100644 (file)
--- a/env/mmc.c
+++ b/env/mmc.c
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if !defined(CONFIG_SYS_MMC_ENV_DEV)
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#endif
+
+__weak int mmc_get_env_dev(void)
+{
+       return CONFIG_SYS_MMC_ENV_DEV;
+}
+
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-static inline int mmc_offset_try_partition(const char *str, s64 *val)
+static inline int mmc_offset_try_partition(const char *str, int copy, s64 *val)
 {
        struct disk_partition info;
        struct blk_desc *desc;
        int len, i, ret;
+       char dev_str[4];
 
-       ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
+       snprintf(dev_str, sizeof(dev_str), "%d", mmc_get_env_dev());
+       ret = blk_get_device_by_str("mmc", dev_str, &desc);
        if (ret < 0)
                return (ret);
 
@@ -45,10 +56,10 @@ static inline int mmc_offset_try_partition(const char *str, s64 *val)
        }
 
        /* round up to info.blksz */
-       len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
+       len = DIV_ROUND_UP(CONFIG_ENV_SIZE, info.blksz);
 
        /* use the top of the partion for the environment */
-       *val = (info.start + info.size - 1) - len / info.blksz;
+       *val = (info.start + info.size - (1 + copy) * len) * info.blksz;
 
        return 0;
 }
@@ -73,7 +84,7 @@ static inline s64 mmc_offset(int copy)
        str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
        if (str) {
                /* try to place the environment at end of the partition */
-               err = mmc_offset_try_partition(str, &val);
+               err = mmc_offset_try_partition(str, copy, &val);
                if (!err)
                        return val;
        }
@@ -114,11 +125,6 @@ __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
        return 0;
 }
 
-__weak int mmc_get_env_dev(void)
-{
-       return CONFIG_SYS_MMC_ENV_DEV;
-}
-
 #ifdef CONFIG_SYS_MMC_ENV_PART
 __weak uint mmc_get_env_part(struct mmc *mmc)
 {
index 41ef3d8..c2f4441 100644 (file)
 
 #define CONFIG_83XX_PCI_STREAMING
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        0xFIXME
index 4b43ee1..618e210 100644 (file)
 
 #define CONFIG_83XX_PCI_STREAMING
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        0xFIXME
index d2a9261..8b7e0da 100644 (file)
 #define CONFIG_SYS_PCI1_IO_SIZE        0x100000        /* 1M */
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
     #define PCI_ENET0_IOADDR   0xe0000000
index 834bf7a..d174b27 100644 (file)
@@ -280,7 +280,6 @@ extern unsigned long get_clock_freq(void);
 
 #define CONFIG_MPC85XX_PCI2
 
-#undef CONFIG_TULIP
 
 #undef CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1057  /* Motorola */
index b9c57e1..e473c0f 100644 (file)
@@ -256,7 +256,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 #define CONFIG_SYS_ISA_IO_BASE_ADDRESS VIDEO_IO_OFFSET
 #endif
 
-#undef CONFIG_TULIP
 
 #ifndef CONFIG_PCI_PNP
        #define PCI_ENET0_IOADDR        CONFIG_SYS_PCI1_IO_BUS
index 4b40129..f760518 100644 (file)
@@ -374,7 +374,6 @@ extern unsigned long get_clock_freq(void);
 #endif
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_DM_PCI)
 #define CONFIG_FSL_PCI_INIT            1       /* Use common FSL init code */
index c25b04e..dcb09b0 100644 (file)
@@ -278,7 +278,6 @@ extern unsigned long get_clock_freq(void);
 
 #define CONFIG_MPC85XX_PCI2
 
-#undef CONFIG_TULIP
 
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1057  /* Motorola */
index 4d1a417..a9f3029 100644 (file)
 #define CONFIG_SYS_PCI1_IO_SIZE        0x100000        /* 1M */
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
     #define PCI_ENET0_IOADDR   0xe0000000
index 1466364..c49f786 100644 (file)
@@ -288,7 +288,6 @@ extern unsigned long get_clock_freq(void);
 #endif /* CONFIG_QE */
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #undef CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1057  /* Motorola */
index dd291ac..acb8dec 100644 (file)
@@ -394,7 +394,6 @@ extern unsigned long get_clock_freq(void);
 #endif /* CONFIG_QE */
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #undef CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 
index 429dae1..57aebfd 100644 (file)
 #define CONFIG_SYS_ISA_IO_BASE_ADDRESS VIDEO_IO_OFFSET
 #endif
 
-#undef CONFIG_TULIP
 
 #ifndef CONFIG_PCI_PNP
        #define PCI_ENET0_IOADDR        CONFIG_SYS_PCIE3_IO_BUS
index 1560b61..42fdcdd 100644 (file)
@@ -330,7 +330,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
 
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 
-#undef CONFIG_TULIP
 
 /************************************************************
  * USB support
index d43d217..aa70f01 100644 (file)
 #define CONFIG_SYS_PCI1_IO_PHYS                CONFIG_SYS_PCI1_IO_BASE
 #define CONFIG_SYS_PCI1_IO_SIZE                0x1000000       /* 16M */
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        CONFIG_SYS_PCI1_IO_BASE
index a7c6677..e51398d 100644 (file)
 
 #if defined(CONFIG_PCI)
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        0xFIXME
index 96c1d53..2f8ac20 100644 (file)
@@ -34,7 +34,6 @@
  * PCI definitions
  */
 
-#define CONFIG_TULIP
 #define CONFIG_SYS_RX_ETH_BUFFER       8       /* use 8 rx buffer on eepro100  */
 
 /*-----------------------------------------------------------------------
index cca596d..0561ec2 100644 (file)
 
 #if defined(CONFIG_PCI)
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        0xFIXME
index f946833..6ac5d7b 100644 (file)
 #endif
 
 #if defined(CONFIG_PCI)
-#undef CONFIG_TULIP
 
 #define CONFIG_PCI_SCAN_SHOW           /* show pci devices on startup */
 
index 5b93ccb..27a15ed 100644 (file)
 
 #define CONFIG_PCI_SCAN_SHOW            /* show pci devices on startup */
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
     #define PCI_ENET0_IOADDR   0xe0000000
index 52d632b..bd94352 100644 (file)
 
 #if defined(CONFIG_PCI)
 
-#undef CONFIG_TULIP
 
 #if !defined(CONFIG_PCI_PNP)
        #define PCI_ENET0_IOADDR        0xFIXME
index e89fbdb..6655043 100644 (file)
@@ -211,6 +211,17 @@ struct env_driver {
 
 extern struct hsearch_data env_htab;
 
+/**
+ * env_get_location()- Provide the best location for the U-Boot environment
+ *
+ * It is a weak function allowing board to overidde the environment location
+ *
+ * @op: operations performed on the environment
+ * @prio: priority between the multiple environments, 0 being the
+ *        highest priority
+ * @return  an enum env_location value on success, or -ve error code.
+ */
+enum env_location env_get_location(enum env_operation op, int prio);
 #endif /* DO_DEPS_ONLY */
 
 #endif /* _ENV_INTERNAL_H_ */
index 2ec7642..d4de735 100644 (file)
@@ -4022,7 +4022,6 @@ CONFIG_TSECV2
 CONFIG_TSECV2_1
 CONFIG_TSEC_TBI
 CONFIG_TSEC_TBICR_SETTINGS
-CONFIG_TULIP
 CONFIG_TWL6030_INPUT
 CONFIG_TWL6030_POWER
 CONFIG_TWR
index 6ff38f1..a64aaa9 100644 (file)
@@ -336,3 +336,66 @@ def test_env_import_whitelist_delete(state_test_env):
     unset_var(state_test_env, 'foo2')
     unset_var(state_test_env, 'foo3')
     unset_var(state_test_env, 'foo4')
+
+@pytest.mark.buildconfigspec('cmd_nvedit_info')
+def test_env_info(state_test_env):
+
+    """Test 'env info' command with all possible options.
+    """
+    c = state_test_env.u_boot_console
+
+    response = c.run_command('env info')
+    nb_line = 0
+    for l in response.split('\n'):
+        if 'env_valid = ' in l:
+            assert '= invalid' in l or '= valid' in l or '= redundant' in l
+            nb_line += 1
+        elif 'env_ready =' in l or 'env_use_default =' in l:
+            assert '= true' in l or '= false' in l
+            nb_line += 1
+        else:
+            assert true
+    assert nb_line == 3
+
+    response = c.run_command('env info -p -d')
+    assert 'Default environment is used' in response or "Environment was loaded from persistent storage" in response
+    assert 'Environment can be persisted' in response or "Environment cannot be persisted" in response
+
+    response = c.run_command('env info -p -d -q')
+    assert response == ""
+
+    response = c.run_command('env info -p -q')
+    assert response == ""
+
+    response = c.run_command('env info -d -q')
+    assert response == ""
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_nvedit_info')
+@pytest.mark.buildconfigspec('cmd_echo')
+def test_env_info_sandbox(state_test_env):
+
+    """Test 'env info' command result with several options on sandbox
+       with a known ENV configuration: ready & default & persistent
+    """
+    c = state_test_env.u_boot_console
+
+    response = c.run_command('env info')
+    assert 'env_ready = true' in response
+    assert 'env_use_default = true' in response
+
+    response = c.run_command('env info -p -d')
+    assert 'Default environment is used' in response
+    assert 'Environment cannot be persisted' in response
+
+    response = c.run_command('env info -d -q')
+    response = c.run_command('echo $?')
+    assert response == "0"
+
+    response = c.run_command('env info -p -q')
+    response = c.run_command('echo $?')
+    assert response == "1"
+
+    response = c.run_command('env info -d -p -q')
+    response = c.run_command('echo $?')
+    assert response == "1"