1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * See file CREDITS for list of people who contributed to this
4  * project.
5  *
6  * Copyright (C) 2013 Curt Brune <curt@cumulusnetworks.com>
7  * Copyright (C) 2014 Srideep <srideep_devireddy@dell.com>
8  * Copyright (C) 2013 Miles Tseng <miles_tseng@accton.com>
9  * Copyright (C) 2014,2016 david_yang <david_yang@accton.com>
10  */
11 
12 #include <common.h>
13 #include <command.h>
14 #include <dm.h>
15 #include <i2c.h>
16 #include <i2c_eeprom.h>
17 #include <env.h>
18 #include <init.h>
19 #include <net.h>
20 #include <asm/global_data.h>
21 #include <linux/ctype.h>
22 #include <u-boot/crc.h>
23 
24 #include "tlv_eeprom.h"
25 
26 DECLARE_GLOBAL_DATA_PTR;
27 
28 #define MAX_TLV_DEVICES	2
29 
30 /* File scope function prototypes */
31 static bool is_checksum_valid(u8 *eeprom);
32 static int read_eeprom(u8 *eeprom);
33 static void show_eeprom(u8 *eeprom);
34 static void decode_tlv(struct tlvinfo_tlv *tlv);
35 static void update_crc(u8 *eeprom);
36 static int prog_eeprom(u8 *eeprom);
37 static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index);
38 static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code);
39 static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval);
40 static int set_mac(char *buf, const char *string);
41 static int set_date(char *buf, const char *string);
42 static int set_bytes(char *buf, const char *string, int *converted_accum);
43 static void show_tlv_devices(void);
44 
45 /* Set to 1 if we've read EEPROM into memory */
46 static int has_been_read;
47 /* The EERPOM contents after being read into memory */
48 static u8 eeprom[TLV_INFO_MAX_LEN];
49 
50 static struct udevice *tlv_devices[MAX_TLV_DEVICES];
51 static unsigned int current_dev;
52 
53 #define to_header(p) ((struct tlvinfo_header *)p)
54 #define to_entry(p) ((struct tlvinfo_tlv *)p)
55 
56 #define HDR_SIZE sizeof(struct tlvinfo_header)
57 #define ENT_SIZE sizeof(struct tlvinfo_tlv)
58 
is_digit(char c)59 static inline bool is_digit(char c)
60 {
61 	return (c >= '0' && c <= '9');
62 }
63 
64 /**
65  *  is_valid_tlv
66  *
67  *  Perform basic sanity checks on a TLV field. The TLV is pointed to
68  *  by the parameter provided.
69  *      1. The type code is not reserved (0x00 or 0xFF)
70  */
is_valid_tlv(struct tlvinfo_tlv * tlv)71 static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv)
72 {
73 	return((tlv->type != 0x00) && (tlv->type != 0xFF));
74 }
75 
76 /**
77  *  is_hex
78  *
79  *  Tests if character is an ASCII hex digit
80  */
is_hex(char p)81 static inline u8 is_hex(char p)
82 {
83 	return (((p >= '0') && (p <= '9')) ||
84 		((p >= 'A') && (p <= 'F')) ||
85 		((p >= 'a') && (p <= 'f')));
86 }
87 
88 /**
89  *  is_checksum_valid
90  *
91  *  Validate the checksum in the provided TlvInfo EEPROM data. First,
92  *  verify that the TlvInfo header is valid, then make sure the last
93  *  TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
94  *  and compare it to the value stored in the EEPROM CRC-32 TLV.
95  */
is_checksum_valid(u8 * eeprom)96 static bool is_checksum_valid(u8 *eeprom)
97 {
98 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
99 	struct tlvinfo_tlv    *eeprom_crc;
100 	unsigned int       calc_crc;
101 	unsigned int       stored_crc;
102 
103 	// Is the eeprom header valid?
104 	if (!is_valid_tlvinfo_header(eeprom_hdr))
105 		return false;
106 
107 	// Is the last TLV a CRC?
108 	eeprom_crc = to_entry(&eeprom[HDR_SIZE +
109 		be16_to_cpu(eeprom_hdr->totallen) - (ENT_SIZE + 4)]);
110 	if (eeprom_crc->type != TLV_CODE_CRC_32 || eeprom_crc->length != 4)
111 		return false;
112 
113 	// Calculate the checksum
114 	calc_crc = crc32(0, (void *)eeprom,
115 			 HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4);
116 	stored_crc = (eeprom_crc->value[0] << 24) |
117 		(eeprom_crc->value[1] << 16) |
118 		(eeprom_crc->value[2] <<  8) |
119 		eeprom_crc->value[3];
120 	return calc_crc == stored_crc;
121 }
122 
123 /**
124  *  read_eeprom
125  *
126  *  Read the EEPROM into memory, if it hasn't already been read.
127  */
read_eeprom(u8 * eeprom)128 static int read_eeprom(u8 *eeprom)
129 {
130 	int ret;
131 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
132 	struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]);
133 
134 	if (has_been_read)
135 		return 0;
136 
137 	/* Read the header */
138 	ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, current_dev);
139 	/* If the header was successfully read, read the TLVs */
140 	if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr))
141 		ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE,
142 				      be16_to_cpu(eeprom_hdr->totallen),
143 				      current_dev);
144 
145 	// If the contents are invalid, start over with default contents
146 	if (!is_valid_tlvinfo_header(eeprom_hdr) ||
147 	    !is_checksum_valid(eeprom)) {
148 		strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
149 		eeprom_hdr->version = TLV_INFO_VERSION;
150 		eeprom_hdr->totallen = cpu_to_be16(0);
151 		update_crc(eeprom);
152 	}
153 
154 	has_been_read = 1;
155 
156 #ifdef DEBUG
157 	show_eeprom(eeprom);
158 #endif
159 
160 	return ret;
161 }
162 
163 /**
164  *  show_eeprom
165  *
166  *  Display the contents of the EEPROM
167  */
show_eeprom(u8 * eeprom)168 static void show_eeprom(u8 *eeprom)
169 {
170 	int tlv_end;
171 	int curr_tlv;
172 #ifdef DEBUG
173 	int i;
174 #endif
175 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
176 	struct tlvinfo_tlv    *eeprom_tlv;
177 
178 	if (!is_valid_tlvinfo_header(eeprom_hdr)) {
179 		printf("EEPROM does not contain data in a valid TlvInfo format.\n");
180 		return;
181 	}
182 
183 	printf("TLV: %u\n", current_dev);
184 	printf("TlvInfo Header:\n");
185 	printf("   Id String:    %s\n", eeprom_hdr->signature);
186 	printf("   Version:      %d\n", eeprom_hdr->version);
187 	printf("   Total Length: %d\n", be16_to_cpu(eeprom_hdr->totallen));
188 
189 	printf("TLV Name             Code Len Value\n");
190 	printf("-------------------- ---- --- -----\n");
191 	curr_tlv = HDR_SIZE;
192 	tlv_end  = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
193 	while (curr_tlv < tlv_end) {
194 		eeprom_tlv = to_entry(&eeprom[curr_tlv]);
195 		if (!is_valid_tlv(eeprom_tlv)) {
196 			printf("Invalid TLV field starting at EEPROM offset %d\n",
197 			       curr_tlv);
198 			return;
199 		}
200 		decode_tlv(eeprom_tlv);
201 		curr_tlv += ENT_SIZE + eeprom_tlv->length;
202 	}
203 
204 	printf("Checksum is %s.\n",
205 	       is_checksum_valid(eeprom) ? "valid" : "invalid");
206 
207 #ifdef DEBUG
208 	printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN);
209 	for (i = 0; i < TLV_INFO_MAX_LEN; i++) {
210 		if ((i % 16) == 0)
211 			printf("\n%02X: ", i);
212 		printf("%02X ", eeprom[i]);
213 	}
214 	printf("\n");
215 #endif
216 }
217 
218 /**
219  *  Struct for displaying the TLV codes and names.
220  */
221 struct tlv_code_desc {
222 	u8    m_code;
223 	char *m_name;
224 };
225 
226 /**
227  *  List of TLV codes and names.
228  */
229 static struct tlv_code_desc tlv_code_list[] = {
230 	{ TLV_CODE_PRODUCT_NAME,   "Product Name"},
231 	{ TLV_CODE_PART_NUMBER,    "Part Number"},
232 	{ TLV_CODE_SERIAL_NUMBER,  "Serial Number"},
233 	{ TLV_CODE_MAC_BASE,       "Base MAC Address"},
234 	{ TLV_CODE_MANUF_DATE,     "Manufacture Date"},
235 	{ TLV_CODE_DEVICE_VERSION, "Device Version"},
236 	{ TLV_CODE_LABEL_REVISION, "Label Revision"},
237 	{ TLV_CODE_PLATFORM_NAME,  "Platform Name"},
238 	{ TLV_CODE_ONIE_VERSION,   "ONIE Version"},
239 	{ TLV_CODE_MAC_SIZE,       "MAC Addresses"},
240 	{ TLV_CODE_MANUF_NAME,     "Manufacturer"},
241 	{ TLV_CODE_MANUF_COUNTRY,  "Country Code"},
242 	{ TLV_CODE_VENDOR_NAME,    "Vendor Name"},
243 	{ TLV_CODE_DIAG_VERSION,   "Diag Version"},
244 	{ TLV_CODE_SERVICE_TAG,    "Service Tag"},
245 	{ TLV_CODE_VENDOR_EXT,     "Vendor Extension"},
246 	{ TLV_CODE_CRC_32,         "CRC-32"},
247 };
248 
249 /**
250  *  Look up a TLV name by its type.
251  */
tlv_type2name(u8 type)252 static inline const char *tlv_type2name(u8 type)
253 {
254 	char *name = "Unknown";
255 	int   i;
256 
257 	for (i = 0; i < ARRAY_SIZE(tlv_code_list); i++) {
258 		if (tlv_code_list[i].m_code == type) {
259 			name = tlv_code_list[i].m_name;
260 			break;
261 		}
262 	}
263 
264 	return name;
265 }
266 
267 /*
268  *  decode_tlv
269  *
270  *  Print a string representing the contents of the TLV field. The format of
271  *  the string is:
272  *      1. The name of the field left justified in 20 characters
273  *      2. The type code in hex right justified in 5 characters
274  *      3. The length in decimal right justified in 4 characters
275  *      4. The value, left justified in however many characters it takes
276  *  The validity of EEPROM contents and the TLV field have been verified
277  *  prior to calling this function.
278  */
279 #define DECODE_NAME_MAX     20
280 
281 /*
282  * The max decode value is currently for the 'raw' type or the 'vendor
283  * extension' type, both of which have the same decode format.  The
284  * max decode string size is computed as follows:
285  *
286  *   strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
287  *
288  */
289 #define DECODE_VALUE_MAX    ((5 * TLV_VALUE_MAX_LEN) + 1)
290 
decode_tlv(struct tlvinfo_tlv * tlv)291 static void decode_tlv(struct tlvinfo_tlv *tlv)
292 {
293 	char name[DECODE_NAME_MAX];
294 	char value[DECODE_VALUE_MAX];
295 	int i;
296 
297 	strncpy(name, tlv_type2name(tlv->type), DECODE_NAME_MAX);
298 
299 	switch (tlv->type) {
300 	case TLV_CODE_PRODUCT_NAME:
301 	case TLV_CODE_PART_NUMBER:
302 	case TLV_CODE_SERIAL_NUMBER:
303 	case TLV_CODE_MANUF_DATE:
304 	case TLV_CODE_LABEL_REVISION:
305 	case TLV_CODE_PLATFORM_NAME:
306 	case TLV_CODE_ONIE_VERSION:
307 	case TLV_CODE_MANUF_NAME:
308 	case TLV_CODE_MANUF_COUNTRY:
309 	case TLV_CODE_VENDOR_NAME:
310 	case TLV_CODE_DIAG_VERSION:
311 	case TLV_CODE_SERVICE_TAG:
312 		memcpy(value, tlv->value, tlv->length);
313 		value[tlv->length] = 0;
314 		break;
315 	case TLV_CODE_MAC_BASE:
316 		sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X",
317 			tlv->value[0], tlv->value[1], tlv->value[2],
318 			tlv->value[3], tlv->value[4], tlv->value[5]);
319 		break;
320 	case TLV_CODE_DEVICE_VERSION:
321 		sprintf(value, "%u", tlv->value[0]);
322 		break;
323 	case TLV_CODE_MAC_SIZE:
324 		sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]);
325 		break;
326 	case TLV_CODE_VENDOR_EXT:
327 		value[0] = 0;
328 		for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length);
329 				i++) {
330 			sprintf(value, "%s 0x%02X", value, tlv->value[i]);
331 		}
332 		break;
333 	case TLV_CODE_CRC_32:
334 		sprintf(value, "0x%02X%02X%02X%02X",
335 			tlv->value[0], tlv->value[1],
336 			tlv->value[2], tlv->value[3]);
337 		break;
338 	default:
339 		value[0] = 0;
340 		for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length);
341 				i++) {
342 			sprintf(value, "%s 0x%02X", value, tlv->value[i]);
343 		}
344 		break;
345 	}
346 
347 	name[DECODE_NAME_MAX - 1] = 0;
348 	printf("%-20s 0x%02X %3d %s\n", name, tlv->type, tlv->length, value);
349 }
350 
351 /**
352  *  update_crc
353  *
354  *  This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then
355  *  one is added. This function should be called after each update to the
356  *  EEPROM structure, to make sure the CRC is always correct.
357  */
update_crc(u8 * eeprom)358 static void update_crc(u8 *eeprom)
359 {
360 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
361 	struct tlvinfo_tlv    *eeprom_crc;
362 	unsigned int      calc_crc;
363 	int               eeprom_index;
364 
365 	// Discover the CRC TLV
366 	if (!tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) {
367 		unsigned int totallen = be16_to_cpu(eeprom_hdr->totallen);
368 
369 		if ((totallen + ENT_SIZE + 4) > TLV_TOTAL_LEN_MAX)
370 			return;
371 		eeprom_index = HDR_SIZE + totallen;
372 		eeprom_hdr->totallen = cpu_to_be16(totallen + ENT_SIZE + 4);
373 	}
374 	eeprom_crc = to_entry(&eeprom[eeprom_index]);
375 	eeprom_crc->type = TLV_CODE_CRC_32;
376 	eeprom_crc->length = 4;
377 
378 	// Calculate the checksum
379 	calc_crc = crc32(0, (void *)eeprom,
380 			 HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4);
381 	eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF;
382 	eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF;
383 	eeprom_crc->value[2] = (calc_crc >>  8) & 0xFF;
384 	eeprom_crc->value[3] = (calc_crc >>  0) & 0xFF;
385 }
386 
387 /**
388  *  prog_eeprom
389  *
390  *  Write the EEPROM data from CPU memory to the hardware.
391  */
prog_eeprom(u8 * eeprom)392 static int prog_eeprom(u8 *eeprom)
393 {
394 	int ret = 0;
395 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
396 	int eeprom_len;
397 
398 	update_crc(eeprom);
399 
400 	eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
401 	ret = write_tlv_eeprom(eeprom, eeprom_len);
402 	if (ret) {
403 		printf("Programming failed.\n");
404 		return -1;
405 	}
406 
407 	printf("Programming passed.\n");
408 	return 0;
409 }
410 
411 /**
412  *  show_tlv_code_list - Display the list of TLV codes and names
413  */
show_tlv_code_list(void)414 void show_tlv_code_list(void)
415 {
416 	int i;
417 
418 	printf("TLV Code    TLV Name\n");
419 	printf("========    =================\n");
420 	for (i = 0; i < ARRAY_SIZE(tlv_code_list); i++) {
421 		printf("0x%02X        %s\n",
422 		       tlv_code_list[i].m_code,
423 		       tlv_code_list[i].m_name);
424 	}
425 }
426 
427 /**
428  *  do_tlv_eeprom
429  *
430  *  This function implements the tlv_eeprom command.
431  */
do_tlv_eeprom(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])432 int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
433 {
434 	char cmd;
435 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
436 
437 	// If no arguments, read the EERPOM and display its contents
438 	if (argc == 1) {
439 		read_eeprom(eeprom);
440 		show_eeprom(eeprom);
441 		return 0;
442 	}
443 
444 	// We only look at the first character to the command, so "read" and
445 	// "reset" will both be treated as "read".
446 	cmd = argv[1][0];
447 
448 	// Read the EEPROM contents
449 	if (cmd == 'r') {
450 		has_been_read = 0;
451 		if (!read_eeprom(eeprom))
452 			printf("EEPROM data loaded from device to memory.\n");
453 		return 0;
454 	}
455 
456 	// Subsequent commands require that the EEPROM has already been read.
457 	if (!has_been_read) {
458 		printf("Please read the EEPROM data first, using the 'tlv_eeprom read' command.\n");
459 		return 0;
460 	}
461 
462 	// Handle the commands that don't take parameters
463 	if (argc == 2) {
464 		switch (cmd) {
465 		case 'w':   /* write */
466 			prog_eeprom(eeprom);
467 			break;
468 		case 'e':   /* erase */
469 			strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING);
470 			eeprom_hdr->version = TLV_INFO_VERSION;
471 			eeprom_hdr->totallen = cpu_to_be16(0);
472 			update_crc(eeprom);
473 			printf("EEPROM data in memory reset.\n");
474 			break;
475 		case 'l':   /* list */
476 			show_tlv_code_list();
477 			break;
478 		case 'd':   /* dev */
479 			show_tlv_devices();
480 			break;
481 		default:
482 			cmd_usage(cmdtp);
483 			break;
484 		}
485 		return 0;
486 	}
487 
488 	// The set command takes one or two args.
489 	if (argc > 4) {
490 		cmd_usage(cmdtp);
491 		return 0;
492 	}
493 
494 	// Set command. If the TLV exists in the EEPROM, delete it. Then if
495 	// data was supplied for this TLV add the TLV with the new contents at
496 	// the end.
497 	if (cmd == 's') {
498 		int tcode;
499 
500 		tcode = simple_strtoul(argv[2], NULL, 0);
501 		tlvinfo_delete_tlv(eeprom, tcode);
502 		if (argc == 4)
503 			tlvinfo_add_tlv(eeprom, tcode, argv[3]);
504 	} else if (cmd == 'd') { /* 'dev' command */
505 		unsigned int devnum;
506 
507 		devnum = simple_strtoul(argv[2], NULL, 0);
508 		if (devnum > MAX_TLV_DEVICES || !tlv_devices[devnum]) {
509 			printf("Invalid device number\n");
510 			return 0;
511 		}
512 		current_dev = devnum;
513 		has_been_read = 0;
514 	} else {
515 		cmd_usage(cmdtp);
516 	}
517 
518 	return 0;
519 }
520 
521 /**
522  *  This macro defines the tlv_eeprom command line command.
523  */
524 U_BOOT_CMD(tlv_eeprom, 4, 1,  do_tlv_eeprom,
525 	   "Display and program the system EEPROM data block.",
526 	   "[read|write|set <type_code> <string_value>|erase|list]\n"
527 	   "tlv_eeprom\n"
528 	   "    - With no arguments display the current contents.\n"
529 	   "tlv_eeprom dev [dev]\n"
530 	   "    - List devices or set current EEPROM device.\n"
531 	   "tlv_eeprom read\n"
532 	   "    - Load EEPROM data from device to memory.\n"
533 	   "tlv_eeprom write\n"
534 	   "    - Write the EEPROM data to persistent storage.\n"
535 	   "tlv_eeprom set <type_code> <string_value>\n"
536 	   "    - Set a field to a value.\n"
537 	   "    - If no string_value, field is deleted.\n"
538 	   "    - Use 'tlv_eeprom write' to make changes permanent.\n"
539 	   "tlv_eeprom erase\n"
540 	   "    - Reset the in memory EEPROM data.\n"
541 	   "    - Use 'tlv_eeprom read' to refresh the in memory EEPROM data.\n"
542 	   "    - Use 'tlv_eeprom write' to make changes permanent.\n"
543 	   "tlv_eeprom list\n"
544 	   "    - List the understood TLV codes and names.\n"
545 	);
546 
547 /**
548  *  tlvinfo_find_tlv
549  *
550  *  This function finds the TLV with the supplied code in the EERPOM.
551  *  An offset from the beginning of the EEPROM is returned in the
552  *  eeprom_index parameter if the TLV is found.
553  */
tlvinfo_find_tlv(u8 * eeprom,u8 tcode,int * eeprom_index)554 static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index)
555 {
556 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
557 	struct tlvinfo_tlv    *eeprom_tlv;
558 	int eeprom_end;
559 
560 	// Search through the TLVs, looking for the first one which matches the
561 	// supplied type code.
562 	*eeprom_index = HDR_SIZE;
563 	eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
564 	while (*eeprom_index < eeprom_end) {
565 		eeprom_tlv = to_entry(&eeprom[*eeprom_index]);
566 		if (!is_valid_tlv(eeprom_tlv))
567 			return false;
568 		if (eeprom_tlv->type == tcode)
569 			return true;
570 		*eeprom_index += ENT_SIZE + eeprom_tlv->length;
571 	}
572 	return(false);
573 }
574 
575 /**
576  *  tlvinfo_delete_tlv
577  *
578  *  This function deletes the TLV with the specified type code from the
579  *  EEPROM.
580  */
tlvinfo_delete_tlv(u8 * eeprom,u8 code)581 static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code)
582 {
583 	int eeprom_index;
584 	int tlength;
585 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
586 	struct tlvinfo_tlv *eeprom_tlv;
587 
588 	// Find the TLV and then move all following TLVs "forward"
589 	if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) {
590 		eeprom_tlv = to_entry(&eeprom[eeprom_index]);
591 		tlength = ENT_SIZE + eeprom_tlv->length;
592 		memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength],
593 		       HDR_SIZE +
594 		       be16_to_cpu(eeprom_hdr->totallen) - eeprom_index -
595 		       tlength);
596 		eeprom_hdr->totallen =
597 			cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
598 				    tlength);
599 		update_crc(eeprom);
600 		return true;
601 	}
602 	return false;
603 }
604 
605 /**
606  *  tlvinfo_add_tlv
607  *
608  *  This function adds a TLV to the EEPROM, converting the value (a string) to
609  *  the format in which it will be stored in the EEPROM.
610  */
611 #define MAX_TLV_VALUE_LEN   256
tlvinfo_add_tlv(u8 * eeprom,int tcode,char * strval)612 static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval)
613 {
614 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
615 	struct tlvinfo_tlv *eeprom_tlv;
616 	int new_tlv_len = 0;
617 	u32 value;
618 	char data[MAX_TLV_VALUE_LEN];
619 	int eeprom_index;
620 
621 	// Encode each TLV type into the format to be stored in the EERPOM
622 	switch (tcode) {
623 	case TLV_CODE_PRODUCT_NAME:
624 	case TLV_CODE_PART_NUMBER:
625 	case TLV_CODE_SERIAL_NUMBER:
626 	case TLV_CODE_LABEL_REVISION:
627 	case TLV_CODE_PLATFORM_NAME:
628 	case TLV_CODE_ONIE_VERSION:
629 	case TLV_CODE_MANUF_NAME:
630 	case TLV_CODE_MANUF_COUNTRY:
631 	case TLV_CODE_VENDOR_NAME:
632 	case TLV_CODE_DIAG_VERSION:
633 	case TLV_CODE_SERVICE_TAG:
634 		strncpy(data, strval, MAX_TLV_VALUE_LEN);
635 		new_tlv_len = min_t(size_t, MAX_TLV_VALUE_LEN, strlen(strval));
636 		break;
637 	case TLV_CODE_DEVICE_VERSION:
638 		value = simple_strtoul(strval, NULL, 0);
639 		if (value >= 256) {
640 			printf("ERROR: Device version must be 255 or less. Value supplied: %u",
641 			       value);
642 			return false;
643 		}
644 		data[0] = value & 0xFF;
645 		new_tlv_len = 1;
646 		break;
647 	case TLV_CODE_MAC_SIZE:
648 		value = simple_strtoul(strval, NULL, 0);
649 		if (value >= 65536) {
650 			printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u",
651 			       value);
652 			return false;
653 		}
654 		data[0] = (value >> 8) & 0xFF;
655 		data[1] = value & 0xFF;
656 		new_tlv_len = 2;
657 		break;
658 	case TLV_CODE_MANUF_DATE:
659 		if (set_date(data, strval) != 0)
660 			return false;
661 		new_tlv_len = 19;
662 		break;
663 	case TLV_CODE_MAC_BASE:
664 		if (set_mac(data, strval) != 0)
665 			return false;
666 		new_tlv_len = 6;
667 		break;
668 	case TLV_CODE_CRC_32:
669 		printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n");
670 		return false;
671 	case TLV_CODE_VENDOR_EXT:
672 	default:
673 		if (set_bytes(data, strval, &new_tlv_len) != 0)
674 			return false;
675 		break;
676 	}
677 
678 	// Is there room for this TLV?
679 	if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) >
680 			TLV_TOTAL_LEN_MAX) {
681 		printf("ERROR: There is not enough room in the EERPOM to save data.\n");
682 		return false;
683 	}
684 
685 	// Add TLV at the end, overwriting CRC TLV if it exists
686 	if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index))
687 		eeprom_hdr->totallen =
688 			cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
689 					ENT_SIZE - 4);
690 	else
691 		eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
692 	eeprom_tlv = to_entry(&eeprom[eeprom_index]);
693 	eeprom_tlv->type = tcode;
694 	eeprom_tlv->length = new_tlv_len;
695 	memcpy(eeprom_tlv->value, data, new_tlv_len);
696 
697 	// Update the total length and calculate (add) a new CRC-32 TLV
698 	eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
699 			ENT_SIZE + new_tlv_len);
700 	update_crc(eeprom);
701 
702 	return true;
703 }
704 
705 /**
706  *  set_mac
707  *
708  *  Converts a string MAC address into a binary buffer.
709  *
710  *  This function takes a pointer to a MAC address string
711  *  (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number).
712  *  The string format is verified and then converted to binary and
713  *  stored in a buffer.
714  */
set_mac(char * buf,const char * string)715 static int set_mac(char *buf, const char *string)
716 {
717 	char *p = (char *)string;
718 	int   i;
719 	int   err = 0;
720 	char *end;
721 
722 	if (!p) {
723 		printf("ERROR: NULL mac addr string passed in.\n");
724 		return -1;
725 	}
726 
727 	if (strlen(p) != 17) {
728 		printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p));
729 		printf("ERROR: Bad MAC address format: %s\n", string);
730 		return -1;
731 	}
732 
733 	for (i = 0; i < 17; i++) {
734 		if ((i % 3) == 2) {
735 			if (p[i] != ':') {
736 				err++;
737 				printf("ERROR: mac: p[%i] != :, found: `%c'\n",
738 				       i, p[i]);
739 				break;
740 			}
741 			continue;
742 		} else if (!is_hex(p[i])) {
743 			err++;
744 			printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n",
745 			       i, p[i]);
746 			break;
747 		}
748 	}
749 
750 	if (err != 0) {
751 		printf("ERROR: Bad MAC address format: %s\n", string);
752 		return -1;
753 	}
754 
755 	/* Convert string to binary */
756 	for (i = 0, p = (char *)string; i < 6; i++) {
757 		buf[i] = p ? hextoul(p, &end) : 0;
758 		if (p)
759 			p = (*end) ? end + 1 : end;
760 	}
761 
762 	if (!is_valid_ethaddr((u8 *)buf)) {
763 		printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n");
764 		printf("ERROR: Bad MAC address format: %s\n", string);
765 		return -1;
766 	}
767 
768 	return 0;
769 }
770 
771 /**
772  *  set_date
773  *
774  *  Validates the format of the data string
775  *
776  *  This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss)
777  *  and validates that the format is correct. If so the string is copied
778  *  to the supplied buffer.
779  */
set_date(char * buf,const char * string)780 static int set_date(char *buf, const char *string)
781 {
782 	int i;
783 
784 	if (!string) {
785 		printf("ERROR: NULL date string passed in.\n");
786 		return -1;
787 	}
788 
789 	if (strlen(string) != 19) {
790 		printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string));
791 		printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
792 		       string);
793 		return -1;
794 	}
795 
796 	for (i = 0; string[i] != 0; i++) {
797 		switch (i) {
798 		case 2:
799 		case 5:
800 			if (string[i] != '/') {
801 				printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
802 				       string);
803 				return -1;
804 			}
805 			break;
806 		case 10:
807 			if (string[i] != ' ') {
808 				printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
809 				       string);
810 				return -1;
811 			}
812 			break;
813 		case 13:
814 		case 16:
815 			if (string[i] != ':') {
816 				printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
817 				       string);
818 				return -1;
819 			}
820 			break;
821 		default:
822 			if (!is_digit(string[i])) {
823 				printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
824 				       string);
825 				return -1;
826 			}
827 			break;
828 		}
829 	}
830 
831 	strcpy(buf, string);
832 	return 0;
833 }
834 
835 /**
836  *  set_bytes
837  *
838  *  Converts a space-separated string of decimal numbers into a
839  *  buffer of bytes.
840  *
841  *  This function takes a pointer to a space-separated string of decimal
842  *  numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers
843  *  and converts them to an array of bytes.
844  */
set_bytes(char * buf,const char * string,int * converted_accum)845 static int set_bytes(char *buf, const char *string, int *converted_accum)
846 {
847 	char *p = (char *)string;
848 	int   i;
849 	uint  byte;
850 
851 	if (!p) {
852 		printf("ERROR: NULL string passed in.\n");
853 		return -1;
854 	}
855 
856 	/* Convert string to bytes */
857 	for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0);
858 			i++) {
859 		while ((*p == ' ') || (*p == '\t') || (*p == ',') ||
860 		       (*p == ';')) {
861 			p++;
862 		}
863 		if (*p != 0) {
864 			if (!is_digit(*p)) {
865 				printf("ERROR: Non-digit found in byte string: (%s)\n",
866 				       string);
867 				return -1;
868 			}
869 			byte = simple_strtoul(p, &p, 0);
870 			if (byte >= 256) {
871 				printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n",
872 				       byte, string);
873 				return -1;
874 			}
875 			buf[i] = byte & 0xFF;
876 		}
877 	}
878 
879 	if (i == TLV_VALUE_MAX_LEN && (*p != 0)) {
880 		printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n",
881 		       TLV_VALUE_MAX_LEN, string);
882 		return -1;
883 	}
884 
885 	*converted_accum = i;
886 	return 0;
887 }
888 
show_tlv_devices(void)889 static void show_tlv_devices(void)
890 {
891 	unsigned int dev;
892 
893 	for (dev = 0; dev < MAX_TLV_DEVICES; dev++)
894 		if (tlv_devices[dev])
895 			printf("TLV: %u%s\n", dev,
896 			       (dev == current_dev) ? " (*)" : "");
897 }
898 
find_tlv_devices(struct udevice ** tlv_devices_p)899 static int find_tlv_devices(struct udevice **tlv_devices_p)
900 {
901 	int ret;
902 	int count_dev = 0;
903 	struct udevice *dev;
904 
905 	for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev);
906 			dev;
907 			ret = uclass_next_device_check(&dev)) {
908 		if (ret == 0)
909 			tlv_devices_p[count_dev++] = dev;
910 		if (count_dev >= MAX_TLV_DEVICES)
911 			break;
912 	}
913 
914 	return (count_dev == 0) ? -ENODEV : 0;
915 }
916 
find_tlv_device_by_index(int dev_num)917 static struct udevice *find_tlv_device_by_index(int dev_num)
918 {
919 	struct udevice *local_tlv_devices[MAX_TLV_DEVICES] = {};
920 	struct udevice **tlv_devices_p;
921 	int ret;
922 
923 	if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) {
924 		/* Assume BSS is initialized; use static data */
925 		if (tlv_devices[dev_num])
926 			return tlv_devices[dev_num];
927 		tlv_devices_p = tlv_devices;
928 	} else {
929 		tlv_devices_p = local_tlv_devices;
930 	}
931 
932 	ret = find_tlv_devices(tlv_devices_p);
933 	if (ret == 0 && tlv_devices_p[dev_num])
934 		return tlv_devices_p[dev_num];
935 
936 	return NULL;
937 }
938 
939 /**
940  * read_tlv_eeprom - read the hwinfo from i2c EEPROM
941  */
read_tlv_eeprom(void * eeprom,int offset,int len,int dev_num)942 int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num)
943 {
944 	struct udevice *dev;
945 
946 	if (dev_num >= MAX_TLV_DEVICES)
947 		return -EINVAL;
948 
949 	dev = find_tlv_device_by_index(dev_num);
950 	if (!dev)
951 		return -ENODEV;
952 
953 	return i2c_eeprom_read(dev, offset, eeprom, len);
954 }
955 
956 /**
957  * write_tlv_eeprom - write the hwinfo to i2c EEPROM
958  */
write_tlv_eeprom(void * eeprom,int len)959 int write_tlv_eeprom(void *eeprom, int len)
960 {
961 	if (!(gd->flags & GD_FLG_RELOC))
962 		return -ENODEV;
963 	if (!tlv_devices[current_dev])
964 		return -ENODEV;
965 
966 	return i2c_eeprom_write(tlv_devices[current_dev], 0, eeprom, len);
967 }
968 
read_tlvinfo_tlv_eeprom(void * eeprom,struct tlvinfo_header ** hdr,struct tlvinfo_tlv ** first_entry,int dev_num)969 int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr,
970 			    struct tlvinfo_tlv **first_entry, int dev_num)
971 {
972 	int ret;
973 	struct tlvinfo_header *tlv_hdr;
974 	struct tlvinfo_tlv *tlv_ent;
975 
976 	/* Read TLV header */
977 	ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num);
978 	if (ret < 0)
979 		return ret;
980 
981 	tlv_hdr = eeprom;
982 	if (!is_valid_tlvinfo_header(tlv_hdr))
983 		return -EINVAL;
984 
985 	/* Read TLV entries */
986 	tlv_ent = to_entry(&tlv_hdr[1]);
987 	ret = read_tlv_eeprom(tlv_ent, HDR_SIZE,
988 			      be16_to_cpu(tlv_hdr->totallen), dev_num);
989 	if (ret < 0)
990 		return ret;
991 	if (!is_checksum_valid(eeprom))
992 		return -EINVAL;
993 
994 	*hdr = tlv_hdr;
995 	*first_entry = tlv_ent;
996 
997 	return 0;
998 }
999 
1000 /**
1001  *  mac_read_from_eeprom
1002  *
1003  *  Read the MAC addresses from EEPROM
1004  *
1005  *  This function reads the MAC addresses from EEPROM and sets the
1006  *  appropriate environment variables for each one read.
1007  *
1008  *  The environment variables are only set if they haven't been set already.
1009  *  This ensures that any user-saved variables are never overwritten.
1010  *
1011  *  This function must be called after relocation.
1012  */
mac_read_from_eeprom(void)1013 int mac_read_from_eeprom(void)
1014 {
1015 	unsigned int i;
1016 	int eeprom_index;
1017 	struct tlvinfo_tlv *eeprom_tlv;
1018 	int maccount;
1019 	u8 macbase[6];
1020 	struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
1021 
1022 	puts("EEPROM: ");
1023 
1024 	if (read_eeprom(eeprom)) {
1025 		printf("Read failed.\n");
1026 		return -1;
1027 	}
1028 
1029 	maccount = 1;
1030 	if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) {
1031 		eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1032 		maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1];
1033 	}
1034 
1035 	memcpy(macbase, "\0\0\0\0\0\0", 6);
1036 	if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) {
1037 		eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1038 		memcpy(macbase, eeprom_tlv->value, 6);
1039 	}
1040 
1041 	for (i = 0; i < maccount; i++) {
1042 		if (is_valid_ethaddr(macbase)) {
1043 			char ethaddr[18];
1044 			char enetvar[11];
1045 
1046 			sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
1047 				macbase[0], macbase[1], macbase[2],
1048 				macbase[3], macbase[4], macbase[5]);
1049 			sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
1050 			/* Only initialize environment variables that are blank
1051 			 * (i.e. have not yet been set)
1052 			 */
1053 			if (!env_get(enetvar))
1054 				env_set(enetvar, ethaddr);
1055 
1056 			macbase[5]++;
1057 			if (macbase[5] == 0) {
1058 				macbase[4]++;
1059 				if (macbase[4] == 0) {
1060 					macbase[3]++;
1061 					if (macbase[3] == 0) {
1062 						macbase[0] = 0;
1063 						macbase[1] = 0;
1064 						macbase[2] = 0;
1065 					}
1066 				}
1067 			}
1068 		}
1069 	}
1070 
1071 	printf("%s v%u len=%u\n", eeprom_hdr->signature, eeprom_hdr->version,
1072 	       be16_to_cpu(eeprom_hdr->totallen));
1073 
1074 	return 0;
1075 }
1076 
1077 /**
1078  *  populate_serial_number - read the serial number from EEPROM
1079  *
1080  *  This function reads the serial number from the EEPROM and sets the
1081  *  appropriate environment variable.
1082  *
1083  *  The environment variable is only set if it has not been set
1084  *  already.  This ensures that any user-saved variables are never
1085  *  overwritten.
1086  *
1087  *  This function must be called after relocation.
1088  */
populate_serial_number(void)1089 int populate_serial_number(void)
1090 {
1091 	char serialstr[257];
1092 	int eeprom_index;
1093 	struct tlvinfo_tlv *eeprom_tlv;
1094 
1095 	if (env_get("serial#"))
1096 		return 0;
1097 
1098 	if (read_eeprom(eeprom)) {
1099 		printf("Read failed.\n");
1100 		return -1;
1101 	}
1102 
1103 	if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) {
1104 		eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1105 		memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length);
1106 		serialstr[eeprom_tlv->length] = 0;
1107 		env_set("serial#", serialstr);
1108 	}
1109 
1110 	return 0;
1111 }
1112