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