1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Command for accessing Arcturus factory environment.
5 * Copyright 2013-2019 Arcturus Networks Inc.
6 * https://www.arcturusnetworks.com/products/
7 * by Oleksandr G Zhadan et al.
17 #include <spi_flash.h>
22 static ulong fwenv_addr[MAX_FWENV_ADDR];
23 const char mystrerr[] = "ERROR: Failed to save factory info";
25 static int ishwaddr(char *hwaddr)
27 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
28 if (hwaddr[2] == ':' &&
37 #if (FWENV_TYPE == FWENV_MMC)
39 static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
41 int set_mmc_arc_product(int argc, char *const argv[])
47 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
49 mmc = find_mmc_device(mmc_dev_num);
51 printf("No SD/MMC/eMMC card found\n");
55 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
59 if (mmc_getwp(mmc) == 1) {
60 printf("Error: card is write protected!\n");
61 return CMD_RET_FAILURE;
64 /* Save factory defaults */
66 cnt = 1; /* One 512 bytes block */
68 for (i = 0; i < MAX_FWENV_ADDR; i++)
69 if (fwenv_addr[i] != -1) {
70 blk = fwenv_addr[i] / 512;
71 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
73 printf("%s: %s [%d]\n", __func__, mystrerr, i);
83 static int read_mmc_arc_info(void)
89 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
91 mmc = find_mmc_device(mmc_dev_num);
93 printf("No SD/MMC/eMMC card found\n");
97 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
103 cnt = 1; /* One 512 bytes block */
105 for (i = 0; i < MAX_FWENV_ADDR; i++)
106 if (fwenv_addr[i] != -1) {
107 blk = fwenv_addr[i] / 512;
108 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
109 flush_cache((ulong) addr, 512);
117 #if (FWENV_TYPE == FWENV_SPI_FLASH)
119 static struct spi_flash *flash;
120 static char smac[4][18];
122 int set_spi_arc_product(int argc, char *const argv[])
126 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
127 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
129 printf("Failed to initialize SPI flash at %u:%u\n",
130 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
134 /* Save factory defaults */
135 for (i = 0; i < MAX_FWENV_ADDR; i++)
136 if (fwenv_addr[i] != -1)
138 (flash, fwenv_addr[i], sizeof(smac), smac))
139 printf("%s: %s [%d]\n", __func__, mystrerr, i);
148 static int read_spi_arc_info(void)
152 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
153 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
155 printf("Failed to initialize SPI flash at %u:%u\n",
156 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
159 for (i = 0; i < MAX_FWENV_ADDR; i++)
160 if (fwenv_addr[i] != -1)
162 (flash, fwenv_addr[i], sizeof(smac), smac))
168 #if (FWENV_TYPE == FWENV_NOR_FLASH)
170 static char smac[4][18];
172 int set_nor_arc_product(int argc, char *const argv[])
176 /* Save factory defaults */
177 for (i = 0; i < MAX_FWENV_ADDR; i++)
178 if (fwenv_addr[i] != -1) {
179 ulong fwenv_end = fwenv_addr[i] + 4;
181 flash_sect_roundb(&fwenv_end);
182 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
184 ((char *)smac, fwenv_addr[i], sizeof(smac)))
185 printf("%s: %s [%d]\n", __func__, mystrerr, i);
188 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
196 static int read_nor_arc_info(void)
200 for (i = 0; i < MAX_FWENV_ADDR; i++)
201 if (fwenv_addr[i] != -1) {
202 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
210 int set_arc_product(int argc, char *const argv[])
215 /* Check serial number */
216 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
220 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
223 strcpy(smac[0], argv[1]);
224 strcpy(smac[1], argv[2]);
225 strcpy(smac[2], argv[3]);
226 strcpy(smac[3], argv[4]);
228 #if (FWENV_TYPE == FWENV_NOR_FLASH)
229 return set_nor_arc_product(argc, argv);
231 #if (FWENV_TYPE == FWENV_SPI_FLASH)
232 return set_spi_arc_product(argc, argv);
234 #if (FWENV_TYPE == FWENV_MMC)
235 return set_mmc_arc_product(argc, argv);
240 static int read_arc_info(void)
242 #if (FWENV_TYPE == FWENV_NOR_FLASH)
243 return read_nor_arc_info();
245 #if (FWENV_TYPE == FWENV_SPI_FLASH)
246 return read_spi_arc_info();
248 #if (FWENV_TYPE == FWENV_MMC)
249 return read_mmc_arc_info();
254 static int do_get_arc_info(void)
256 int l = read_arc_info();
257 char *oldserial = env_get("SERIAL");
258 char *oldversion = env_get("VERSION");
260 if (oldversion != NULL)
261 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
265 printf("%s: failed to read factory info\n", __func__);
269 printf("\rSERIAL: ");
270 if (smac[0][0] == EMPY_CHAR) {
271 printf("<not found>\n");
273 printf("%s\n", smac[0]);
274 env_set("SERIAL", smac[0]);
277 if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
278 env_set("ethaddr", NULL);
279 env_set("eth1addr", NULL);
280 env_set("eth2addr", NULL);
285 if (smac[1][0] == EMPY_CHAR) {
286 printf("<not found>\n");
288 char *ret = env_get("ethaddr");
291 env_set("ethaddr", smac[1]);
292 printf("%s\n", smac[1]);
293 } else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
294 env_set("ethaddr", smac[1]);
295 printf("%s (factory)\n", smac[1]);
301 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
302 env_set("eth1addr", NULL);
303 env_set("eth2addr", NULL);
308 if (smac[2][0] == EMPY_CHAR) {
309 printf("<not found>\n");
311 char *ret = env_get("eth1addr");
314 env_set("ethaddr", smac[2]);
315 printf("%s\n", smac[2]);
316 } else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
317 env_set("eth1addr", smac[2]);
318 printf("%s (factory)\n", smac[2]);
324 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
325 env_set("eth2addr", NULL);
330 if (smac[3][0] == EMPY_CHAR) {
331 printf("<not found>\n");
333 char *ret = env_get("eth2addr");
336 env_set("ethaddr", smac[3]);
337 printf("%s\n", smac[3]);
338 } else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
339 env_set("eth2addr", smac[3]);
340 printf("%s (factory)\n", smac[3]);
346 if (oldserial == NULL || oldversion == NULL) {
347 if (oldversion == NULL)
348 env_set("VERSION", U_BOOT_VERSION);
355 static int init_fwenv(void)
359 fwenv_addr[0] = FWENV_ADDR1;
360 fwenv_addr[1] = FWENV_ADDR2;
361 fwenv_addr[2] = FWENV_ADDR3;
362 fwenv_addr[3] = FWENV_ADDR4;
364 for (i = 0; i < MAX_FWENV_ADDR; i++)
365 if (fwenv_addr[i] != -1)
368 printf("%s: No firmfare info storage address is defined\n",
373 void get_arc_info(void)
379 static int do_arc_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
391 if (strcmp(cmd, "product") == 0)
392 ret = set_arc_product(argc, argv);
393 else if (strcmp(cmd, "info") == 0)
394 ret = do_get_arc_info();
397 return CMD_RET_USAGE;
402 U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
403 "Arcturus product command sub-system",
404 "product serial hwaddr0 hwaddr1 hwaddr2 - save Arcturus factory env\n"
405 "info - show Arcturus factory env\n\n");