blob: 0d3ac88fffea84975cd98428f75999f534ad7207 [file] [log] [blame]
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -04001/*
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
40static struct spi_flash *flash;
41char smac[4][18];
42
43static 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
55static 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
110int 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]);
Simon Glass6a38e412017-08-03 12:22:09 -0600141 env_set("SERIAL", smac[3]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400142 }
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 {
Simon Glass64b723f2017-08-03 12:22:12 -0600152 char *ret = env_get("ethaddr");
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400153
154 if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
Simon Glass6a38e412017-08-03 12:22:09 -0600155 env_set("ethaddr", smac[2]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400156 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) {
Simon Glass6a38e412017-08-03 12:22:09 -0600163 env_set("eth1addr", smac[2]);
164 env_set("eth2addr", smac[2]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400165 return 0;
166 }
167
168 printf("HWADDR1:");
169 if (smac[1][0] == 0xFF) {
170 printf("\t<not found>\n");
171 } else {
Simon Glass64b723f2017-08-03 12:22:12 -0600172 char *ret = env_get("eth1addr");
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400173
174 if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
Simon Glass6a38e412017-08-03 12:22:09 -0600175 env_set("eth1addr", smac[1]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400176 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) {
Simon Glass6a38e412017-08-03 12:22:09 -0600183 env_set("eth2addr", smac[1]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400184 return 0;
185 }
186
187 printf("HWADDR2:");
188 if (smac[0][0] == 0xFF) {
189 printf("\t<not found>\n");
190 } else {
Simon Glass64b723f2017-08-03 12:22:12 -0600191 char *ret = env_get("eth2addr");
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400192
193 if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
Simon Glass6a38e412017-08-03 12:22:09 -0600194 env_set("eth2addr", smac[0]);
Oleksandr G Zhadan19ac6882015-04-29 16:57:39 -0400195 printf("\t%s (factory)\n", smac[0]);
196 } else {
197 printf("\t%s\n", ret);
198 }
199 }
200
201 return 0;
202}
203
204static 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 }
221done:
222 if (ret == -1)
223 return CMD_RET_USAGE;
224
225 return ret;
226}
227
228U_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");