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