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