1 // SPDX-License-Identifier: GPL-2.0+
3 * See file CREDITS for list of people who contributed to this
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>
16 #include <i2c_eeprom.h>
20 #include <linux/ctype.h>
21 #include <u-boot/crc.h>
23 #include "tlv_eeprom.h"
25 DECLARE_GLOBAL_DATA_PTR
;
27 #define MAX_TLV_DEVICES 2
29 /* File scope function prototypes */
30 static bool is_checksum_valid(u8
*eeprom
);
31 static int read_eeprom(u8
*eeprom
);
32 static void show_eeprom(u8
*eeprom
);
33 static void decode_tlv(struct tlvinfo_tlv
*tlv
);
34 static void update_crc(u8
*eeprom
);
35 static int prog_eeprom(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(void);
44 /* Set to 1 if we've read EEPROM into memory */
45 static int has_been_read
;
46 /* The EERPOM contents after being read into memory */
47 static u8 eeprom
[TLV_INFO_MAX_LEN
];
49 static struct udevice
*tlv_devices
[MAX_TLV_DEVICES
];
50 static unsigned int current_dev
;
52 #define to_header(p) ((struct tlvinfo_header *)p)
53 #define to_entry(p) ((struct tlvinfo_tlv *)p)
55 #define HDR_SIZE sizeof(struct tlvinfo_header)
56 #define ENT_SIZE sizeof(struct tlvinfo_tlv)
58 static inline bool is_digit(char c
)
60 return (c
>= '0' && c
<= '9');
66 * Perform basic sanity checks on a TLV field. The TLV is pointed to
67 * by the parameter provided.
68 * 1. The type code is not reserved (0x00 or 0xFF)
70 static inline bool is_valid_tlv(struct tlvinfo_tlv
*tlv
)
72 return((tlv
->type
!= 0x00) && (tlv
->type
!= 0xFF));
78 * Tests if character is an ASCII hex digit
80 static inline u8
is_hex(char p
)
82 return (((p
>= '0') && (p
<= '9')) ||
83 ((p
>= 'A') && (p
<= 'F')) ||
84 ((p
>= 'a') && (p
<= 'f')));
90 * Validate the checksum in the provided TlvInfo EEPROM data. First,
91 * verify that the TlvInfo header is valid, then make sure the last
92 * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
93 * and compare it to the value stored in the EEPROM CRC-32 TLV.
95 static bool is_checksum_valid(u8
*eeprom
)
97 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
98 struct tlvinfo_tlv
*eeprom_crc
;
99 unsigned int calc_crc
;
100 unsigned int stored_crc
;
102 // Is the eeprom header valid?
103 if (!is_valid_tlvinfo_header(eeprom_hdr
))
106 // Is the last TLV a CRC?
107 eeprom_crc
= to_entry(&eeprom
[HDR_SIZE
+
108 be16_to_cpu(eeprom_hdr
->totallen
) - (ENT_SIZE
+ 4)]);
109 if (eeprom_crc
->type
!= TLV_CODE_CRC_32
|| eeprom_crc
->length
!= 4)
112 // Calculate the checksum
113 calc_crc
= crc32(0, (void *)eeprom
,
114 HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
) - 4);
115 stored_crc
= (eeprom_crc
->value
[0] << 24) |
116 (eeprom_crc
->value
[1] << 16) |
117 (eeprom_crc
->value
[2] << 8) |
118 eeprom_crc
->value
[3];
119 return calc_crc
== stored_crc
;
125 * Read the EEPROM into memory, if it hasn't already been read.
127 static int read_eeprom(u8
*eeprom
)
130 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
131 struct tlvinfo_tlv
*eeprom_tlv
= to_entry(&eeprom
[HDR_SIZE
]);
136 /* Read the header */
137 ret
= read_tlv_eeprom((void *)eeprom_hdr
, 0, HDR_SIZE
, current_dev
);
138 /* If the header was successfully read, read the TLVs */
139 if (ret
== 0 && is_valid_tlvinfo_header(eeprom_hdr
))
140 ret
= read_tlv_eeprom((void *)eeprom_tlv
, HDR_SIZE
,
141 be16_to_cpu(eeprom_hdr
->totallen
),
144 // If the contents are invalid, start over with default contents
145 if (!is_valid_tlvinfo_header(eeprom_hdr
) ||
146 !is_checksum_valid(eeprom
)) {
147 strcpy(eeprom_hdr
->signature
, TLV_INFO_ID_STRING
);
148 eeprom_hdr
->version
= TLV_INFO_VERSION
;
149 eeprom_hdr
->totallen
= cpu_to_be16(0);
165 * Display the contents of the EEPROM
167 static void show_eeprom(u8
*eeprom
)
171 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
172 struct tlvinfo_tlv
*eeprom_tlv
;
174 if (!is_valid_tlvinfo_header(eeprom_hdr
)) {
175 printf("EEPROM does not contain data in a valid TlvInfo format.\n");
179 printf("TLV: %u\n", current_dev
);
180 printf("TlvInfo Header:\n");
181 printf(" Id String: %s\n", eeprom_hdr
->signature
);
182 printf(" Version: %d\n", eeprom_hdr
->version
);
183 printf(" Total Length: %d\n", be16_to_cpu(eeprom_hdr
->totallen
));
185 printf("TLV Name Code Len Value\n");
186 printf("-------------------- ---- --- -----\n");
188 tlv_end
= HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
);
189 while (curr_tlv
< tlv_end
) {
190 eeprom_tlv
= to_entry(&eeprom
[curr_tlv
]);
191 if (!is_valid_tlv(eeprom_tlv
)) {
192 printf("Invalid TLV field starting at EEPROM offset %d\n",
196 decode_tlv(eeprom_tlv
);
197 curr_tlv
+= ENT_SIZE
+ eeprom_tlv
->length
;
200 printf("Checksum is %s.\n",
201 is_checksum_valid(eeprom
) ? "valid" : "invalid");
204 printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN
);
205 for (i
= 0; i
< TLV_INFO_MAX_LEN
; i
++) {
207 printf("\n%02X: ", i
);
208 printf("%02X ", eeprom
[i
]);
215 * Struct for displaying the TLV codes and names.
217 struct tlv_code_desc
{
223 * List of TLV codes and names.
225 static struct tlv_code_desc tlv_code_list
[] = {
226 { TLV_CODE_PRODUCT_NAME
, "Product Name"},
227 { TLV_CODE_PART_NUMBER
, "Part Number"},
228 { TLV_CODE_SERIAL_NUMBER
, "Serial Number"},
229 { TLV_CODE_MAC_BASE
, "Base MAC Address"},
230 { TLV_CODE_MANUF_DATE
, "Manufacture Date"},
231 { TLV_CODE_DEVICE_VERSION
, "Device Version"},
232 { TLV_CODE_LABEL_REVISION
, "Label Revision"},
233 { TLV_CODE_PLATFORM_NAME
, "Platform Name"},
234 { TLV_CODE_ONIE_VERSION
, "ONIE Version"},
235 { TLV_CODE_MAC_SIZE
, "MAC Addresses"},
236 { TLV_CODE_MANUF_NAME
, "Manufacturer"},
237 { TLV_CODE_MANUF_COUNTRY
, "Country Code"},
238 { TLV_CODE_VENDOR_NAME
, "Vendor Name"},
239 { TLV_CODE_DIAG_VERSION
, "Diag Version"},
240 { TLV_CODE_SERVICE_TAG
, "Service Tag"},
241 { TLV_CODE_VENDOR_EXT
, "Vendor Extension"},
242 { TLV_CODE_CRC_32
, "CRC-32"},
246 * Look up a TLV name by its type.
248 static inline const char *tlv_type2name(u8 type
)
250 char *name
= "Unknown";
253 for (i
= 0; i
< ARRAY_SIZE(tlv_code_list
); i
++) {
254 if (tlv_code_list
[i
].m_code
== type
) {
255 name
= tlv_code_list
[i
].m_name
;
266 * Print a string representing the contents of the TLV field. The format of
268 * 1. The name of the field left justified in 20 characters
269 * 2. The type code in hex right justified in 5 characters
270 * 3. The length in decimal right justified in 4 characters
271 * 4. The value, left justified in however many characters it takes
272 * The validity of EEPROM contents and the TLV field have been verified
273 * prior to calling this function.
275 #define DECODE_NAME_MAX 20
278 * The max decode value is currently for the 'raw' type or the 'vendor
279 * extension' type, both of which have the same decode format. The
280 * max decode string size is computed as follows:
282 * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
285 #define DECODE_VALUE_MAX ((5 * TLV_VALUE_MAX_LEN) + 1)
287 static void decode_tlv(struct tlvinfo_tlv
*tlv
)
289 char name
[DECODE_NAME_MAX
];
290 char value
[DECODE_VALUE_MAX
];
293 strncpy(name
, tlv_type2name(tlv
->type
), DECODE_NAME_MAX
);
296 case TLV_CODE_PRODUCT_NAME
:
297 case TLV_CODE_PART_NUMBER
:
298 case TLV_CODE_SERIAL_NUMBER
:
299 case TLV_CODE_MANUF_DATE
:
300 case TLV_CODE_LABEL_REVISION
:
301 case TLV_CODE_PLATFORM_NAME
:
302 case TLV_CODE_ONIE_VERSION
:
303 case TLV_CODE_MANUF_NAME
:
304 case TLV_CODE_MANUF_COUNTRY
:
305 case TLV_CODE_VENDOR_NAME
:
306 case TLV_CODE_DIAG_VERSION
:
307 case TLV_CODE_SERVICE_TAG
:
308 memcpy(value
, tlv
->value
, tlv
->length
);
309 value
[tlv
->length
] = 0;
311 case TLV_CODE_MAC_BASE
:
312 sprintf(value
, "%02X:%02X:%02X:%02X:%02X:%02X",
313 tlv
->value
[0], tlv
->value
[1], tlv
->value
[2],
314 tlv
->value
[3], tlv
->value
[4], tlv
->value
[5]);
316 case TLV_CODE_DEVICE_VERSION
:
317 sprintf(value
, "%u", tlv
->value
[0]);
319 case TLV_CODE_MAC_SIZE
:
320 sprintf(value
, "%u", (tlv
->value
[0] << 8) | tlv
->value
[1]);
322 case TLV_CODE_VENDOR_EXT
:
324 for (i
= 0; (i
< (DECODE_VALUE_MAX
/ 5)) && (i
< tlv
->length
);
326 sprintf(value
, "%s 0x%02X", value
, tlv
->value
[i
]);
329 case TLV_CODE_CRC_32
:
330 sprintf(value
, "0x%02X%02X%02X%02X",
331 tlv
->value
[0], tlv
->value
[1],
332 tlv
->value
[2], tlv
->value
[3]);
336 for (i
= 0; (i
< (DECODE_VALUE_MAX
/ 5)) && (i
< tlv
->length
);
338 sprintf(value
, "%s 0x%02X", value
, tlv
->value
[i
]);
343 name
[DECODE_NAME_MAX
- 1] = 0;
344 printf("%-20s 0x%02X %3d %s\n", name
, tlv
->type
, tlv
->length
, value
);
350 * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then
351 * one is added. This function should be called after each update to the
352 * EEPROM structure, to make sure the CRC is always correct.
354 static void update_crc(u8
*eeprom
)
356 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
357 struct tlvinfo_tlv
*eeprom_crc
;
358 unsigned int calc_crc
;
361 // Discover the CRC TLV
362 if (!tlvinfo_find_tlv(eeprom
, TLV_CODE_CRC_32
, &eeprom_index
)) {
363 unsigned int totallen
= be16_to_cpu(eeprom_hdr
->totallen
);
365 if ((totallen
+ ENT_SIZE
+ 4) > TLV_TOTAL_LEN_MAX
)
367 eeprom_index
= HDR_SIZE
+ totallen
;
368 eeprom_hdr
->totallen
= cpu_to_be16(totallen
+ ENT_SIZE
+ 4);
370 eeprom_crc
= to_entry(&eeprom
[eeprom_index
]);
371 eeprom_crc
->type
= TLV_CODE_CRC_32
;
372 eeprom_crc
->length
= 4;
374 // Calculate the checksum
375 calc_crc
= crc32(0, (void *)eeprom
,
376 HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
) - 4);
377 eeprom_crc
->value
[0] = (calc_crc
>> 24) & 0xFF;
378 eeprom_crc
->value
[1] = (calc_crc
>> 16) & 0xFF;
379 eeprom_crc
->value
[2] = (calc_crc
>> 8) & 0xFF;
380 eeprom_crc
->value
[3] = (calc_crc
>> 0) & 0xFF;
386 * Write the EEPROM data from CPU memory to the hardware.
388 static int prog_eeprom(u8
*eeprom
)
391 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
396 eeprom_len
= HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
);
397 ret
= write_tlv_eeprom(eeprom
, eeprom_len
);
399 printf("Programming failed.\n");
403 printf("Programming passed.\n");
408 * show_tlv_code_list - Display the list of TLV codes and names
410 void show_tlv_code_list(void)
414 printf("TLV Code TLV Name\n");
415 printf("======== =================\n");
416 for (i
= 0; i
< ARRAY_SIZE(tlv_code_list
); i
++) {
417 printf("0x%02X %s\n",
418 tlv_code_list
[i
].m_code
,
419 tlv_code_list
[i
].m_name
);
426 * This function implements the tlv_eeprom command.
428 int do_tlv_eeprom(struct cmd_tbl
*cmdtp
, int flag
, int argc
, char *const argv
[])
431 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
433 // If no arguments, read the EERPOM and display its contents
440 // We only look at the first character to the command, so "read" and
441 // "reset" will both be treated as "read".
444 // Read the EEPROM contents
447 if (!read_eeprom(eeprom
))
448 printf("EEPROM data loaded from device to memory.\n");
452 // Subsequent commands require that the EEPROM has already been read.
453 if (!has_been_read
) {
454 printf("Please read the EEPROM data first, using the 'tlv_eeprom read' command.\n");
458 // Handle the commands that don't take parameters
461 case 'w': /* write */
464 case 'e': /* erase */
465 strcpy(eeprom_hdr
->signature
, TLV_INFO_ID_STRING
);
466 eeprom_hdr
->version
= TLV_INFO_VERSION
;
467 eeprom_hdr
->totallen
= cpu_to_be16(0);
469 printf("EEPROM data in memory reset.\n");
472 show_tlv_code_list();
484 // The set command takes one or two args.
490 // Set command. If the TLV exists in the EEPROM, delete it. Then if
491 // data was supplied for this TLV add the TLV with the new contents at
496 tcode
= simple_strtoul(argv
[2], NULL
, 0);
497 tlvinfo_delete_tlv(eeprom
, tcode
);
499 tlvinfo_add_tlv(eeprom
, tcode
, argv
[3]);
500 } else if (cmd
== 'd') { /* 'dev' command */
503 devnum
= simple_strtoul(argv
[2], NULL
, 0);
504 if (devnum
> MAX_TLV_DEVICES
|| !tlv_devices
[devnum
]) {
505 printf("Invalid device number\n");
508 current_dev
= devnum
;
518 * This macro defines the tlv_eeprom command line command.
520 U_BOOT_CMD(tlv_eeprom
, 4, 1, do_tlv_eeprom
,
521 "Display and program the system EEPROM data block.",
522 "[read|write|set <type_code> <string_value>|erase|list]\n"
524 " - With no arguments display the current contents.\n"
525 "tlv_eeprom dev [dev]\n"
526 " - List devices or set current EEPROM device.\n"
528 " - Load EEPROM data from device to memory.\n"
530 " - Write the EEPROM data to persistent storage.\n"
531 "tlv_eeprom set <type_code> <string_value>\n"
532 " - Set a field to a value.\n"
533 " - If no string_value, field is deleted.\n"
534 " - Use 'tlv_eeprom write' to make changes permanent.\n"
536 " - Reset the in memory EEPROM data.\n"
537 " - Use 'tlv_eeprom read' to refresh the in memory EEPROM data.\n"
538 " - Use 'tlv_eeprom write' to make changes permanent.\n"
540 " - List the understood TLV codes and names.\n"
546 * This function finds the TLV with the supplied code in the EERPOM.
547 * An offset from the beginning of the EEPROM is returned in the
548 * eeprom_index parameter if the TLV is found.
550 static bool tlvinfo_find_tlv(u8
*eeprom
, u8 tcode
, int *eeprom_index
)
552 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
553 struct tlvinfo_tlv
*eeprom_tlv
;
556 // Search through the TLVs, looking for the first one which matches the
557 // supplied type code.
558 *eeprom_index
= HDR_SIZE
;
559 eeprom_end
= HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
);
560 while (*eeprom_index
< eeprom_end
) {
561 eeprom_tlv
= to_entry(&eeprom
[*eeprom_index
]);
562 if (!is_valid_tlv(eeprom_tlv
))
564 if (eeprom_tlv
->type
== tcode
)
566 *eeprom_index
+= ENT_SIZE
+ eeprom_tlv
->length
;
574 * This function deletes the TLV with the specified type code from the
577 static bool tlvinfo_delete_tlv(u8
*eeprom
, u8 code
)
581 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
582 struct tlvinfo_tlv
*eeprom_tlv
;
584 // Find the TLV and then move all following TLVs "forward"
585 if (tlvinfo_find_tlv(eeprom
, code
, &eeprom_index
)) {
586 eeprom_tlv
= to_entry(&eeprom
[eeprom_index
]);
587 tlength
= ENT_SIZE
+ eeprom_tlv
->length
;
588 memcpy(&eeprom
[eeprom_index
], &eeprom
[eeprom_index
+ tlength
],
590 be16_to_cpu(eeprom_hdr
->totallen
) - eeprom_index
-
592 eeprom_hdr
->totallen
=
593 cpu_to_be16(be16_to_cpu(eeprom_hdr
->totallen
) -
604 * This function adds a TLV to the EEPROM, converting the value (a string) to
605 * the format in which it will be stored in the EEPROM.
607 #define MAX_TLV_VALUE_LEN 256
608 static bool tlvinfo_add_tlv(u8
*eeprom
, int tcode
, char *strval
)
610 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
611 struct tlvinfo_tlv
*eeprom_tlv
;
614 char data
[MAX_TLV_VALUE_LEN
];
617 // Encode each TLV type into the format to be stored in the EERPOM
619 case TLV_CODE_PRODUCT_NAME
:
620 case TLV_CODE_PART_NUMBER
:
621 case TLV_CODE_SERIAL_NUMBER
:
622 case TLV_CODE_LABEL_REVISION
:
623 case TLV_CODE_PLATFORM_NAME
:
624 case TLV_CODE_ONIE_VERSION
:
625 case TLV_CODE_MANUF_NAME
:
626 case TLV_CODE_MANUF_COUNTRY
:
627 case TLV_CODE_VENDOR_NAME
:
628 case TLV_CODE_DIAG_VERSION
:
629 case TLV_CODE_SERVICE_TAG
:
630 strncpy(data
, strval
, MAX_TLV_VALUE_LEN
);
631 new_tlv_len
= min_t(size_t, MAX_TLV_VALUE_LEN
, strlen(strval
));
633 case TLV_CODE_DEVICE_VERSION
:
634 value
= simple_strtoul(strval
, NULL
, 0);
636 printf("ERROR: Device version must be 255 or less. Value supplied: %u",
640 data
[0] = value
& 0xFF;
643 case TLV_CODE_MAC_SIZE
:
644 value
= simple_strtoul(strval
, NULL
, 0);
645 if (value
>= 65536) {
646 printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u",
650 data
[0] = (value
>> 8) & 0xFF;
651 data
[1] = value
& 0xFF;
654 case TLV_CODE_MANUF_DATE
:
655 if (set_date(data
, strval
) != 0)
659 case TLV_CODE_MAC_BASE
:
660 if (set_mac(data
, strval
) != 0)
664 case TLV_CODE_CRC_32
:
665 printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n");
667 case TLV_CODE_VENDOR_EXT
:
669 if (set_bytes(data
, strval
, &new_tlv_len
) != 0)
674 // Is there room for this TLV?
675 if ((be16_to_cpu(eeprom_hdr
->totallen
) + ENT_SIZE
+ new_tlv_len
) >
677 printf("ERROR: There is not enough room in the EERPOM to save data.\n");
681 // Add TLV at the end, overwriting CRC TLV if it exists
682 if (tlvinfo_find_tlv(eeprom
, TLV_CODE_CRC_32
, &eeprom_index
))
683 eeprom_hdr
->totallen
=
684 cpu_to_be16(be16_to_cpu(eeprom_hdr
->totallen
) -
687 eeprom_index
= HDR_SIZE
+ be16_to_cpu(eeprom_hdr
->totallen
);
688 eeprom_tlv
= to_entry(&eeprom
[eeprom_index
]);
689 eeprom_tlv
->type
= tcode
;
690 eeprom_tlv
->length
= new_tlv_len
;
691 memcpy(eeprom_tlv
->value
, data
, new_tlv_len
);
693 // Update the total length and calculate (add) a new CRC-32 TLV
694 eeprom_hdr
->totallen
= cpu_to_be16(be16_to_cpu(eeprom_hdr
->totallen
) +
695 ENT_SIZE
+ new_tlv_len
);
704 * Converts a string MAC address into a binary buffer.
706 * This function takes a pointer to a MAC address string
707 * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number).
708 * The string format is verified and then converted to binary and
709 * stored in a buffer.
711 static int set_mac(char *buf
, const char *string
)
713 char *p
= (char *)string
;
719 printf("ERROR: NULL mac addr string passed in.\n");
723 if (strlen(p
) != 17) {
724 printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p
));
725 printf("ERROR: Bad MAC address format: %s\n", string
);
729 for (i
= 0; i
< 17; i
++) {
733 printf("ERROR: mac: p[%i] != :, found: `%c'\n",
738 } else if (!is_hex(p
[i
])) {
740 printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n",
747 printf("ERROR: Bad MAC address format: %s\n", string
);
751 /* Convert string to binary */
752 for (i
= 0, p
= (char *)string
; i
< 6; i
++) {
753 buf
[i
] = p
? simple_strtoul(p
, &end
, 16) : 0;
755 p
= (*end
) ? end
+ 1 : end
;
758 if (!is_valid_ethaddr((u8
*)buf
)) {
759 printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n");
760 printf("ERROR: Bad MAC address format: %s\n", string
);
770 * Validates the format of the data string
772 * This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss)
773 * and validates that the format is correct. If so the string is copied
774 * to the supplied buffer.
776 static int set_date(char *buf
, const char *string
)
781 printf("ERROR: NULL date string passed in.\n");
785 if (strlen(string
) != 19) {
786 printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string
));
787 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
792 for (i
= 0; string
[i
] != 0; i
++) {
796 if (string
[i
] != '/') {
797 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
803 if (string
[i
] != ' ') {
804 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
811 if (string
[i
] != ':') {
812 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
818 if (!is_digit(string
[i
])) {
819 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
834 * Converts a space-separated string of decimal numbers into a
837 * This function takes a pointer to a space-separated string of decimal
838 * numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers
839 * and converts them to an array of bytes.
841 static int set_bytes(char *buf
, const char *string
, int *converted_accum
)
843 char *p
= (char *)string
;
848 printf("ERROR: NULL string passed in.\n");
852 /* Convert string to bytes */
853 for (i
= 0, p
= (char *)string
; (i
< TLV_VALUE_MAX_LEN
) && (*p
!= 0);
855 while ((*p
== ' ') || (*p
== '\t') || (*p
== ',') ||
861 printf("ERROR: Non-digit found in byte string: (%s)\n",
865 byte
= simple_strtoul(p
, &p
, 0);
867 printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n",
871 buf
[i
] = byte
& 0xFF;
875 if (i
== TLV_VALUE_MAX_LEN
&& (*p
!= 0)) {
876 printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n",
877 TLV_VALUE_MAX_LEN
, string
);
881 *converted_accum
= i
;
885 static void show_tlv_devices(void)
889 for (dev
= 0; dev
< MAX_TLV_DEVICES
; dev
++)
890 if (tlv_devices
[dev
])
891 printf("TLV: %u%s\n", dev
,
892 (dev
== current_dev
) ? " (*)" : "");
895 static int find_tlv_devices(struct udevice
**tlv_devices_p
)
901 for (ret
= uclass_first_device_check(UCLASS_I2C_EEPROM
, &dev
);
903 ret
= uclass_next_device_check(&dev
)) {
905 tlv_devices_p
[count_dev
++] = dev
;
906 if (count_dev
>= MAX_TLV_DEVICES
)
910 return (count_dev
== 0) ? -ENODEV
: 0;
913 static struct udevice
*find_tlv_device_by_index(int dev_num
)
915 struct udevice
*local_tlv_devices
[MAX_TLV_DEVICES
] = {};
916 struct udevice
**tlv_devices_p
;
919 if (gd
->flags
& (GD_FLG_RELOC
| GD_FLG_SPL_INIT
)) {
920 /* Assume BSS is initialized; use static data */
921 if (tlv_devices
[dev_num
])
922 return tlv_devices
[dev_num
];
923 tlv_devices_p
= tlv_devices
;
925 tlv_devices_p
= local_tlv_devices
;
928 ret
= find_tlv_devices(tlv_devices_p
);
929 if (ret
== 0 && tlv_devices_p
[dev_num
])
930 return tlv_devices_p
[dev_num
];
936 * read_tlv_eeprom - read the hwinfo from i2c EEPROM
938 int read_tlv_eeprom(void *eeprom
, int offset
, int len
, int dev_num
)
942 if (dev_num
>= MAX_TLV_DEVICES
)
945 dev
= find_tlv_device_by_index(dev_num
);
949 return i2c_eeprom_read(dev
, offset
, eeprom
, len
);
953 * write_tlv_eeprom - write the hwinfo to i2c EEPROM
955 int write_tlv_eeprom(void *eeprom
, int len
)
957 if (!(gd
->flags
& GD_FLG_RELOC
))
959 if (!tlv_devices
[current_dev
])
962 return i2c_eeprom_write(tlv_devices
[current_dev
], 0, eeprom
, len
);
965 int read_tlvinfo_tlv_eeprom(void *eeprom
, struct tlvinfo_header
**hdr
,
966 struct tlvinfo_tlv
**first_entry
, int dev_num
)
969 struct tlvinfo_header
*tlv_hdr
;
970 struct tlvinfo_tlv
*tlv_ent
;
972 /* Read TLV header */
973 ret
= read_tlv_eeprom(eeprom
, 0, HDR_SIZE
, dev_num
);
978 if (!is_valid_tlvinfo_header(tlv_hdr
))
981 /* Read TLV entries */
982 tlv_ent
= to_entry(&tlv_hdr
[1]);
983 ret
= read_tlv_eeprom(tlv_ent
, HDR_SIZE
,
984 be16_to_cpu(tlv_hdr
->totallen
), dev_num
);
987 if (!is_checksum_valid(eeprom
))
991 *first_entry
= tlv_ent
;
997 * mac_read_from_eeprom
999 * Read the MAC addresses from EEPROM
1001 * This function reads the MAC addresses from EEPROM and sets the
1002 * appropriate environment variables for each one read.
1004 * The environment variables are only set if they haven't been set already.
1005 * This ensures that any user-saved variables are never overwritten.
1007 * This function must be called after relocation.
1009 int mac_read_from_eeprom(void)
1013 struct tlvinfo_tlv
*eeprom_tlv
;
1016 struct tlvinfo_header
*eeprom_hdr
= to_header(eeprom
);
1020 if (read_eeprom(eeprom
)) {
1021 printf("Read failed.\n");
1026 if (tlvinfo_find_tlv(eeprom
, TLV_CODE_MAC_SIZE
, &eeprom_index
)) {
1027 eeprom_tlv
= to_entry(&eeprom
[eeprom_index
]);
1028 maccount
= (eeprom_tlv
->value
[0] << 8) | eeprom_tlv
->value
[1];
1031 memcpy(macbase
, "\0\0\0\0\0\0", 6);
1032 if (tlvinfo_find_tlv(eeprom
, TLV_CODE_MAC_BASE
, &eeprom_index
)) {
1033 eeprom_tlv
= to_entry(&eeprom
[eeprom_index
]);
1034 memcpy(macbase
, eeprom_tlv
->value
, 6);
1037 for (i
= 0; i
< maccount
; i
++) {
1038 if (is_valid_ethaddr(macbase
)) {
1042 sprintf(ethaddr
, "%02X:%02X:%02X:%02X:%02X:%02X",
1043 macbase
[0], macbase
[1], macbase
[2],
1044 macbase
[3], macbase
[4], macbase
[5]);
1045 sprintf(enetvar
, i
? "eth%daddr" : "ethaddr", i
);
1046 /* Only initialize environment variables that are blank
1047 * (i.e. have not yet been set)
1049 if (!env_get(enetvar
))
1050 env_set(enetvar
, ethaddr
);
1053 if (macbase
[5] == 0) {
1055 if (macbase
[4] == 0) {
1057 if (macbase
[3] == 0) {
1067 printf("%s v%u len=%u\n", eeprom_hdr
->signature
, eeprom_hdr
->version
,
1068 be16_to_cpu(eeprom_hdr
->totallen
));
1074 * populate_serial_number - read the serial number from EEPROM
1076 * This function reads the serial number from the EEPROM and sets the
1077 * appropriate environment variable.
1079 * The environment variable is only set if it has not been set
1080 * already. This ensures that any user-saved variables are never
1083 * This function must be called after relocation.
1085 int populate_serial_number(void)
1087 char serialstr
[257];
1089 struct tlvinfo_tlv
*eeprom_tlv
;
1091 if (env_get("serial#"))
1094 if (read_eeprom(eeprom
)) {
1095 printf("Read failed.\n");
1099 if (tlvinfo_find_tlv(eeprom
, TLV_CODE_SERIAL_NUMBER
, &eeprom_index
)) {
1100 eeprom_tlv
= to_entry(&eeprom
[eeprom_index
]);
1101 memcpy(serialstr
, eeprom_tlv
->value
, eeprom_tlv
->length
);
1102 serialstr
[eeprom_tlv
->length
] = 0;
1103 env_set("serial#", serialstr
);