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>
22 #include <linux/stringify.h>
24 static ulong fwenv_addr[MAX_FWENV_ADDR];
25 const char mystrerr[] = "ERROR: Failed to save factory info";
27 static int ishwaddr(char *hwaddr)
29 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
30 if (hwaddr[2] == ':' &&
39 #if (FWENV_TYPE == FWENV_MMC)
41 static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
43 int set_mmc_arc_product(int argc, char *const argv[])
49 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
51 mmc = find_mmc_device(mmc_dev_num);
53 printf("No SD/MMC/eMMC card found\n");
57 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
61 if (mmc_getwp(mmc) == 1) {
62 printf("Error: card is write protected!\n");
63 return CMD_RET_FAILURE;
66 /* Save factory defaults */
68 cnt = 1; /* One 512 bytes block */
70 for (i = 0; i < MAX_FWENV_ADDR; i++)
71 if (fwenv_addr[i] != -1) {
72 blk = fwenv_addr[i] / 512;
73 n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
75 printf("%s: %s [%d]\n", __func__, mystrerr, i);
85 static int read_mmc_arc_info(void)
91 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
93 mmc = find_mmc_device(mmc_dev_num);
95 printf("No SD/MMC/eMMC card found\n");
99 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
105 cnt = 1; /* One 512 bytes block */
107 for (i = 0; i < MAX_FWENV_ADDR; i++)
108 if (fwenv_addr[i] != -1) {
109 blk = fwenv_addr[i] / 512;
110 n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
111 flush_cache((ulong) addr, 512);
119 #if (FWENV_TYPE == FWENV_SPI_FLASH)
121 static struct spi_flash *flash;
122 static char smac[4][18];
124 int set_spi_arc_product(int argc, char *const argv[])
128 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
129 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
131 printf("Failed to initialize SPI flash at %u:%u\n",
132 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
136 /* Save factory defaults */
137 for (i = 0; i < MAX_FWENV_ADDR; i++)
138 if (fwenv_addr[i] != -1)
140 (flash, fwenv_addr[i], sizeof(smac), smac))
141 printf("%s: %s [%d]\n", __func__, mystrerr, i);
150 static int read_spi_arc_info(void)
154 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
155 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
157 printf("Failed to initialize SPI flash at %u:%u\n",
158 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
161 for (i = 0; i < MAX_FWENV_ADDR; i++)
162 if (fwenv_addr[i] != -1)
164 (flash, fwenv_addr[i], sizeof(smac), smac))
170 #if (FWENV_TYPE == FWENV_NOR_FLASH)
172 static char smac[4][18];
174 int set_nor_arc_product(int argc, char *const argv[])
178 /* Save factory defaults */
179 for (i = 0; i < MAX_FWENV_ADDR; i++)
180 if (fwenv_addr[i] != -1) {
181 ulong fwenv_end = fwenv_addr[i] + 4;
183 flash_sect_roundb(&fwenv_end);
184 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
186 ((char *)smac, fwenv_addr[i], sizeof(smac)))
187 printf("%s: %s [%d]\n", __func__, mystrerr, i);
190 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
198 static int read_nor_arc_info(void)
202 for (i = 0; i < MAX_FWENV_ADDR; i++)
203 if (fwenv_addr[i] != -1) {
204 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
212 int set_arc_product(int argc, char *const argv[])
217 /* Check serial number */
218 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
222 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
225 strcpy(smac[0], argv[1]);
226 strcpy(smac[1], argv[2]);
227 strcpy(smac[2], argv[3]);
228 strcpy(smac[3], argv[4]);
230 #if (FWENV_TYPE == FWENV_NOR_FLASH)
231 return set_nor_arc_product(argc, argv);
233 #if (FWENV_TYPE == FWENV_SPI_FLASH)
234 return set_spi_arc_product(argc, argv);
236 #if (FWENV_TYPE == FWENV_MMC)
237 return set_mmc_arc_product(argc, argv);
242 static int read_arc_info(void)
244 #if (FWENV_TYPE == FWENV_NOR_FLASH)
245 return read_nor_arc_info();
247 #if (FWENV_TYPE == FWENV_SPI_FLASH)
248 return read_spi_arc_info();
250 #if (FWENV_TYPE == FWENV_MMC)
251 return read_mmc_arc_info();
256 static int do_get_arc_info(void)
258 int l = read_arc_info();
259 char *oldserial = env_get("SERIAL");
260 char *oldversion = env_get("VERSION");
262 if (oldversion != NULL)
263 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
267 printf("%s: failed to read factory info\n", __func__);
271 printf("\rSERIAL: ");
272 if (smac[0][0] == EMPY_CHAR) {
273 printf("<not found>\n");
275 printf("%s\n", smac[0]);
276 env_set("SERIAL", smac[0]);
279 if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
280 env_set("ethaddr", NULL);
281 env_set("eth1addr", NULL);
282 env_set("eth2addr", NULL);
287 if (smac[1][0] == EMPY_CHAR) {
288 printf("<not found>\n");
290 char *ret = env_get("ethaddr");
293 env_set("ethaddr", smac[1]);
294 printf("%s\n", smac[1]);
295 } else if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
296 env_set("ethaddr", smac[1]);
297 printf("%s (factory)\n", smac[1]);
303 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
304 env_set("eth1addr", NULL);
305 env_set("eth2addr", NULL);
310 if (smac[2][0] == EMPY_CHAR) {
311 printf("<not found>\n");
313 char *ret = env_get("eth1addr");
316 env_set("ethaddr", smac[2]);
317 printf("%s\n", smac[2]);
318 } else if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
319 env_set("eth1addr", smac[2]);
320 printf("%s (factory)\n", smac[2]);
326 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
327 env_set("eth2addr", NULL);
332 if (smac[3][0] == EMPY_CHAR) {
333 printf("<not found>\n");
335 char *ret = env_get("eth2addr");
338 env_set("ethaddr", smac[3]);
339 printf("%s\n", smac[3]);
340 } else if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
341 env_set("eth2addr", smac[3]);
342 printf("%s (factory)\n", smac[3]);
348 if (oldserial == NULL || oldversion == NULL) {
349 if (oldversion == NULL)
350 env_set("VERSION", U_BOOT_VERSION);
357 static int init_fwenv(void)
361 fwenv_addr[0] = FWENV_ADDR1;
362 fwenv_addr[1] = FWENV_ADDR2;
363 fwenv_addr[2] = FWENV_ADDR3;
364 fwenv_addr[3] = FWENV_ADDR4;
366 for (i = 0; i < MAX_FWENV_ADDR; i++)
367 if (fwenv_addr[i] != -1)
370 printf("%s: No firmfare info storage address is defined\n",
375 void get_arc_info(void)
381 static int do_arc_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
394 if (strcmp(cmd, "product") == 0)
395 ret = set_arc_product(argc, argv);
396 else if (strcmp(cmd, "info") == 0)
397 ret = do_get_arc_info();
400 return CMD_RET_USAGE;
405 U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
406 "Arcturus product command sub-system",
407 "product serial hwaddr0 hwaddr1 hwaddr2 - save Arcturus factory env\n"
408 "info - show Arcturus factory env\n\n");