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.
14 #include <spi_flash.h>
17 #include <environment.h>
20 static ulong fwenv_addr[MAX_FWENV_ADDR];
21 const char mystrerr[] = "ERROR: Failed to save factory info";
23 static int ishwaddr(char *hwaddr)
25 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
26 if (hwaddr[2] == ':' &&
35 #if (FWENV_TYPE == FWENV_MMC)
37 static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
39 int set_mmc_arc_product(int argc, char *const argv[])
45 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
47 mmc = find_mmc_device(mmc_dev_num);
49 printf("No SD/MMC/eMMC card found\n");
53 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
57 if (mmc_getwp(mmc) == 1) {
58 printf("Error: card is write protected!\n");
59 return CMD_RET_FAILURE;
62 /* Save factory defaults */
64 cnt = 1; /* One 512 bytes block */
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);
71 printf("%s: %s [%d]\n", __func__, mystrerr, i);
81 static int read_mmc_arc_info(void)
87 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
89 mmc = find_mmc_device(mmc_dev_num);
91 printf("No SD/MMC/eMMC card found\n");
95 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
101 cnt = 1; /* One 512 bytes block */
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);
115 #if (FWENV_TYPE == FWENV_SPI_FLASH)
117 static struct spi_flash *flash;
118 static char smac[4][18];
120 int set_spi_arc_product(int argc, char *const argv[])
124 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
125 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
127 printf("Failed to initialize SPI flash at %u:%u\n",
128 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
132 /* Save factory defaults */
133 for (i = 0; i < MAX_FWENV_ADDR; i++)
134 if (fwenv_addr[i] != -1)
136 (flash, fwenv_addr[i], sizeof(smac), smac))
137 printf("%s: %s [%d]\n", __func__, mystrerr, i);
146 static int read_spi_arc_info(void)
150 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
151 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
153 printf("Failed to initialize SPI flash at %u:%u\n",
154 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
157 for (i = 0; i < MAX_FWENV_ADDR; i++)
158 if (fwenv_addr[i] != -1)
160 (flash, fwenv_addr[i], sizeof(smac), smac))
166 #if (FWENV_TYPE == FWENV_NOR_FLASH)
168 static char smac[4][18];
170 int set_nor_arc_product(int argc, char *const argv[])
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;
179 flash_sect_roundb(&fwenv_end);
180 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
182 ((char *)smac, fwenv_addr[i], sizeof(smac)))
183 printf("%s: %s [%d]\n", __func__, mystrerr, i);
186 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
194 static int read_nor_arc_info(void)
198 for (i = 0; i < MAX_FWENV_ADDR; i++)
199 if (fwenv_addr[i] != -1) {
200 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
208 int set_arc_product(int argc, char *const argv[])
213 /* Check serial number */
214 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
218 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
221 strcpy(smac[0], argv[1]);
222 strcpy(smac[1], argv[2]);
223 strcpy(smac[2], argv[3]);
224 strcpy(smac[3], argv[4]);
226 #if (FWENV_TYPE == FWENV_NOR_FLASH)
227 return set_nor_arc_product(argc, argv);
229 #if (FWENV_TYPE == FWENV_SPI_FLASH)
230 return set_spi_arc_product(argc, argv);
232 #if (FWENV_TYPE == FWENV_MMC)
233 return set_mmc_arc_product(argc, argv);
238 static int read_arc_info(void)
240 #if (FWENV_TYPE == FWENV_NOR_FLASH)
241 return read_nor_arc_info();
243 #if (FWENV_TYPE == FWENV_SPI_FLASH)
244 return read_spi_arc_info();
246 #if (FWENV_TYPE == FWENV_MMC)
247 return read_mmc_arc_info();
252 static int do_get_arc_info(void)
254 int l = read_arc_info();
255 char *oldserial = env_get("SERIAL");
256 char *oldversion = env_get("VERSION");
258 if (oldversion != NULL)
259 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
263 printf("%s: failed to read factory info\n", __func__);
267 printf("\rSERIAL: ");
268 if (smac[0][0] == EMPY_CHAR) {
269 printf("<not found>\n");
271 printf("%s\n", smac[0]);
272 env_set("SERIAL", smac[0]);
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);
283 if (smac[1][0] == EMPY_CHAR) {
284 printf("<not found>\n");
286 char *ret = env_get("ethaddr");
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]);
299 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
300 env_set("eth1addr", NULL);
301 env_set("eth2addr", NULL);
306 if (smac[2][0] == EMPY_CHAR) {
307 printf("<not found>\n");
309 char *ret = env_get("eth1addr");
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]);
322 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
323 env_set("eth2addr", NULL);
328 if (smac[3][0] == EMPY_CHAR) {
329 printf("<not found>\n");
331 char *ret = env_get("eth2addr");
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]);
344 if (oldserial == NULL || oldversion == NULL) {
345 if (oldversion == NULL)
346 env_set("VERSION", U_BOOT_VERSION);
353 static int init_fwenv(void)
357 fwenv_addr[0] = FWENV_ADDR1;
358 fwenv_addr[1] = FWENV_ADDR2;
359 fwenv_addr[2] = FWENV_ADDR3;
360 fwenv_addr[3] = FWENV_ADDR4;
362 for (i = 0; i < MAX_FWENV_ADDR; i++)
363 if (fwenv_addr[i] != -1)
366 printf("%s: No firmfare info storage address is defined\n",
371 void get_arc_info(void)
377 static int do_arc_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
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();
395 return CMD_RET_USAGE;
400 U_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");