board: Arcturus: DM: Disable drivers without DM support.

Extra "not DM" controllers support is disabled.
u-boot BSP still good enough to upgrade and run images.

Signed-off-by: Oleksandr Zhadan <oleks@arcturusnetworks.com>
Signed-off-by: Michael Durrant <mdurrant@arcturusnetworks.com>
diff --git a/board/Arcturus/ucp1020/cmd_arc.c b/board/Arcturus/ucp1020/cmd_arc.c
index 9579d52..7a510c6 100644
--- a/board/Arcturus/ucp1020/cmd_arc.c
+++ b/board/Arcturus/ucp1020/cmd_arc.c
@@ -2,8 +2,8 @@
 /*
  * Command for accessing Arcturus factory environment.
  *
- * Copyright 2013-2015 Arcturus Networks Inc.
- *           http://www.arcturusnetworks.com/products/ucp1020/
+ * Copyright 2013-2019 Arcturus Networks Inc.
+ *           https://www.arcturusnetworks.com/products/
  *           by Oleksandr G Zhadan et al.
  *
  */
@@ -12,19 +12,13 @@
 #include <div64.h>
 #include <malloc.h>
 #include <spi_flash.h>
-
+#include <mmc.h>
+#include <version.h>
+#include <environment.h>
 #include <asm/io.h>
 
-#define MAX_SERIAL_SIZE 15
-#define MAX_HWADDR_SIZE 17
-
-#define FIRM_ADDR1 (0x200 - sizeof(smac))
-#define FIRM_ADDR2 (0x400 - sizeof(smac))
-#define FIRM_ADDR3 (CONFIG_ENV_SECT_SIZE + 0x200 - sizeof(smac))
-#define FIRM_ADDR4 (CONFIG_ENV_SECT_SIZE + 0x400 - sizeof(smac))
-
-static struct spi_flash *flash;
-char smac[4][18];
+static ulong fwenv_addr[MAX_FWENV_ADDR];
+const char mystrerr[] = "ERROR: Failed to save factory info";
 
 static int ishwaddr(char *hwaddr)
 {
@@ -38,11 +32,181 @@
 	return -1;
 }
 
-static int set_arc_product(int argc, char *const argv[])
-{
-	int err = 0;
-	char *mystrerr = "ERROR: Failed to save factory info in spi location";
+#if (FWENV_TYPE == FWENV_MMC)
 
+static char smac[29][18] __attribute__ ((aligned(0x200)));	/* 1 MMC block is 512 bytes */
+
+int set_mmc_arc_product(int argc, char *const argv[])
+{
+	struct mmc *mmc;
+	u32 blk, cnt, n;
+	int i, err = 1;
+	void *addr;
+	const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
+
+	mmc = find_mmc_device(mmc_dev_num);
+	if (!mmc) {
+		printf("No SD/MMC/eMMC card found\n");
+		return 0;
+	}
+	if (mmc_init(mmc)) {
+		printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
+		       mmc_dev_num);
+		return 0;
+	}
+	if (mmc_getwp(mmc) == 1) {
+		printf("Error: card is write protected!\n");
+		return CMD_RET_FAILURE;
+	}
+
+	/* Save factory defaults */
+	addr = (void *)smac;
+	cnt = 1;		/* One 512 bytes block */
+
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1) {
+			blk = fwenv_addr[i] / 512;
+			n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
+			if (n != cnt)
+				printf("%s: %s [%d]\n", __func__, mystrerr, i);
+			else
+				err = 0;
+		}
+	if (err)
+		return -2;
+
+	return err;
+}
+
+static int read_mmc_arc_info(void)
+{
+	struct mmc *mmc;
+	u32 blk, cnt, n;
+	int i;
+	void *addr;
+	const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
+
+	mmc = find_mmc_device(mmc_dev_num);
+	if (!mmc) {
+		printf("No SD/MMC/eMMC card found\n");
+		return 0;
+	}
+	if (mmc_init(mmc)) {
+		printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
+		       mmc_dev_num);
+		return 0;
+	}
+
+	addr = (void *)smac;
+	cnt = 1;		/* One 512 bytes block */
+
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1) {
+			blk = fwenv_addr[i] / 512;
+			n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
+			flush_cache((ulong) addr, 512);
+			if (n == cnt)
+				return (i + 1);
+		}
+	return 0;
+}
+#endif
+
+#if (FWENV_TYPE == FWENV_SPI_FLASH)
+
+static struct spi_flash *flash;
+static char smac[4][18];
+
+int set_spi_arc_product(int argc, char *const argv[])
+{
+	int i, err = 1;
+
+	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+	if (!flash) {
+		printf("Failed to initialize SPI flash at %u:%u\n",
+		       CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
+		return -1;
+	}
+
+	/* Save factory defaults */
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1)
+			if (spi_flash_write
+			    (flash, fwenv_addr[i], sizeof(smac), smac))
+				printf("%s: %s [%d]\n", __func__, mystrerr, i);
+			else
+				err = 0;
+	if (err)
+		return -2;
+
+	return err;
+}
+
+static int read_spi_arc_info(void)
+{
+	int i;
+
+	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+	if (!flash) {
+		printf("Failed to initialize SPI flash at %u:%u\n",
+		       CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
+		return 0;
+	}
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1)
+			if (!spi_flash_read
+			    (flash, fwenv_addr[i], sizeof(smac), smac))
+				return (i + 1);
+	return 0;
+}
+#endif
+
+#if (FWENV_TYPE == FWENV_NOR_FLASH)
+
+static char smac[4][18];
+
+int set_nor_arc_product(int argc, char *const argv[])
+{
+	int i, err = 1;
+
+	/* Save factory defaults */
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1) {
+			ulong fwenv_end = fwenv_addr[i] + 4;
+
+			flash_sect_roundb(&fwenv_end);
+			flash_sect_protect(0, fwenv_addr[i], fwenv_end);
+			if (flash_write
+			    ((char *)smac, fwenv_addr[i], sizeof(smac)))
+				printf("%s: %s [%d]\n", __func__, mystrerr, i);
+			else
+				err = 0;
+			flash_sect_protect(1, fwenv_addr[i], fwenv_end);
+		}
+	if (err)
+		return -2;
+
+	return err;
+}
+
+static int read_nor_arc_info(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1) {
+			memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
+			return (i + 1);
+		}
+
+	return 0;
+}
+#endif
+
+int set_arc_product(int argc, char *const argv[])
+{
 	if (argc != 5)
 		return -1;
 
@@ -54,140 +218,163 @@
 	if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
 		return -1;
 
-	strcpy(smac[3], argv[1]);
-	strcpy(smac[2], argv[2]);
-	strcpy(smac[1], argv[3]);
-	strcpy(smac[0], argv[4]);
+	strcpy(smac[0], argv[1]);
+	strcpy(smac[1], argv[2]);
+	strcpy(smac[2], argv[3]);
+	strcpy(smac[3], argv[4]);
 
-	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
-				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+#if (FWENV_TYPE == FWENV_NOR_FLASH)
+	return set_nor_arc_product(argc, argv);
+#endif
+#if (FWENV_TYPE == FWENV_SPI_FLASH)
+	return set_spi_arc_product(argc, argv);
+#endif
+#if (FWENV_TYPE == FWENV_MMC)
+	return set_mmc_arc_product(argc, argv);
+#endif
+	return -2;
+}
 
-	/*
-	 * Save factory defaults
-	 */
+static int read_arc_info(void)
+{
+#if (FWENV_TYPE == FWENV_NOR_FLASH)
+	return read_nor_arc_info();
+#endif
+#if (FWENV_TYPE == FWENV_SPI_FLASH)
+	return read_spi_arc_info();
+#endif
+#if (FWENV_TYPE == FWENV_MMC)
+	return read_mmc_arc_info();
+#endif
+	return 0;
+}
 
-	if (spi_flash_write(flash, FIRM_ADDR1, sizeof(smac), smac)) {
-		printf("%s: %s [1]\n", __func__, mystrerr);
-		err++;
-	}
-	if (spi_flash_write(flash, FIRM_ADDR2, sizeof(smac), smac)) {
-		printf("%s: %s [2]\n", __func__, mystrerr);
-		err++;
-	}
+static int do_get_arc_info(void)
+{
+	int l = read_arc_info();
+	char *oldserial = env_get("SERIAL");
+	char *oldversion = env_get("VERSION");
 
-	if (spi_flash_write(flash, FIRM_ADDR3, sizeof(smac), smac)) {
-		printf("%s: %s [3]\n", __func__, mystrerr);
-		err++;
-	}
+	if (oldversion != NULL)
+		if (strcmp(oldversion, U_BOOT_VERSION) != 0)
+			oldversion = NULL;
 
-	if (spi_flash_write(flash, FIRM_ADDR4, sizeof(smac), smac)) {
-		printf("%s: %s [4]\n", __func__, mystrerr);
-		err++;
-	}
-
-	if (err == 4) {
-		printf("%s: %s [ALL]\n", __func__, mystrerr);
+	if (l == 0) {
+		printf("%s: failed to read factory info\n", __func__);
 		return -2;
 	}
 
-	return 0;
-}
-
-int get_arc_info(void)
-{
-	int location = 1;
-	char *myerr = "ERROR: Failed to read all 4 factory info spi locations";
-
-	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
-				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
-
-	if (spi_flash_read(flash, FIRM_ADDR1, sizeof(smac), smac)) {
-		location++;
-		if (spi_flash_read(flash, FIRM_ADDR2, sizeof(smac), smac)) {
-			location++;
-			if (spi_flash_read(flash, FIRM_ADDR3, sizeof(smac),
-					   smac)) {
-				location++;
-				if (spi_flash_read(flash, FIRM_ADDR4,
-						   sizeof(smac), smac)) {
-					printf("%s: %s\n", __func__, myerr);
-					return -2;
-				}
-			}
-		}
-	}
-	if (smac[3][0] != 0) {
-		if (location > 1)
-			printf("Using region %d\n", location);
-		printf("SERIAL: ");
-		if (smac[3][0] == 0xFF) {
-			printf("\t<not found>\n");
-		} else {
-			printf("\t%s\n", smac[3]);
-			env_set("SERIAL", smac[3]);
-		}
-	}
-
-	if (strcmp(smac[2], "00:00:00:00:00:00") == 0)
-		return 0;
-
-	printf("HWADDR0:");
-	if (smac[2][0] == 0xFF) {
-		printf("\t<not found>\n");
+	printf("\rSERIAL:  ");
+	if (smac[0][0] == EMPY_CHAR) {
+		printf("<not found>\n");
 	} else {
-		char *ret = env_get("ethaddr");
-
-		if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
-			env_set("ethaddr", smac[2]);
-			printf("\t%s (factory)\n", smac[2]);
-		} else {
-			printf("\t%s\n", ret);
-		}
+		printf("%s\n", smac[0]);
+		env_set("SERIAL", smac[0]);
 	}
 
 	if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
-		env_set("eth1addr", smac[2]);
-		env_set("eth2addr", smac[2]);
-		return 0;
+		env_set("ethaddr", NULL);
+		env_set("eth1addr", NULL);
+		env_set("eth2addr", NULL);
+		goto done;
 	}
 
-	printf("HWADDR1:");
-	if (smac[1][0] == 0xFF) {
-		printf("\t<not found>\n");
+	printf("HWADDR0: ");
+	if (smac[1][0] == EMPY_CHAR) {
+		printf("<not found>\n");
+	} else {
+		char *ret = env_get("ethaddr");
+
+		if (ret == NULL) {
+			env_set("ethaddr", smac[1]);
+			printf("%s\n", smac[1]);
+		} else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
+			env_set("ethaddr", smac[1]);
+			printf("%s (factory)\n", smac[1]);
+		} else {
+			printf("%s\n", ret);
+		}
+	}
+
+	if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
+		env_set("eth1addr", NULL);
+		env_set("eth2addr", NULL);
+		goto done;
+	}
+
+	printf("HWADDR1: ");
+	if (smac[2][0] == EMPY_CHAR) {
+		printf("<not found>\n");
 	} else {
 		char *ret = env_get("eth1addr");
 
-		if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
-			env_set("eth1addr", smac[1]);
-			printf("\t%s (factory)\n", smac[1]);
+		if (ret == NULL) {
+			env_set("ethaddr", smac[2]);
+			printf("%s\n", smac[2]);
+		} else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
+			env_set("eth1addr", smac[2]);
+			printf("%s (factory)\n", smac[2]);
 		} else {
-			printf("\t%s\n", ret);
+			printf("%s\n", ret);
 		}
 	}
 
-	if (strcmp(smac[0], "00:00:00:00:00:00") == 0) {
-		env_set("eth2addr", smac[1]);
-		return 0;
+	if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
+		env_set("eth2addr", NULL);
+		goto done;
 	}
 
-	printf("HWADDR2:");
-	if (smac[0][0] == 0xFF) {
-		printf("\t<not found>\n");
+	printf("HWADDR2: ");
+	if (smac[3][0] == EMPY_CHAR) {
+		printf("<not found>\n");
 	} else {
 		char *ret = env_get("eth2addr");
 
-		if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
-			env_set("eth2addr", smac[0]);
-			printf("\t%s (factory)\n", smac[0]);
+		if (ret == NULL) {
+			env_set("ethaddr", smac[3]);
+			printf("%s\n", smac[3]);
+		} else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
+			env_set("eth2addr", smac[3]);
+			printf("%s (factory)\n", smac[3]);
 		} else {
-			printf("\t%s\n", ret);
+			printf("%s\n", ret);
 		}
 	}
+done:
+	if (oldserial == NULL || oldversion == NULL) {
+		if (oldversion == NULL)
+			env_set("VERSION", U_BOOT_VERSION);
+		env_save();
+	}
 
 	return 0;
 }
 
-static int do_arc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+static int init_fwenv(void)
+{
+	int i, ret = -1;
+
+	fwenv_addr[0] = FWENV_ADDR1;
+	fwenv_addr[1] = FWENV_ADDR2;
+	fwenv_addr[2] = FWENV_ADDR3;
+	fwenv_addr[3] = FWENV_ADDR4;
+
+	for (i = 0; i < MAX_FWENV_ADDR; i++)
+		if (fwenv_addr[i] != -1)
+			ret = 0;
+	if (ret)
+		printf("%s: No firmfare info storage address is defined\n",
+		       __func__);
+	return ret;
+}
+
+void get_arc_info(void)
+{
+	if (!init_fwenv())
+		do_get_arc_info();
+}
+
+static int do_arc_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
 {
 	const char *cmd;
 	int ret = -1;
@@ -196,15 +383,14 @@
 	--argc;
 	++argv;
 
-	if (strcmp(cmd, "product") == 0) {
+	if (init_fwenv())
+		return ret;
+
+	if (strcmp(cmd, "product") == 0)
 		ret = set_arc_product(argc, argv);
-		goto done;
-	}
-	if (strcmp(cmd, "info") == 0) {
-		ret = get_arc_info();
-		goto done;
-	}
-done:
+	else if (strcmp(cmd, "info") == 0)
+		ret = do_get_arc_info();
+
 	if (ret == -1)
 		return CMD_RET_USAGE;