1 /* 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 40 static struct spi_flash *flash; 41 char smac[4][18]; 42 43 static 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 55 static 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 110 int 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]); 141 setenv("SERIAL", smac[3]); 142 } 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 { 152 char *ret = getenv("ethaddr"); 153 154 if (strcmp(ret, __stringify(CONFIG_ETHADDR)) == 0) { 155 setenv("ethaddr", smac[2]); 156 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) { 163 setenv("eth1addr", smac[2]); 164 setenv("eth2addr", smac[2]); 165 return 0; 166 } 167 168 printf("HWADDR1:"); 169 if (smac[1][0] == 0xFF) { 170 printf("\t<not found>\n"); 171 } else { 172 char *ret = getenv("eth1addr"); 173 174 if (strcmp(ret, __stringify(CONFIG_ETH1ADDR)) == 0) { 175 setenv("eth1addr", smac[1]); 176 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) { 183 setenv("eth2addr", smac[1]); 184 return 0; 185 } 186 187 printf("HWADDR2:"); 188 if (smac[0][0] == 0xFF) { 189 printf("\t<not found>\n"); 190 } else { 191 char *ret = getenv("eth2addr"); 192 193 if (strcmp(ret, __stringify(CONFIG_ETH2ADDR)) == 0) { 194 setenv("eth2addr", smac[0]); 195 printf("\t%s (factory)\n", smac[0]); 196 } else { 197 printf("\t%s\n", ret); 198 } 199 } 200 201 return 0; 202 } 203 204 static 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 } 221 done: 222 if (ret == -1) 223 return CMD_RET_USAGE; 224 225 return ret; 226 } 227 228 U_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"); 232