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