SPDX: Convert all of our multiple license tags to Linux Kernel style
[oweals/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-2015 Arcturus Networks Inc.
6  *           http://www.arcturusnetworks.com/products/ucp1020/
7  *           by Oleksandr G Zhadan et al.
8  *
9  */
10
11 #include <common.h>
12 #include <div64.h>
13 #include <malloc.h>
14 #include <spi_flash.h>
15
16 #include <asm/io.h>
17
18 #ifndef CONFIG_SF_DEFAULT_SPEED
19 #   define CONFIG_SF_DEFAULT_SPEED      1000000
20 #endif
21 #ifndef CONFIG_SF_DEFAULT_MODE
22 #   define CONFIG_SF_DEFAULT_MODE       SPI_MODE0
23 #endif
24 #ifndef CONFIG_SF_DEFAULT_CS
25 #   define CONFIG_SF_DEFAULT_CS         0
26 #endif
27 #ifndef CONFIG_SF_DEFAULT_BUS
28 #   define CONFIG_SF_DEFAULT_BUS        0
29 #endif
30
31 #define MAX_SERIAL_SIZE 15
32 #define MAX_HWADDR_SIZE 17
33
34 #define FIRM_ADDR1 (0x200 - sizeof(smac))
35 #define FIRM_ADDR2 (0x400 - sizeof(smac))
36 #define FIRM_ADDR3 (CONFIG_ENV_SECT_SIZE + 0x200 - sizeof(smac))
37 #define FIRM_ADDR4 (CONFIG_ENV_SECT_SIZE + 0x400 - sizeof(smac))
38
39 static struct spi_flash *flash;
40 char smac[4][18];
41
42 static int ishwaddr(char *hwaddr)
43 {
44         if (strlen(hwaddr) == MAX_HWADDR_SIZE)
45                 if (hwaddr[2] == ':' &&
46                     hwaddr[5] == ':' &&
47                     hwaddr[8] == ':' &&
48                     hwaddr[11] == ':' &&
49                     hwaddr[14] == ':')
50                         return 0;
51         return -1;
52 }
53
54 static int set_arc_product(int argc, char *const argv[])
55 {
56         int err = 0;
57         char *mystrerr = "ERROR: Failed to save factory info in spi location";
58
59         if (argc != 5)
60                 return -1;
61
62         /* Check serial number */
63         if (strlen(argv[1]) != MAX_SERIAL_SIZE)
64                 return -1;
65
66         /* Check HWaddrs */
67         if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
68                 return -1;
69
70         strcpy(smac[3], argv[1]);
71         strcpy(smac[2], argv[2]);
72         strcpy(smac[1], argv[3]);
73         strcpy(smac[0], argv[4]);
74
75         flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
76                                 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
77
78         /*
79          * Save factory defaults
80          */
81
82         if (spi_flash_write(flash, FIRM_ADDR1, sizeof(smac), smac)) {
83                 printf("%s: %s [1]\n", __func__, mystrerr);
84                 err++;
85         }
86         if (spi_flash_write(flash, FIRM_ADDR2, sizeof(smac), smac)) {
87                 printf("%s: %s [2]\n", __func__, mystrerr);
88                 err++;
89         }
90
91         if (spi_flash_write(flash, FIRM_ADDR3, sizeof(smac), smac)) {
92                 printf("%s: %s [3]\n", __func__, mystrerr);
93                 err++;
94         }
95
96         if (spi_flash_write(flash, FIRM_ADDR4, sizeof(smac), smac)) {
97                 printf("%s: %s [4]\n", __func__, mystrerr);
98                 err++;
99         }
100
101         if (err == 4) {
102                 printf("%s: %s [ALL]\n", __func__, mystrerr);
103                 return -2;
104         }
105
106         return 0;
107 }
108
109 int get_arc_info(void)
110 {
111         int location = 1;
112         char *myerr = "ERROR: Failed to read all 4 factory info spi locations";
113
114         flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
115                                 CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
116
117         if (spi_flash_read(flash, FIRM_ADDR1, sizeof(smac), smac)) {
118                 location++;
119                 if (spi_flash_read(flash, FIRM_ADDR2, sizeof(smac), smac)) {
120                         location++;
121                         if (spi_flash_read(flash, FIRM_ADDR3, sizeof(smac),
122                                            smac)) {
123                                 location++;
124                                 if (spi_flash_read(flash, FIRM_ADDR4,
125                                                    sizeof(smac), smac)) {
126                                         printf("%s: %s\n", __func__, myerr);
127                                         return -2;
128                                 }
129                         }
130                 }
131         }
132         if (smac[3][0] != 0) {
133                 if (location > 1)
134                         printf("Using region %d\n", location);
135                 printf("SERIAL: ");
136                 if (smac[3][0] == 0xFF) {
137                         printf("\t<not found>\n");
138                 } else {
139                         printf("\t%s\n", smac[3]);
140                         env_set("SERIAL", smac[3]);
141                 }
142         }
143
144         if (strcmp(smac[2], "00:00:00:00:00:00") == 0)
145                 return 0;
146
147         printf("HWADDR0:");
148         if (smac[2][0] == 0xFF) {
149                 printf("\t<not found>\n");
150         } else {
151                 char *ret = env_get("ethaddr");
152
153                 if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
154                         env_set("ethaddr", smac[2]);
155                         printf("\t%s (factory)\n", smac[2]);
156                 } else {
157                         printf("\t%s\n", ret);
158                 }
159         }
160
161         if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
162                 env_set("eth1addr", smac[2]);
163                 env_set("eth2addr", smac[2]);
164                 return 0;
165         }
166
167         printf("HWADDR1:");
168         if (smac[1][0] == 0xFF) {
169                 printf("\t<not found>\n");
170         } else {
171                 char *ret = env_get("eth1addr");
172
173                 if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
174                         env_set("eth1addr", smac[1]);
175                         printf("\t%s (factory)\n", smac[1]);
176                 } else {
177                         printf("\t%s\n", ret);
178                 }
179         }
180
181         if (strcmp(smac[0], "00:00:00:00:00:00") == 0) {
182                 env_set("eth2addr", smac[1]);
183                 return 0;
184         }
185
186         printf("HWADDR2:");
187         if (smac[0][0] == 0xFF) {
188                 printf("\t<not found>\n");
189         } else {
190                 char *ret = env_get("eth2addr");
191
192                 if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
193                         env_set("eth2addr", smac[0]);
194                         printf("\t%s (factory)\n", smac[0]);
195                 } else {
196                         printf("\t%s\n", ret);
197                 }
198         }
199
200         return 0;
201 }
202
203 static int do_arc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
204 {
205         const char *cmd;
206         int ret = -1;
207
208         cmd = argv[1];
209         --argc;
210         ++argv;
211
212         if (strcmp(cmd, "product") == 0) {
213                 ret = set_arc_product(argc, argv);
214                 goto done;
215         }
216         if (strcmp(cmd, "info") == 0) {
217                 ret = get_arc_info();
218                 goto done;
219         }
220 done:
221         if (ret == -1)
222                 return CMD_RET_USAGE;
223
224         return ret;
225 }
226
227 U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
228            "Arcturus product command sub-system",
229            "product serial hwaddr0 hwaddr1 hwaddr2    - save Arcturus factory env\n"
230            "info                                      - show Arcturus factory env\n\n");