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