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.
18 #include <spi_flash.h>
23 static ulong fwenv_addr[MAX_FWENV_ADDR];
24 const char mystrerr[] = "ERROR: Failed to save factory info";
26 static int ishwaddr(char *hwaddr)
28 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
29 if (hwaddr[2] == ':' &&
38 #if (FWENV_TYPE == FWENV_MMC)
40 static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
42 int set_mmc_arc_product(int argc, char *const argv[])
48 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
50 mmc = find_mmc_device(mmc_dev_num);
52 printf("No SD/MMC/eMMC card found\n");
56 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
60 if (mmc_getwp(mmc) == 1) {
61 printf("Error: card is write protected!\n");
62 return CMD_RET_FAILURE;
65 /* Save factory defaults */
67 cnt = 1; /* One 512 bytes block */
69 for (i = 0; i < MAX_FWENV_ADDR; i++)
70 if (fwenv_addr[i] != -1) {
71 blk = fwenv_addr[i] / 512;
72 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
74 printf("%s: %s [%d]\n", __func__, mystrerr, i);
84 static int read_mmc_arc_info(void)
90 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
92 mmc = find_mmc_device(mmc_dev_num);
94 printf("No SD/MMC/eMMC card found\n");
98 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
104 cnt = 1; /* One 512 bytes block */
106 for (i = 0; i < MAX_FWENV_ADDR; i++)
107 if (fwenv_addr[i] != -1) {
108 blk = fwenv_addr[i] / 512;
109 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
110 flush_cache((ulong) addr, 512);
118 #if (FWENV_TYPE == FWENV_SPI_FLASH)
120 static struct spi_flash *flash;
121 static char smac[4][18];
123 int set_spi_arc_product(int argc, char *const argv[])
127 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
128 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
130 printf("Failed to initialize SPI flash at %u:%u\n",
131 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
135 /* Save factory defaults */
136 for (i = 0; i < MAX_FWENV_ADDR; i++)
137 if (fwenv_addr[i] != -1)
139 (flash, fwenv_addr[i], sizeof(smac), smac))
140 printf("%s: %s [%d]\n", __func__, mystrerr, i);
149 static int read_spi_arc_info(void)
153 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
154 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
156 printf("Failed to initialize SPI flash at %u:%u\n",
157 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
160 for (i = 0; i < MAX_FWENV_ADDR; i++)
161 if (fwenv_addr[i] != -1)
163 (flash, fwenv_addr[i], sizeof(smac), smac))
169 #if (FWENV_TYPE == FWENV_NOR_FLASH)
171 static char smac[4][18];
173 int set_nor_arc_product(int argc, char *const argv[])
177 /* Save factory defaults */
178 for (i = 0; i < MAX_FWENV_ADDR; i++)
179 if (fwenv_addr[i] != -1) {
180 ulong fwenv_end = fwenv_addr[i] + 4;
182 flash_sect_roundb(&fwenv_end);
183 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
185 ((char *)smac, fwenv_addr[i], sizeof(smac)))
186 printf("%s: %s [%d]\n", __func__, mystrerr, i);
189 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
197 static int read_nor_arc_info(void)
201 for (i = 0; i < MAX_FWENV_ADDR; i++)
202 if (fwenv_addr[i] != -1) {
203 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
211 int set_arc_product(int argc, char *const argv[])
216 /* Check serial number */
217 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
221 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
224 strcpy(smac[0], argv[1]);
225 strcpy(smac[1], argv[2]);
226 strcpy(smac[2], argv[3]);
227 strcpy(smac[3], argv[4]);
229 #if (FWENV_TYPE == FWENV_NOR_FLASH)
230 return set_nor_arc_product(argc, argv);
232 #if (FWENV_TYPE == FWENV_SPI_FLASH)
233 return set_spi_arc_product(argc, argv);
235 #if (FWENV_TYPE == FWENV_MMC)
236 return set_mmc_arc_product(argc, argv);
241 static int read_arc_info(void)
243 #if (FWENV_TYPE == FWENV_NOR_FLASH)
244 return read_nor_arc_info();
246 #if (FWENV_TYPE == FWENV_SPI_FLASH)
247 return read_spi_arc_info();
249 #if (FWENV_TYPE == FWENV_MMC)
250 return read_mmc_arc_info();
255 static int do_get_arc_info(void)
257 int l = read_arc_info();
258 char *oldserial = env_get("SERIAL");
259 char *oldversion = env_get("VERSION");
261 if (oldversion != NULL)
262 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
266 printf("%s: failed to read factory info\n", __func__);
270 printf("\rSERIAL: ");
271 if (smac[0][0] == EMPY_CHAR) {
272 printf("<not found>\n");
274 printf("%s\n", smac[0]);
275 env_set("SERIAL", smac[0]);
278 if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
279 env_set("ethaddr", NULL);
280 env_set("eth1addr", NULL);
281 env_set("eth2addr", NULL);
286 if (smac[1][0] == EMPY_CHAR) {
287 printf("<not found>\n");
289 char *ret = env_get("ethaddr");
292 env_set("ethaddr", smac[1]);
293 printf("%s\n", smac[1]);
294 } else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
295 env_set("ethaddr", smac[1]);
296 printf("%s (factory)\n", smac[1]);
302 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
303 env_set("eth1addr", NULL);
304 env_set("eth2addr", NULL);
309 if (smac[2][0] == EMPY_CHAR) {
310 printf("<not found>\n");
312 char *ret = env_get("eth1addr");
315 env_set("ethaddr", smac[2]);
316 printf("%s\n", smac[2]);
317 } else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
318 env_set("eth1addr", smac[2]);
319 printf("%s (factory)\n", smac[2]);
325 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
326 env_set("eth2addr", NULL);
331 if (smac[3][0] == EMPY_CHAR) {
332 printf("<not found>\n");
334 char *ret = env_get("eth2addr");
337 env_set("ethaddr", smac[3]);
338 printf("%s\n", smac[3]);
339 } else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
340 env_set("eth2addr", smac[3]);
341 printf("%s (factory)\n", smac[3]);
347 if (oldserial == NULL || oldversion == NULL) {
348 if (oldversion == NULL)
349 env_set("VERSION", U_BOOT_VERSION);
356 static int init_fwenv(void)
360 fwenv_addr[0] = FWENV_ADDR1;
361 fwenv_addr[1] = FWENV_ADDR2;
362 fwenv_addr[2] = FWENV_ADDR3;
363 fwenv_addr[3] = FWENV_ADDR4;
365 for (i = 0; i < MAX_FWENV_ADDR; i++)
366 if (fwenv_addr[i] != -1)
369 printf("%s: No firmfare info storage address is defined\n",
374 void get_arc_info(void)
380 static int do_arc_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
393 if (strcmp(cmd, "product") == 0)
394 ret = set_arc_product(argc, argv);
395 else if (strcmp(cmd, "info") == 0)
396 ret = do_get_arc_info();
399 return CMD_RET_USAGE;
404 U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
405 "Arcturus product command sub-system",
406 "product serial hwaddr0 hwaddr1 hwaddr2 - save Arcturus factory env\n"
407 "info - show Arcturus factory env\n\n");