uboot/board/Arcturus/ucp1020/cmd_arc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Command for accessing Arcturus factory environment.
   4 *
   5 * Copyright 2013-2019 Arcturus Networks Inc.
   6 *           https://www.arcturusnetworks.com/products/
   7 *           by Oleksandr G Zhadan et al.
   8 *
   9 */
  10
  11#include <common.h>
  12#include <div64.h>
  13#include <env.h>
  14#include <malloc.h>
  15#include <spi_flash.h>
  16#include <mmc.h>
  17#include <version.h>
  18#include <asm/io.h>
  19
  20static ulong fwenv_addr[MAX_FWENV_ADDR];
  21const char mystrerr[] = "ERROR: Failed to save factory info";
  22
  23static int ishwaddr(char *hwaddr)
  24{
  25        if (strlen(hwaddr) == MAX_HWADDR_SIZE)
  26                if (hwaddr[2] == ':' &&
  27                    hwaddr[5] == ':' &&
  28                    hwaddr[8] == ':' &&
  29                    hwaddr[11] == ':' &&
  30                    hwaddr[14] == ':')
  31                        return 0;
  32        return -1;
  33}
  34
  35#if (FWENV_TYPE == FWENV_MMC)
  36
  37static char smac[29][18] __attribute__ ((aligned(0x200)));      /* 1 MMC block is 512 bytes */
  38
  39int set_mmc_arc_product(int argc, char *const argv[])
  40{
  41        struct mmc *mmc;
  42        u32 blk, cnt, n;
  43        int i, err = 1;
  44        void *addr;
  45        const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
  46
  47        mmc = find_mmc_device(mmc_dev_num);
  48        if (!mmc) {
  49                printf("No SD/MMC/eMMC card found\n");
  50                return 0;
  51        }
  52        if (mmc_init(mmc)) {
  53                printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
  54                       mmc_dev_num);
  55                return 0;
  56        }
  57        if (mmc_getwp(mmc) == 1) {
  58                printf("Error: card is write protected!\n");
  59                return CMD_RET_FAILURE;
  60        }
  61
  62        /* Save factory defaults */
  63        addr = (void *)smac;
  64        cnt = 1;                /* One 512 bytes block */
  65
  66        for (i = 0; i < MAX_FWENV_ADDR; i++)
  67                if (fwenv_addr[i] != -1) {
  68                        blk = fwenv_addr[i] / 512;
  69                        n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
  70                        if (n != cnt)
  71                                printf("%s: %s [%d]\n", __func__, mystrerr, i);
  72                        else
  73                                err = 0;
  74                }
  75        if (err)
  76                return -2;
  77
  78        return err;
  79}
  80
  81static int read_mmc_arc_info(void)
  82{
  83        struct mmc *mmc;
  84        u32 blk, cnt, n;
  85        int i;
  86        void *addr;
  87        const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
  88
  89        mmc = find_mmc_device(mmc_dev_num);
  90        if (!mmc) {
  91                printf("No SD/MMC/eMMC card found\n");
  92                return 0;
  93        }
  94        if (mmc_init(mmc)) {
  95                printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
  96                       mmc_dev_num);
  97                return 0;
  98        }
  99
 100        addr = (void *)smac;
 101        cnt = 1;                /* One 512 bytes block */
 102
 103        for (i = 0; i < MAX_FWENV_ADDR; i++)
 104                if (fwenv_addr[i] != -1) {
 105                        blk = fwenv_addr[i] / 512;
 106                        n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
 107                        flush_cache((ulong) addr, 512);
 108                        if (n == cnt)
 109                                return (i + 1);
 110                }
 111        return 0;
 112}
 113#endif
 114
 115#if (FWENV_TYPE == FWENV_SPI_FLASH)
 116
 117static struct spi_flash *flash;
 118static char smac[4][18];
 119
 120int set_spi_arc_product(int argc, char *const argv[])
 121{
 122        int i, err = 1;
 123
 124        flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
 125                                CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
 126        if (!flash) {
 127                printf("Failed to initialize SPI flash at %u:%u\n",
 128                       CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
 129                return -1;
 130        }
 131
 132        /* Save factory defaults */
 133        for (i = 0; i < MAX_FWENV_ADDR; i++)
 134                if (fwenv_addr[i] != -1)
 135                        if (spi_flash_write
 136                            (flash, fwenv_addr[i], sizeof(smac), smac))
 137                                printf("%s: %s [%d]\n", __func__, mystrerr, i);
 138                        else
 139                                err = 0;
 140        if (err)
 141                return -2;
 142
 143        return err;
 144}
 145
 146static int read_spi_arc_info(void)
 147{
 148        int i;
 149
 150        flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
 151                                CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
 152        if (!flash) {
 153                printf("Failed to initialize SPI flash at %u:%u\n",
 154                       CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
 155                return 0;
 156        }
 157        for (i = 0; i < MAX_FWENV_ADDR; i++)
 158                if (fwenv_addr[i] != -1)
 159                        if (!spi_flash_read
 160                            (flash, fwenv_addr[i], sizeof(smac), smac))
 161                                return (i + 1);
 162        return 0;
 163}
 164#endif
 165
 166#if (FWENV_TYPE == FWENV_NOR_FLASH)
 167
 168static char smac[4][18];
 169
 170int set_nor_arc_product(int argc, char *const argv[])
 171{
 172        int i, err = 1;
 173
 174        /* Save factory defaults */
 175        for (i = 0; i < MAX_FWENV_ADDR; i++)
 176                if (fwenv_addr[i] != -1) {
 177                        ulong fwenv_end = fwenv_addr[i] + 4;
 178
 179                        flash_sect_roundb(&fwenv_end);
 180                        flash_sect_protect(0, fwenv_addr[i], fwenv_end);
 181                        if (flash_write
 182                            ((char *)smac, fwenv_addr[i], sizeof(smac)))
 183                                printf("%s: %s [%d]\n", __func__, mystrerr, i);
 184                        else
 185                                err = 0;
 186                        flash_sect_protect(1, fwenv_addr[i], fwenv_end);
 187                }
 188        if (err)
 189                return -2;
 190
 191        return err;
 192}
 193
 194static int read_nor_arc_info(void)
 195{
 196        int i;
 197
 198        for (i = 0; i < MAX_FWENV_ADDR; i++)
 199                if (fwenv_addr[i] != -1) {
 200                        memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
 201                        return (i + 1);
 202                }
 203
 204        return 0;
 205}
 206#endif
 207
 208int set_arc_product(int argc, char *const argv[])
 209{
 210        if (argc != 5)
 211                return -1;
 212
 213        /* Check serial number */
 214        if (strlen(argv[1]) != MAX_SERIAL_SIZE)
 215                return -1;
 216
 217        /* Check HWaddrs */
 218        if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
 219                return -1;
 220
 221        strcpy(smac[0], argv[1]);
 222        strcpy(smac[1], argv[2]);
 223        strcpy(smac[2], argv[3]);
 224        strcpy(smac[3], argv[4]);
 225
 226#if (FWENV_TYPE == FWENV_NOR_FLASH)
 227        return set_nor_arc_product(argc, argv);
 228#endif
 229#if (FWENV_TYPE == FWENV_SPI_FLASH)
 230        return set_spi_arc_product(argc, argv);
 231#endif
 232#if (FWENV_TYPE == FWENV_MMC)
 233        return set_mmc_arc_product(argc, argv);
 234#endif
 235        return -2;
 236}
 237
 238static int read_arc_info(void)
 239{
 240#if (FWENV_TYPE == FWENV_NOR_FLASH)
 241        return read_nor_arc_info();
 242#endif
 243#if (FWENV_TYPE == FWENV_SPI_FLASH)
 244        return read_spi_arc_info();
 245#endif
 246#if (FWENV_TYPE == FWENV_MMC)
 247        return read_mmc_arc_info();
 248#endif
 249        return 0;
 250}
 251
 252static int do_get_arc_info(void)
 253{
 254        int l = read_arc_info();
 255        char *oldserial = env_get("SERIAL");
 256        char *oldversion = env_get("VERSION");
 257
 258        if (oldversion != NULL)
 259                if (strcmp(oldversion, U_BOOT_VERSION) != 0)
 260                        oldversion = NULL;
 261
 262        if (l == 0) {
 263                printf("%s: failed to read factory info\n", __func__);
 264                return -2;
 265        }
 266
 267        printf("\rSERIAL:  ");
 268        if (smac[0][0] == EMPY_CHAR) {
 269                printf("<not found>\n");
 270        } else {
 271                printf("%s\n", smac[0]);
 272                env_set("SERIAL", smac[0]);
 273        }
 274
 275        if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
 276                env_set("ethaddr", NULL);
 277                env_set("eth1addr", NULL);
 278                env_set("eth2addr", NULL);
 279                goto done;
 280        }
 281
 282        printf("HWADDR0: ");
 283        if (smac[1][0] == EMPY_CHAR) {
 284                printf("<not found>\n");
 285        } else {
 286                char *ret = env_get("ethaddr");
 287
 288                if (ret == NULL) {
 289                        env_set("ethaddr", smac[1]);
 290                        printf("%s\n", smac[1]);
 291                } else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
 292                        env_set("ethaddr", smac[1]);
 293                        printf("%s (factory)\n", smac[1]);
 294                } else {
 295                        printf("%s\n", ret);
 296                }
 297        }
 298
 299        if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
 300                env_set("eth1addr", NULL);
 301                env_set("eth2addr", NULL);
 302                goto done;
 303        }
 304
 305        printf("HWADDR1: ");
 306        if (smac[2][0] == EMPY_CHAR) {
 307                printf("<not found>\n");
 308        } else {
 309                char *ret = env_get("eth1addr");
 310
 311                if (ret == NULL) {
 312                        env_set("ethaddr", smac[2]);
 313                        printf("%s\n", smac[2]);
 314                } else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
 315                        env_set("eth1addr", smac[2]);
 316                        printf("%s (factory)\n", smac[2]);
 317                } else {
 318                        printf("%s\n", ret);
 319                }
 320        }
 321
 322        if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
 323                env_set("eth2addr", NULL);
 324                goto done;
 325        }
 326
 327        printf("HWADDR2: ");
 328        if (smac[3][0] == EMPY_CHAR) {
 329                printf("<not found>\n");
 330        } else {
 331                char *ret = env_get("eth2addr");
 332
 333                if (ret == NULL) {
 334                        env_set("ethaddr", smac[3]);
 335                        printf("%s\n", smac[3]);
 336                } else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
 337                        env_set("eth2addr", smac[3]);
 338                        printf("%s (factory)\n", smac[3]);
 339                } else {
 340                        printf("%s\n", ret);
 341                }
 342        }
 343done:
 344        if (oldserial == NULL || oldversion == NULL) {
 345                if (oldversion == NULL)
 346                        env_set("VERSION", U_BOOT_VERSION);
 347                env_save();
 348        }
 349
 350        return 0;
 351}
 352
 353static int init_fwenv(void)
 354{
 355        int i, ret = -1;
 356
 357        fwenv_addr[0] = FWENV_ADDR1;
 358        fwenv_addr[1] = FWENV_ADDR2;
 359        fwenv_addr[2] = FWENV_ADDR3;
 360        fwenv_addr[3] = FWENV_ADDR4;
 361
 362        for (i = 0; i < MAX_FWENV_ADDR; i++)
 363                if (fwenv_addr[i] != -1)
 364                        ret = 0;
 365        if (ret)
 366                printf("%s: No firmfare info storage address is defined\n",
 367                       __func__);
 368        return ret;
 369}
 370
 371void get_arc_info(void)
 372{
 373        if (!init_fwenv())
 374                do_get_arc_info();
 375}
 376
 377static int do_arc_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
 378{
 379        const char *cmd;
 380        int ret = -1;
 381
 382        cmd = argv[1];
 383        --argc;
 384        ++argv;
 385
 386        if (init_fwenv())
 387                return ret;
 388
 389        if (strcmp(cmd, "product") == 0)
 390                ret = set_arc_product(argc, argv);
 391        else if (strcmp(cmd, "info") == 0)
 392                ret = do_get_arc_info();
 393
 394        if (ret == -1)
 395                return CMD_RET_USAGE;
 396
 397        return ret;
 398}
 399
 400U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
 401           "Arcturus product command sub-system",
 402           "product serial hwaddr0 hwaddr1 hwaddr2    - save Arcturus factory env\n"
 403           "info                                      - show Arcturus factory env\n\n");
 404