xref: /rk3399_rockchip-uboot/board/Arcturus/ucp1020/cmd_arc.c (revision 00caae6d47645e68d6e5277aceb69592b49381a6)
18b0044ffSOleksandr G Zhadan /*
28b0044ffSOleksandr G Zhadan  * Command for accessing Arcturus factory environment.
38b0044ffSOleksandr G Zhadan  *
48b0044ffSOleksandr G Zhadan  * Copyright 2013-2015 Arcturus Networks Inc.
58b0044ffSOleksandr G Zhadan  *           http://www.arcturusnetworks.com/products/ucp1020/
68b0044ffSOleksandr G Zhadan  *           by Oleksandr G Zhadan et al.
78b0044ffSOleksandr G Zhadan  *
88b0044ffSOleksandr G Zhadan  * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause
98b0044ffSOleksandr G Zhadan  *
108b0044ffSOleksandr G Zhadan  */
118b0044ffSOleksandr G Zhadan 
128b0044ffSOleksandr G Zhadan #include <common.h>
138b0044ffSOleksandr G Zhadan #include <div64.h>
148b0044ffSOleksandr G Zhadan #include <malloc.h>
158b0044ffSOleksandr G Zhadan #include <spi_flash.h>
168b0044ffSOleksandr G Zhadan 
178b0044ffSOleksandr G Zhadan #include <asm/io.h>
188b0044ffSOleksandr G Zhadan 
198b0044ffSOleksandr G Zhadan #ifndef CONFIG_SF_DEFAULT_SPEED
208b0044ffSOleksandr G Zhadan #   define CONFIG_SF_DEFAULT_SPEED	1000000
218b0044ffSOleksandr G Zhadan #endif
228b0044ffSOleksandr G Zhadan #ifndef CONFIG_SF_DEFAULT_MODE
238b0044ffSOleksandr G Zhadan #   define CONFIG_SF_DEFAULT_MODE	SPI_MODE0
248b0044ffSOleksandr G Zhadan #endif
258b0044ffSOleksandr G Zhadan #ifndef CONFIG_SF_DEFAULT_CS
268b0044ffSOleksandr G Zhadan #   define CONFIG_SF_DEFAULT_CS		0
278b0044ffSOleksandr G Zhadan #endif
288b0044ffSOleksandr G Zhadan #ifndef CONFIG_SF_DEFAULT_BUS
298b0044ffSOleksandr G Zhadan #   define CONFIG_SF_DEFAULT_BUS	0
308b0044ffSOleksandr G Zhadan #endif
318b0044ffSOleksandr G Zhadan 
328b0044ffSOleksandr G Zhadan #define MAX_SERIAL_SIZE 15
338b0044ffSOleksandr G Zhadan #define MAX_HWADDR_SIZE 17
348b0044ffSOleksandr G Zhadan 
358b0044ffSOleksandr G Zhadan #define FIRM_ADDR1 (0x200 - sizeof(smac))
368b0044ffSOleksandr G Zhadan #define FIRM_ADDR2 (0x400 - sizeof(smac))
378b0044ffSOleksandr G Zhadan #define FIRM_ADDR3 (CONFIG_ENV_SECT_SIZE + 0x200 - sizeof(smac))
388b0044ffSOleksandr G Zhadan #define FIRM_ADDR4 (CONFIG_ENV_SECT_SIZE + 0x400 - sizeof(smac))
398b0044ffSOleksandr G Zhadan 
408b0044ffSOleksandr G Zhadan static struct spi_flash *flash;
418b0044ffSOleksandr G Zhadan char smac[4][18];
428b0044ffSOleksandr G Zhadan 
ishwaddr(char * hwaddr)438b0044ffSOleksandr G Zhadan static int ishwaddr(char *hwaddr)
448b0044ffSOleksandr G Zhadan {
458b0044ffSOleksandr G Zhadan 	if (strlen(hwaddr) == MAX_HWADDR_SIZE)
468b0044ffSOleksandr G Zhadan 		if (hwaddr[2] == ':' &&
478b0044ffSOleksandr G Zhadan 		    hwaddr[5] == ':' &&
488b0044ffSOleksandr G Zhadan 		    hwaddr[8] == ':' &&
498b0044ffSOleksandr G Zhadan 		    hwaddr[11] == ':' &&
508b0044ffSOleksandr G Zhadan 		    hwaddr[14] == ':')
518b0044ffSOleksandr G Zhadan 			return 0;
528b0044ffSOleksandr G Zhadan 	return -1;
538b0044ffSOleksandr G Zhadan }
548b0044ffSOleksandr G Zhadan 
set_arc_product(int argc,char * const argv[])558b0044ffSOleksandr G Zhadan static int set_arc_product(int argc, char *const argv[])
568b0044ffSOleksandr G Zhadan {
578b0044ffSOleksandr G Zhadan 	int err = 0;
588b0044ffSOleksandr G Zhadan 	char *mystrerr = "ERROR: Failed to save factory info in spi location";
598b0044ffSOleksandr G Zhadan 
608b0044ffSOleksandr G Zhadan 	if (argc != 5)
618b0044ffSOleksandr G Zhadan 		return -1;
628b0044ffSOleksandr G Zhadan 
638b0044ffSOleksandr G Zhadan 	/* Check serial number */
648b0044ffSOleksandr G Zhadan 	if (strlen(argv[1]) != MAX_SERIAL_SIZE)
658b0044ffSOleksandr G Zhadan 		return -1;
668b0044ffSOleksandr G Zhadan 
678b0044ffSOleksandr G Zhadan 	/* Check HWaddrs */
688b0044ffSOleksandr G Zhadan 	if (ishwaddr(argv[2]) || ishwaddr(argv[3]) || ishwaddr(argv[4]))
698b0044ffSOleksandr G Zhadan 		return -1;
708b0044ffSOleksandr G Zhadan 
718b0044ffSOleksandr G Zhadan 	strcpy(smac[3], argv[1]);
728b0044ffSOleksandr G Zhadan 	strcpy(smac[2], argv[2]);
738b0044ffSOleksandr G Zhadan 	strcpy(smac[1], argv[3]);
748b0044ffSOleksandr G Zhadan 	strcpy(smac[0], argv[4]);
758b0044ffSOleksandr G Zhadan 
768b0044ffSOleksandr G Zhadan 	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
778b0044ffSOleksandr G Zhadan 				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
788b0044ffSOleksandr G Zhadan 
798b0044ffSOleksandr G Zhadan 	/*
808b0044ffSOleksandr G Zhadan 	 * Save factory defaults
818b0044ffSOleksandr G Zhadan 	 */
828b0044ffSOleksandr G Zhadan 
838b0044ffSOleksandr G Zhadan 	if (spi_flash_write(flash, FIRM_ADDR1, sizeof(smac), smac)) {
848b0044ffSOleksandr G Zhadan 		printf("%s: %s [1]\n", __func__, mystrerr);
858b0044ffSOleksandr G Zhadan 		err++;
868b0044ffSOleksandr G Zhadan 	}
878b0044ffSOleksandr G Zhadan 	if (spi_flash_write(flash, FIRM_ADDR2, sizeof(smac), smac)) {
888b0044ffSOleksandr G Zhadan 		printf("%s: %s [2]\n", __func__, mystrerr);
898b0044ffSOleksandr G Zhadan 		err++;
908b0044ffSOleksandr G Zhadan 	}
918b0044ffSOleksandr G Zhadan 
928b0044ffSOleksandr G Zhadan 	if (spi_flash_write(flash, FIRM_ADDR3, sizeof(smac), smac)) {
938b0044ffSOleksandr G Zhadan 		printf("%s: %s [3]\n", __func__, mystrerr);
948b0044ffSOleksandr G Zhadan 		err++;
958b0044ffSOleksandr G Zhadan 	}
968b0044ffSOleksandr G Zhadan 
978b0044ffSOleksandr G Zhadan 	if (spi_flash_write(flash, FIRM_ADDR4, sizeof(smac), smac)) {
988b0044ffSOleksandr G Zhadan 		printf("%s: %s [4]\n", __func__, mystrerr);
998b0044ffSOleksandr G Zhadan 		err++;
1008b0044ffSOleksandr G Zhadan 	}
1018b0044ffSOleksandr G Zhadan 
1028b0044ffSOleksandr G Zhadan 	if (err == 4) {
1038b0044ffSOleksandr G Zhadan 		printf("%s: %s [ALL]\n", __func__, mystrerr);
1048b0044ffSOleksandr G Zhadan 		return -2;
1058b0044ffSOleksandr G Zhadan 	}
1068b0044ffSOleksandr G Zhadan 
1078b0044ffSOleksandr G Zhadan 	return 0;
1088b0044ffSOleksandr G Zhadan }
1098b0044ffSOleksandr G Zhadan 
get_arc_info(void)1108b0044ffSOleksandr G Zhadan int get_arc_info(void)
1118b0044ffSOleksandr G Zhadan {
1128b0044ffSOleksandr G Zhadan 	int location = 1;
1138b0044ffSOleksandr G Zhadan 	char *myerr = "ERROR: Failed to read all 4 factory info spi locations";
1148b0044ffSOleksandr G Zhadan 
1158b0044ffSOleksandr G Zhadan 	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
1168b0044ffSOleksandr G Zhadan 				CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
1178b0044ffSOleksandr G Zhadan 
1188b0044ffSOleksandr G Zhadan 	if (spi_flash_read(flash, FIRM_ADDR1, sizeof(smac), smac)) {
1198b0044ffSOleksandr G Zhadan 		location++;
1208b0044ffSOleksandr G Zhadan 		if (spi_flash_read(flash, FIRM_ADDR2, sizeof(smac), smac)) {
1218b0044ffSOleksandr G Zhadan 			location++;
1228b0044ffSOleksandr G Zhadan 			if (spi_flash_read(flash, FIRM_ADDR3, sizeof(smac),
1238b0044ffSOleksandr G Zhadan 					   smac)) {
1248b0044ffSOleksandr G Zhadan 				location++;
1258b0044ffSOleksandr G Zhadan 				if (spi_flash_read(flash, FIRM_ADDR4,
1268b0044ffSOleksandr G Zhadan 						   sizeof(smac), smac)) {
1278b0044ffSOleksandr G Zhadan 					printf("%s: %s\n", __func__, myerr);
1288b0044ffSOleksandr G Zhadan 					return -2;
1298b0044ffSOleksandr G Zhadan 				}
1308b0044ffSOleksandr G Zhadan 			}
1318b0044ffSOleksandr G Zhadan 		}
1328b0044ffSOleksandr G Zhadan 	}
1338b0044ffSOleksandr G Zhadan 	if (smac[3][0] != 0) {
1348b0044ffSOleksandr G Zhadan 		if (location > 1)
1358b0044ffSOleksandr G Zhadan 			printf("Using region %d\n", location);
1368b0044ffSOleksandr G Zhadan 		printf("SERIAL: ");
1378b0044ffSOleksandr G Zhadan 		if (smac[3][0] == 0xFF) {
1388b0044ffSOleksandr G Zhadan 			printf("\t<not found>\n");
1398b0044ffSOleksandr G Zhadan 		} else {
1408b0044ffSOleksandr G Zhadan 			printf("\t%s\n", smac[3]);
141382bee57SSimon Glass 			env_set("SERIAL", smac[3]);
1428b0044ffSOleksandr G Zhadan 		}
1438b0044ffSOleksandr G Zhadan 	}
1448b0044ffSOleksandr G Zhadan 
1458b0044ffSOleksandr G Zhadan 	if (strcmp(smac[2], "00:00:00:00:00:00") == 0)
1468b0044ffSOleksandr G Zhadan 		return 0;
1478b0044ffSOleksandr G Zhadan 
1488b0044ffSOleksandr G Zhadan 	printf("HWADDR0:");
1498b0044ffSOleksandr G Zhadan 	if (smac[2][0] == 0xFF) {
1508b0044ffSOleksandr G Zhadan 		printf("\t<not found>\n");
1518b0044ffSOleksandr G Zhadan 	} else {
152*00caae6dSSimon Glass 		char *ret = env_get("ethaddr");
1538b0044ffSOleksandr G Zhadan 
1548b0044ffSOleksandr G Zhadan 		if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) {
155382bee57SSimon Glass 			env_set("ethaddr", smac[2]);
1568b0044ffSOleksandr G Zhadan 			printf("\t%s (factory)\n", smac[2]);
1578b0044ffSOleksandr G Zhadan 		} else {
1588b0044ffSOleksandr G Zhadan 			printf("\t%s\n", ret);
1598b0044ffSOleksandr G Zhadan 		}
1608b0044ffSOleksandr G Zhadan 	}
1618b0044ffSOleksandr G Zhadan 
1628b0044ffSOleksandr G Zhadan 	if (strcmp(smac[1], "00:00:00:00:00:00") == 0) {
163382bee57SSimon Glass 		env_set("eth1addr", smac[2]);
164382bee57SSimon Glass 		env_set("eth2addr", smac[2]);
1658b0044ffSOleksandr G Zhadan 		return 0;
1668b0044ffSOleksandr G Zhadan 	}
1678b0044ffSOleksandr G Zhadan 
1688b0044ffSOleksandr G Zhadan 	printf("HWADDR1:");
1698b0044ffSOleksandr G Zhadan 	if (smac[1][0] == 0xFF) {
1708b0044ffSOleksandr G Zhadan 		printf("\t<not found>\n");
1718b0044ffSOleksandr G Zhadan 	} else {
172*00caae6dSSimon Glass 		char *ret = env_get("eth1addr");
1738b0044ffSOleksandr G Zhadan 
1748b0044ffSOleksandr G Zhadan 		if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) {
175382bee57SSimon Glass 			env_set("eth1addr", smac[1]);
1768b0044ffSOleksandr G Zhadan 			printf("\t%s (factory)\n", smac[1]);
1778b0044ffSOleksandr G Zhadan 		} else {
1788b0044ffSOleksandr G Zhadan 			printf("\t%s\n", ret);
1798b0044ffSOleksandr G Zhadan 		}
1808b0044ffSOleksandr G Zhadan 	}
1818b0044ffSOleksandr G Zhadan 
1828b0044ffSOleksandr G Zhadan 	if (strcmp(smac[0], "00:00:00:00:00:00") == 0) {
183382bee57SSimon Glass 		env_set("eth2addr", smac[1]);
1848b0044ffSOleksandr G Zhadan 		return 0;
1858b0044ffSOleksandr G Zhadan 	}
1868b0044ffSOleksandr G Zhadan 
1878b0044ffSOleksandr G Zhadan 	printf("HWADDR2:");
1888b0044ffSOleksandr G Zhadan 	if (smac[0][0] == 0xFF) {
1898b0044ffSOleksandr G Zhadan 		printf("\t<not found>\n");
1908b0044ffSOleksandr G Zhadan 	} else {
191*00caae6dSSimon Glass 		char *ret = env_get("eth2addr");
1928b0044ffSOleksandr G Zhadan 
1938b0044ffSOleksandr G Zhadan 		if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) {
194382bee57SSimon Glass 			env_set("eth2addr", smac[0]);
1958b0044ffSOleksandr G Zhadan 			printf("\t%s (factory)\n", smac[0]);
1968b0044ffSOleksandr G Zhadan 		} else {
1978b0044ffSOleksandr G Zhadan 			printf("\t%s\n", ret);
1988b0044ffSOleksandr G Zhadan 		}
1998b0044ffSOleksandr G Zhadan 	}
2008b0044ffSOleksandr G Zhadan 
2018b0044ffSOleksandr G Zhadan 	return 0;
2028b0044ffSOleksandr G Zhadan }
2038b0044ffSOleksandr G Zhadan 
do_arc_cmd(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2048b0044ffSOleksandr G Zhadan static int do_arc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
2058b0044ffSOleksandr G Zhadan {
2068b0044ffSOleksandr G Zhadan 	const char *cmd;
2078b0044ffSOleksandr G Zhadan 	int ret = -1;
2088b0044ffSOleksandr G Zhadan 
2098b0044ffSOleksandr G Zhadan 	cmd = argv[1];
2108b0044ffSOleksandr G Zhadan 	--argc;
2118b0044ffSOleksandr G Zhadan 	++argv;
2128b0044ffSOleksandr G Zhadan 
2138b0044ffSOleksandr G Zhadan 	if (strcmp(cmd, "product") == 0) {
2148b0044ffSOleksandr G Zhadan 		ret = set_arc_product(argc, argv);
2158b0044ffSOleksandr G Zhadan 		goto done;
2168b0044ffSOleksandr G Zhadan 	}
2178b0044ffSOleksandr G Zhadan 	if (strcmp(cmd, "info") == 0) {
2188b0044ffSOleksandr G Zhadan 		ret = get_arc_info();
2198b0044ffSOleksandr G Zhadan 		goto done;
2208b0044ffSOleksandr G Zhadan 	}
2218b0044ffSOleksandr G Zhadan done:
2228b0044ffSOleksandr G Zhadan 	if (ret == -1)
2238b0044ffSOleksandr G Zhadan 		return CMD_RET_USAGE;
2248b0044ffSOleksandr G Zhadan 
2258b0044ffSOleksandr G Zhadan 	return ret;
2268b0044ffSOleksandr G Zhadan }
2278b0044ffSOleksandr G Zhadan 
2288b0044ffSOleksandr G Zhadan U_BOOT_CMD(arc, 6, 1, do_arc_cmd,
2298b0044ffSOleksandr G Zhadan 	   "Arcturus product command sub-system",
2308b0044ffSOleksandr G Zhadan 	   "product serial hwaddr0 hwaddr1 hwaddr2    - save Arcturus factory env\n"
2318b0044ffSOleksandr G Zhadan 	   "info                                      - show Arcturus factory env\n\n");
232