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