X-Git-Url: https://git.librecmc.org/?p=oweals%2Fu-boot.git;a=blobdiff_plain;f=board%2FArcturus%2Fucp1020%2Fcmd_arc.c;h=4b30b66e208f178fd596032c563338b3d6781f79;hp=fa6b4853f9b063ce2d042f8618928d127f330a84;hb=c27178ba3649f539c9f1890ea147f4c5415f63b5;hpb=8b0044ff5942943eaa49935f49d5006b346a60f8 diff --git a/board/Arcturus/ucp1020/cmd_arc.c b/board/Arcturus/ucp1020/cmd_arc.c index fa6b4853f9..4b30b66e20 100644 --- a/board/Arcturus/ucp1020/cmd_arc.c +++ b/board/Arcturus/ucp1020/cmd_arc.c @@ -1,44 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * 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. * - * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause - * */ #include +#include +#include #include +#include +#include #include #include - +#include +#include #include +#include -#ifndef CONFIG_SF_DEFAULT_SPEED -# define CONFIG_SF_DEFAULT_SPEED 1000000 -#endif -#ifndef CONFIG_SF_DEFAULT_MODE -# define CONFIG_SF_DEFAULT_MODE SPI_MODE0 -#endif -#ifndef CONFIG_SF_DEFAULT_CS -# define CONFIG_SF_DEFAULT_CS 0 -#endif -#ifndef CONFIG_SF_DEFAULT_BUS -# define CONFIG_SF_DEFAULT_BUS 0 -#endif - -#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) { @@ -52,156 +36,350 @@ static int ishwaddr(char *hwaddr) return -1; } -static int set_arc_product(int argc, char *const argv[]) +#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[]) { - int err = 0; - char *mystrerr = "ERROR: Failed to save factory info in spi location"; + 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; + } - if (argc != 5) - return -1; + /* 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; - /* Check serial number */ - if (strlen(argv[1]) != MAX_SERIAL_SIZE) - return -1; + return err; +} - /* Check HWaddrs */ - if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4])) - return -1; +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; + } - strcpy(smac[3], argv[1]); - strcpy(smac[2], argv[2]); - strcpy(smac[1], argv[3]); - strcpy(smac[0], argv[4]); + addr = (void *)smac; + cnt = 1; /* One 512 bytes block */ - flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, - CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); + 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 - /* - * Save factory defaults - */ +#if (FWENV_TYPE == FWENV_SPI_FLASH) - 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 struct spi_flash *flash; +static char smac[4][18]; - if (spi_flash_write(flash, FIRM_ADDR3, sizeof(smac), smac)) { - printf("%s: %s [3]\n", __func__, mystrerr); - err++; - } +int set_spi_arc_product(int argc, char *const argv[]) +{ + int i, err = 1; - if (spi_flash_write(flash, FIRM_ADDR4, sizeof(smac), smac)) { - printf("%s: %s [4]\n", __func__, mystrerr); - err++; + 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; } - if (err == 4) { - printf("%s: %s [ALL]\n", __func__, mystrerr); + /* 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 0; + return err; } -int get_arc_info(void) +static int read_spi_arc_info(void) { - int location = 1; - char *myerr = "ERROR: Failed to read all 4 factory info spi locations"; + 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) - 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; - } - } +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 (smac[3][0] != 0) { - if (location > 1) - printf("Using region %d\n", location); - printf("SERIAL: "); - if (smac[3][0] == 0xFF) { - printf("\t\n"); - } else { - printf("\t%s\n", smac[3]); - setenv("SERIAL", smac[3]); + 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); } - } - if (strcmp(smac[2], "00:00:00:00:00:00") == 0) - return 0; + return 0; +} +#endif + +int set_arc_product(int argc, char *const argv[]) +{ + if (argc != 5) + return -1; + + /* Check serial number */ + if (strlen(argv[1]) != MAX_SERIAL_SIZE) + return -1; + + /* Check HWaddrs */ + if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4])) + return -1; + + strcpy(smac[0], argv[1]); + strcpy(smac[1], argv[2]); + strcpy(smac[2], argv[3]); + strcpy(smac[3], argv[4]); + +#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; +} + +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; +} + +static int do_get_arc_info(void) +{ + int l = read_arc_info(); + char *oldserial = env_get("SERIAL"); + char *oldversion = env_get("VERSION"); + + if (oldversion != NULL) + if (strcmp(oldversion, U_BOOT_VERSION) != 0) + oldversion = NULL; - printf("HWADDR0:"); - if (smac[2][0] == 0xFF) { - printf("\t\n"); + if (l == 0) { + printf("%s: failed to read factory info\n", __func__); + return -2; + } + + printf("\rSERIAL: "); + if (smac[0][0] == EMPY_CHAR) { + printf("\n"); } else { - char *ret = getenv("ethaddr"); + printf("%s\n", smac[0]); + env_set("SERIAL", smac[0]); + } + + if (strcmp(smac[1], "00:00:00:00:00:00") == 0) { + env_set("ethaddr", NULL); + env_set("eth1addr", NULL); + env_set("eth2addr", NULL); + goto done; + } - if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) { - setenv("ethaddr", smac[2]); - printf("\t%s (factory)\n", smac[2]); + printf("HWADDR0: "); + if (smac[1][0] == EMPY_CHAR) { + printf("\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("\t%s\n", ret); + printf("%s\n", ret); } } - if (strcmp(smac[1], "00:00:00:00:00:00") == 0) { - setenv("eth1addr", smac[2]); - setenv("eth2addr", smac[2]); - return 0; + 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[1][0] == 0xFF) { - printf("\t\n"); + printf("HWADDR1: "); + if (smac[2][0] == EMPY_CHAR) { + printf("\n"); } else { - char *ret = getenv("eth1addr"); - - if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) { - setenv("eth1addr", smac[1]); - printf("\t%s (factory)\n", smac[1]); + char *ret = env_get("eth1addr"); + + 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) { - setenv("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\n"); + printf("HWADDR2: "); + if (smac[3][0] == EMPY_CHAR) { + printf("\n"); } else { - char *ret = getenv("eth2addr"); - - if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) { - setenv("eth2addr", smac[0]); - printf("\t%s (factory)\n", smac[0]); + char *ret = env_get("eth2addr"); + + 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(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { const char *cmd; int ret = -1; @@ -210,15 +388,14 @@ static int do_arc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) --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;