]> Git Repo - J-u-boot.git/blame - board/Arcturus/ucp1020/cmd_arc.c
command: Remove the cmd_tbl_t typedef
[J-u-boot.git] / board / Arcturus / ucp1020 / cmd_arc.c
CommitLineData
4549e789 1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
8b0044ff
OZ
2/*
3 * Command for accessing Arcturus factory environment.
4 *
f51d7fc8
OZ
5 * Copyright 2013-2019 Arcturus Networks Inc.
6 * https://www.arcturusnetworks.com/products/
8b0044ff
OZ
7 * by Oleksandr G Zhadan et al.
8 *
8b0044ff
OZ
9 */
10
11#include <common.h>
09140113 12#include <command.h>
1eb69ae4 13#include <cpu_func.h>
8b0044ff 14#include <div64.h>
9fb625ce 15#include <env.h>
b79fdc76 16#include <flash.h>
8b0044ff
OZ
17#include <malloc.h>
18#include <spi_flash.h>
f51d7fc8
OZ
19#include <mmc.h>
20#include <version.h>
8b0044ff
OZ
21#include <asm/io.h>
22
f51d7fc8
OZ
23static ulong fwenv_addr[MAX_FWENV_ADDR];
24const char mystrerr[] = "ERROR: Failed to save factory info";
8b0044ff
OZ
25
26static int ishwaddr(char *hwaddr)
27{
28 if (strlen(hwaddr) == MAX_HWADDR_SIZE)
29 if (hwaddr[2] == ':' &&
30 hwaddr[5] == ':' &&
31 hwaddr[8] == ':' &&
32 hwaddr[11] == ':' &&
33 hwaddr[14] == ':')
34 return 0;
35 return -1;
36}
37
f51d7fc8
OZ
38#if (FWENV_TYPE == FWENV_MMC)
39
40static char smac[29][18] __attribute__ ((aligned(0x200))); /* 1 MMC block is 512 bytes */
41
42int set_mmc_arc_product(int argc, char *const argv[])
8b0044ff 43{
f51d7fc8
OZ
44 struct mmc *mmc;
45 u32 blk, cnt, n;
46 int i, err = 1;
47 void *addr;
48 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
49
50 mmc = find_mmc_device(mmc_dev_num);
51 if (!mmc) {
52 printf("No SD/MMC/eMMC card found\n");
53 return 0;
54 }
55 if (mmc_init(mmc)) {
56 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
57 mmc_dev_num);
58 return 0;
59 }
60 if (mmc_getwp(mmc) == 1) {
61 printf("Error: card is write protected!\n");
62 return CMD_RET_FAILURE;
63 }
8b0044ff 64
f51d7fc8
OZ
65 /* Save factory defaults */
66 addr = (void *)smac;
67 cnt = 1; /* One 512 bytes block */
68
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);
73 if (n != cnt)
74 printf("%s: %s [%d]\n", __func__, mystrerr, i);
75 else
76 err = 0;
77 }
78 if (err)
79 return -2;
8b0044ff 80
f51d7fc8
OZ
81 return err;
82}
8b0044ff 83
f51d7fc8
OZ
84static int read_mmc_arc_info(void)
85{
86 struct mmc *mmc;
87 u32 blk, cnt, n;
88 int i;
89 void *addr;
90 const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
91
92 mmc = find_mmc_device(mmc_dev_num);
93 if (!mmc) {
94 printf("No SD/MMC/eMMC card found\n");
95 return 0;
96 }
97 if (mmc_init(mmc)) {
98 printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
99 mmc_dev_num);
100 return 0;
101 }
8b0044ff 102
f51d7fc8
OZ
103 addr = (void *)smac;
104 cnt = 1; /* One 512 bytes block */
8b0044ff 105
f51d7fc8
OZ
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);
111 if (n == cnt)
112 return (i + 1);
113 }
114 return 0;
115}
116#endif
8b0044ff 117
f51d7fc8 118#if (FWENV_TYPE == FWENV_SPI_FLASH)
8b0044ff 119
f51d7fc8
OZ
120static struct spi_flash *flash;
121static char smac[4][18];
8b0044ff 122
f51d7fc8
OZ
123int set_spi_arc_product(int argc, char *const argv[])
124{
125 int i, err = 1;
8b0044ff 126
f51d7fc8
OZ
127 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
128 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
129 if (!flash) {
130 printf("Failed to initialize SPI flash at %u:%u\n",
131 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
132 return -1;
8b0044ff
OZ
133 }
134
f51d7fc8
OZ
135 /* Save factory defaults */
136 for (i = 0; i < MAX_FWENV_ADDR; i++)
137 if (fwenv_addr[i] != -1)
138 if (spi_flash_write
139 (flash, fwenv_addr[i], sizeof(smac), smac))
140 printf("%s: %s [%d]\n", __func__, mystrerr, i);
141 else
142 err = 0;
143 if (err)
8b0044ff 144 return -2;
8b0044ff 145
f51d7fc8 146 return err;
8b0044ff
OZ
147}
148
f51d7fc8 149static int read_spi_arc_info(void)
8b0044ff 150{
f51d7fc8 151 int i;
8b0044ff
OZ
152
153 flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
154 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
f51d7fc8
OZ
155 if (!flash) {
156 printf("Failed to initialize SPI flash at %u:%u\n",
157 CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS);
158 return 0;
159 }
160 for (i = 0; i < MAX_FWENV_ADDR; i++)
161 if (fwenv_addr[i] != -1)
162 if (!spi_flash_read
163 (flash, fwenv_addr[i], sizeof(smac), smac))
164 return (i + 1);
165 return 0;
166}
167#endif
168
169#if (FWENV_TYPE == FWENV_NOR_FLASH)
8b0044ff 170
f51d7fc8
OZ
171static char smac[4][18];
172
173int set_nor_arc_product(int argc, char *const argv[])
174{
175 int i, err = 1;
176
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;
181
182 flash_sect_roundb(&fwenv_end);
183 flash_sect_protect(0, fwenv_addr[i], fwenv_end);
184 if (flash_write
185 ((char *)smac, fwenv_addr[i], sizeof(smac)))
186 printf("%s: %s [%d]\n", __func__, mystrerr, i);
187 else
188 err = 0;
189 flash_sect_protect(1, fwenv_addr[i], fwenv_end);
8b0044ff 190 }
f51d7fc8
OZ
191 if (err)
192 return -2;
193
194 return err;
195}
196
197static int read_nor_arc_info(void)
198{
199 int i;
200
201 for (i = 0; i < MAX_FWENV_ADDR; i++)
202 if (fwenv_addr[i] != -1) {
203 memcpy(smac, (void *)fwenv_addr[i], sizeof(smac));
204 return (i + 1);
8b0044ff 205 }
f51d7fc8
OZ
206
207 return 0;
208}
209#endif
210
211int set_arc_product(int argc, char *const argv[])
212{
213 if (argc != 5)
214 return -1;
215
216 /* Check serial number */
217 if (strlen(argv[1]) != MAX_SERIAL_SIZE)
218 return -1;
219
220 /* Check HWaddrs */
221 if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
222 return -1;
223
224 strcpy(smac[0], argv[1]);
225 strcpy(smac[1], argv[2]);
226 strcpy(smac[2], argv[3]);
227 strcpy(smac[3], argv[4]);
228
229#if (FWENV_TYPE == FWENV_NOR_FLASH)
230 return set_nor_arc_product(argc, argv);
231#endif
232#if (FWENV_TYPE == FWENV_SPI_FLASH)
233 return set_spi_arc_product(argc, argv);
234#endif
235#if (FWENV_TYPE == FWENV_MMC)
236 return set_mmc_arc_product(argc, argv);
237#endif
238 return -2;
239}
240
241static int read_arc_info(void)
242{
243#if (FWENV_TYPE == FWENV_NOR_FLASH)
244 return read_nor_arc_info();
245#endif
246#if (FWENV_TYPE == FWENV_SPI_FLASH)
247 return read_spi_arc_info();
248#endif
249#if (FWENV_TYPE == FWENV_MMC)
250 return read_mmc_arc_info();
251#endif
252 return 0;
253}
254
255static int do_get_arc_info(void)
256{
257 int l = read_arc_info();
258 char *oldserial = env_get("SERIAL");
259 char *oldversion = env_get("VERSION");
260
261 if (oldversion != NULL)
262 if (strcmp(oldversion, U_BOOT_VERSION) != 0)
263 oldversion = NULL;
264
265 if (l == 0) {
266 printf("%s: failed to read factory info\n", __func__);
267 return -2;
8b0044ff
OZ
268 }
269
f51d7fc8
OZ
270 printf("\rSERIAL: ");
271 if (smac[0][0] == EMPY_CHAR) {
272 printf("<not found>\n");
273 } else {
274 printf("%s\n", smac[0]);
275 env_set("SERIAL", smac[0]);
276 }
8b0044ff 277
f51d7fc8
OZ
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);
282 goto done;
283 }
284
285 printf("HWADDR0: ");
286 if (smac[1][0] == EMPY_CHAR) {
287 printf("<not found>\n");
8b0044ff 288 } else {
00caae6d 289 char *ret = env_get("ethaddr");
8b0044ff 290
f51d7fc8
OZ
291 if (ret == NULL) {
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]);
8b0044ff 297 } else {
f51d7fc8 298 printf("%s\n", ret);
8b0044ff
OZ
299 }
300 }
301
f51d7fc8
OZ
302 if (strcmp(smac[2], "00:00:00:00:00:00") == 0) {
303 env_set("eth1addr", NULL);
304 env_set("eth2addr", NULL);
305 goto done;
8b0044ff
OZ
306 }
307
f51d7fc8
OZ
308 printf("HWADDR1: ");
309 if (smac[2][0] == EMPY_CHAR) {
310 printf("<not found>\n");
8b0044ff 311 } else {
00caae6d 312 char *ret = env_get("eth1addr");
8b0044ff 313
f51d7fc8
OZ
314 if (ret == NULL) {
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]);
8b0044ff 320 } else {
f51d7fc8 321 printf("%s\n", ret);
8b0044ff
OZ
322 }
323 }
324
f51d7fc8
OZ
325 if (strcmp(smac[3], "00:00:00:00:00:00") == 0) {
326 env_set("eth2addr", NULL);
327 goto done;
8b0044ff
OZ
328 }
329
f51d7fc8
OZ
330 printf("HWADDR2: ");
331 if (smac[3][0] == EMPY_CHAR) {
332 printf("<not found>\n");
8b0044ff 333 } else {
00caae6d 334 char *ret = env_get("eth2addr");
8b0044ff 335
f51d7fc8
OZ
336 if (ret == NULL) {
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]);
8b0044ff 342 } else {
f51d7fc8 343 printf("%s\n", ret);
8b0044ff
OZ
344 }
345 }
f51d7fc8
OZ
346done:
347 if (oldserial == NULL || oldversion == NULL) {
348 if (oldversion == NULL)
349 env_set("VERSION", U_BOOT_VERSION);
350 env_save();
351 }
8b0044ff
OZ
352
353 return 0;
354}
355
f51d7fc8
OZ
356static int init_fwenv(void)
357{
358 int i, ret = -1;
359
360 fwenv_addr[0] = FWENV_ADDR1;
361 fwenv_addr[1] = FWENV_ADDR2;
362 fwenv_addr[2] = FWENV_ADDR3;
363 fwenv_addr[3] = FWENV_ADDR4;
364
365 for (i = 0; i < MAX_FWENV_ADDR; i++)
366 if (fwenv_addr[i] != -1)
367 ret = 0;
368 if (ret)
369 printf("%s: No firmfare info storage address is defined\n",
370 __func__);
371 return ret;
372}
373
374void get_arc_info(void)
375{
376 if (!init_fwenv())
377 do_get_arc_info();
378}
379
09140113
SG
380static int do_arc_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
381 char *const argv[])
8b0044ff
OZ
382{
383 const char *cmd;
384 int ret = -1;
385
386 cmd = argv[1];
387 --argc;
388 ++argv;
389
f51d7fc8
OZ
390 if (init_fwenv())
391 return ret;
392
393 if (strcmp(cmd, "product") == 0)
8b0044ff 394 ret = set_arc_product(argc, argv);
f51d7fc8
OZ
395 else if (strcmp(cmd, "info") == 0)
396 ret = do_get_arc_info();
397
8b0044ff
OZ
398 if (ret == -1)
399 return CMD_RET_USAGE;
400
401 return ret;
402}
403
404U_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");
This page took 0.342059 seconds and 4 git commands to generate.