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.
15 #include <spi_flash.h>
18 #include <environment.h>
21 static ulong fwenv_addr[MAX_FWENV_ADDR];
22 const char mystrerr[] = "ERROR: Failed to save factory info";
24 static int ishwaddr(char *hwaddr)
26 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
27 if (hwaddr[2] == ':' &&
36 #if (FWENV_TYPE == FWENV_MMC)
38 static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
40 int set_mmc_arc_product(int argc, char *const argv[])
46 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
48 mmc = find_mmc_device(mmc_dev_num);
50 printf("No SD/MMC/eMMC card found\n");
54 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
58 if (mmc_getwp(mmc) == 1) {
59 printf("Error: card is write protected!\n");
60 return CMD_RET_FAILURE;
63 /* Save factory defaults */
65 cnt = 1; /* One 512 bytes block */
67 for (i = 0; i < MAX_FWENV_ADDR; i++)
68 if (fwenv_addr[i] != -1) {
69 blk = fwenv_addr[i] / 512;
70 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
72 printf("%s: %s [%d]\n", __func__, mystrerr, i);
82 static int read_mmc_arc_info(void)
88 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
90 mmc = find_mmc_device(mmc_dev_num);
92 printf("No SD/MMC/eMMC card found\n");
96 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
102 cnt = 1; /* One 512 bytes block */
104 for (i = 0; i < MAX_FWENV_ADDR; i++)
105 if (fwenv_addr[i] != -1) {
106 blk = fwenv_addr[i] / 512;
107 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
108 flush_cache((ulong) addr, 512);
116 #if (FWENV_TYPE == FWENV_SPI_FLASH)
118 static struct spi_flash *flash;
119 static char smac[4][18];
121 int set_spi_arc_product(int argc, char *const argv[])
125 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
126 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
128 printf("Failed to initialize SPI flash at %u:%u\n",
129 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
133 /* Save factory defaults */
134 for (i = 0; i < MAX_FWENV_ADDR; i++)
135 if (fwenv_addr[i] != -1)
137 (flash, fwenv_addr[i], sizeof(smac), smac))
138 printf("%s: %s [%d]\n", __func__, mystrerr, i);
147 static int read_spi_arc_info(void)
151 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
152 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
154 printf("Failed to initialize SPI flash at %u:%u\n",
155 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
158 for (i = 0; i < MAX_FWENV_ADDR; i++)
159 if (fwenv_addr[i] != -1)
161 (flash, fwenv_addr[i], sizeof(smac), smac))
167 #if (FWENV_TYPE == FWENV_NOR_FLASH)
169 static char smac[4][18];
171 int set_nor_arc_product(int argc, char *const argv[])
175 /* Save factory defaults */
176 for (i = 0; i < MAX_FWENV_ADDR; i++)
177 if (fwenv_addr[i] != -1) {
178 ulong fwenv_end = fwenv_addr[i] + 4;
180 flash_sect_roundb(&fwenv_end);
181 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
183 ((char *)smac, fwenv_addr[i], sizeof(smac)))
184 printf("%s: %s [%d]\n", __func__, mystrerr, i);
187 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
195 static int read_nor_arc_info(void)
199 for (i = 0; i < MAX_FWENV_ADDR; i++)
200 if (fwenv_addr[i] != -1) {
201 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
209 int set_arc_product(int argc, char *const argv[])
214 /* Check serial number */
215 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
219 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
222 strcpy(smac[0], argv[1]);
223 strcpy(smac[1], argv[2]);
224 strcpy(smac[2], argv[3]);
225 strcpy(smac[3], argv[4]);
227 #if (FWENV_TYPE == FWENV_NOR_FLASH)
228 return set_nor_arc_product(argc, argv);
230 #if (FWENV_TYPE == FWENV_SPI_FLASH)
231 return set_spi_arc_product(argc, argv);
233 #if (FWENV_TYPE == FWENV_MMC)
234 return set_mmc_arc_product(argc, argv);
239 static int read_arc_info(void)
241 #if (FWENV_TYPE == FWENV_NOR_FLASH)
242 return read_nor_arc_info();
244 #if (FWENV_TYPE == FWENV_SPI_FLASH)
245 return read_spi_arc_info();
247 #if (FWENV_TYPE == FWENV_MMC)
248 return read_mmc_arc_info();
253 static int do_get_arc_info(void)
255 int l = read_arc_info();
256 char *oldserial = env_get("SERIAL");
257 char *oldversion = env_get("VERSION");
259 if (oldversion != NULL)
260 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
264 printf("%s: failed to read factory info\n", __func__);
268 printf("\rSERIAL: ");
269 if (smac[0][0] == EMPY_CHAR) {
270 printf("<not found>\n");
272 printf("%s\n", smac[0]);
273 env_set("SERIAL", smac[0]);
276 if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
277 env_set("ethaddr", NULL);
278 env_set("eth1addr", NULL);
279 env_set("eth2addr", NULL);
284 if (smac[1][0] == EMPY_CHAR) {
285 printf("<not found>\n");
287 char *ret = env_get("ethaddr");
290 env_set("ethaddr", smac[1]);
291 printf("%s\n", smac[1]);
292 } else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
293 env_set("ethaddr", smac[1]);
294 printf("%s (factory)\n", smac[1]);
300 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
301 env_set("eth1addr", NULL);
302 env_set("eth2addr", NULL);
307 if (smac[2][0] == EMPY_CHAR) {
308 printf("<not found>\n");
310 char *ret = env_get("eth1addr");
313 env_set("ethaddr", smac[2]);
314 printf("%s\n", smac[2]);
315 } else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
316 env_set("eth1addr", smac[2]);
317 printf("%s (factory)\n", smac[2]);
323 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
324 env_set("eth2addr", NULL);
329 if (smac[3][0] == EMPY_CHAR) {
330 printf("<not found>\n");
332 char *ret = env_get("eth2addr");
335 env_set("ethaddr", smac[3]);
336 printf("%s\n", smac[3]);
337 } else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
338 env_set("eth2addr", smac[3]);
339 printf("%s (factory)\n", smac[3]);
345 if (oldserial == NULL || oldversion == NULL) {
346 if (oldversion == NULL)
347 env_set("VERSION", U_BOOT_VERSION);
354 static int init_fwenv(void)
358 fwenv_addr[0] = FWENV_ADDR1;
359 fwenv_addr[1] = FWENV_ADDR2;
360 fwenv_addr[2] = FWENV_ADDR3;
361 fwenv_addr[3] = FWENV_ADDR4;
363 for (i = 0; i < MAX_FWENV_ADDR; i++)
364 if (fwenv_addr[i] != -1)
367 printf("%s: No firmfare info storage address is defined\n",
372 void get_arc_info(void)
378 static int do_arc_cmd(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
390 if (strcmp(cmd, "product") == 0)
391 ret = set_arc_product(argc, argv);
392 else if (strcmp(cmd, "info") == 0)
393 ret = do_get_arc_info();
396 return CMD_RET_USAGE;
401 U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
402 "Arcturus product command sub-system",
403 "product serial hwaddr0 hwaddr1 hwaddr2 - save Arcturus factory env\n"
404 "info - show Arcturus factory env\n\n");