Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-sh into next
[platform/kernel/u-boot.git] / cmd / tlv_eeprom.c
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
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  */
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  */
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  */
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  */
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  */
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  */
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
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  */
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  */
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  */
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  */
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                         return CMD_RET_USAGE;
483                 }
484                 return 0;
485         }
486
487         // The set command takes one or two args.
488         if (argc > 4)
489                 return CMD_RET_USAGE;
490
491         // Set command. If the TLV exists in the EEPROM, delete it. Then if
492         // data was supplied for this TLV add the TLV with the new contents at
493         // the end.
494         if (cmd == 's') {
495                 int tcode;
496
497                 tcode = simple_strtoul(argv[2], NULL, 0);
498                 tlvinfo_delete_tlv(eeprom, tcode);
499                 if (argc == 4)
500                         tlvinfo_add_tlv(eeprom, tcode, argv[3]);
501         } else if (cmd == 'd') { /* 'dev' command */
502                 unsigned int devnum;
503
504                 devnum = simple_strtoul(argv[2], NULL, 0);
505                 if (devnum > MAX_TLV_DEVICES || !tlv_devices[devnum]) {
506                         printf("Invalid device number\n");
507                         return 0;
508                 }
509                 current_dev = devnum;
510                 has_been_read = 0;
511         } else {
512                 return CMD_RET_USAGE;
513         }
514
515         return 0;
516 }
517
518 /**
519  *  This macro defines the tlv_eeprom command line command.
520  */
521 U_BOOT_CMD(tlv_eeprom, 4, 1,  do_tlv_eeprom,
522            "Display and program the system EEPROM data block.",
523            "[read|write|set <type_code> <string_value>|erase|list]\n"
524            "tlv_eeprom\n"
525            "    - With no arguments display the current contents.\n"
526            "tlv_eeprom dev [dev]\n"
527            "    - List devices or set current EEPROM device.\n"
528            "tlv_eeprom read\n"
529            "    - Load EEPROM data from device to memory.\n"
530            "tlv_eeprom write\n"
531            "    - Write the EEPROM data to persistent storage.\n"
532            "tlv_eeprom set <type_code> <string_value>\n"
533            "    - Set a field to a value.\n"
534            "    - If no string_value, field is deleted.\n"
535            "    - Use 'tlv_eeprom write' to make changes permanent.\n"
536            "tlv_eeprom erase\n"
537            "    - Reset the in memory EEPROM data.\n"
538            "    - Use 'tlv_eeprom read' to refresh the in memory EEPROM data.\n"
539            "    - Use 'tlv_eeprom write' to make changes permanent.\n"
540            "tlv_eeprom list\n"
541            "    - List the understood TLV codes and names.\n"
542         );
543
544 /**
545  *  tlvinfo_find_tlv
546  *
547  *  This function finds the TLV with the supplied code in the EERPOM.
548  *  An offset from the beginning of the EEPROM is returned in the
549  *  eeprom_index parameter if the TLV is found.
550  */
551 static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index)
552 {
553         struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
554         struct tlvinfo_tlv    *eeprom_tlv;
555         int eeprom_end;
556
557         // Search through the TLVs, looking for the first one which matches the
558         // supplied type code.
559         *eeprom_index = HDR_SIZE;
560         eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
561         while (*eeprom_index < eeprom_end) {
562                 eeprom_tlv = to_entry(&eeprom[*eeprom_index]);
563                 if (!is_valid_tlv(eeprom_tlv))
564                         return false;
565                 if (eeprom_tlv->type == tcode)
566                         return true;
567                 *eeprom_index += ENT_SIZE + eeprom_tlv->length;
568         }
569         return(false);
570 }
571
572 /**
573  *  tlvinfo_delete_tlv
574  *
575  *  This function deletes the TLV with the specified type code from the
576  *  EEPROM.
577  */
578 static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code)
579 {
580         int eeprom_index;
581         int tlength;
582         struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
583         struct tlvinfo_tlv *eeprom_tlv;
584
585         // Find the TLV and then move all following TLVs "forward"
586         if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) {
587                 eeprom_tlv = to_entry(&eeprom[eeprom_index]);
588                 tlength = ENT_SIZE + eeprom_tlv->length;
589                 memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength],
590                        HDR_SIZE +
591                        be16_to_cpu(eeprom_hdr->totallen) - eeprom_index -
592                        tlength);
593                 eeprom_hdr->totallen =
594                         cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
595                                     tlength);
596                 update_crc(eeprom);
597                 return true;
598         }
599         return false;
600 }
601
602 /**
603  *  tlvinfo_add_tlv
604  *
605  *  This function adds a TLV to the EEPROM, converting the value (a string) to
606  *  the format in which it will be stored in the EEPROM.
607  */
608 #define MAX_TLV_VALUE_LEN   256
609 static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval)
610 {
611         struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
612         struct tlvinfo_tlv *eeprom_tlv;
613         int new_tlv_len = 0;
614         u32 value;
615         char data[MAX_TLV_VALUE_LEN];
616         int eeprom_index;
617
618         // Encode each TLV type into the format to be stored in the EERPOM
619         switch (tcode) {
620         case TLV_CODE_PRODUCT_NAME:
621         case TLV_CODE_PART_NUMBER:
622         case TLV_CODE_SERIAL_NUMBER:
623         case TLV_CODE_LABEL_REVISION:
624         case TLV_CODE_PLATFORM_NAME:
625         case TLV_CODE_ONIE_VERSION:
626         case TLV_CODE_MANUF_NAME:
627         case TLV_CODE_MANUF_COUNTRY:
628         case TLV_CODE_VENDOR_NAME:
629         case TLV_CODE_DIAG_VERSION:
630         case TLV_CODE_SERVICE_TAG:
631                 strncpy(data, strval, MAX_TLV_VALUE_LEN);
632                 new_tlv_len = min_t(size_t, MAX_TLV_VALUE_LEN, strlen(strval));
633                 break;
634         case TLV_CODE_DEVICE_VERSION:
635                 value = simple_strtoul(strval, NULL, 0);
636                 if (value >= 256) {
637                         printf("ERROR: Device version must be 255 or less. Value supplied: %u",
638                                value);
639                         return false;
640                 }
641                 data[0] = value & 0xFF;
642                 new_tlv_len = 1;
643                 break;
644         case TLV_CODE_MAC_SIZE:
645                 value = simple_strtoul(strval, NULL, 0);
646                 if (value >= 65536) {
647                         printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u",
648                                value);
649                         return false;
650                 }
651                 data[0] = (value >> 8) & 0xFF;
652                 data[1] = value & 0xFF;
653                 new_tlv_len = 2;
654                 break;
655         case TLV_CODE_MANUF_DATE:
656                 if (set_date(data, strval) != 0)
657                         return false;
658                 new_tlv_len = 19;
659                 break;
660         case TLV_CODE_MAC_BASE:
661                 if (set_mac(data, strval) != 0)
662                         return false;
663                 new_tlv_len = 6;
664                 break;
665         case TLV_CODE_CRC_32:
666                 printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n");
667                 return false;
668         case TLV_CODE_VENDOR_EXT:
669         default:
670                 if (set_bytes(data, strval, &new_tlv_len) != 0)
671                         return false;
672                 break;
673         }
674
675         // Is there room for this TLV?
676         if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) >
677                         TLV_TOTAL_LEN_MAX) {
678                 printf("ERROR: There is not enough room in the EERPOM to save data.\n");
679                 return false;
680         }
681
682         // Add TLV at the end, overwriting CRC TLV if it exists
683         if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index))
684                 eeprom_hdr->totallen =
685                         cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) -
686                                         ENT_SIZE - 4);
687         else
688                 eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen);
689         eeprom_tlv = to_entry(&eeprom[eeprom_index]);
690         eeprom_tlv->type = tcode;
691         eeprom_tlv->length = new_tlv_len;
692         memcpy(eeprom_tlv->value, data, new_tlv_len);
693
694         // Update the total length and calculate (add) a new CRC-32 TLV
695         eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) +
696                         ENT_SIZE + new_tlv_len);
697         update_crc(eeprom);
698
699         return true;
700 }
701
702 /**
703  *  set_mac
704  *
705  *  Converts a string MAC address into a binary buffer.
706  *
707  *  This function takes a pointer to a MAC address string
708  *  (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number).
709  *  The string format is verified and then converted to binary and
710  *  stored in a buffer.
711  */
712 static int set_mac(char *buf, const char *string)
713 {
714         char *p = (char *)string;
715         int   i;
716         int   err = 0;
717         char *end;
718
719         if (!p) {
720                 printf("ERROR: NULL mac addr string passed in.\n");
721                 return -1;
722         }
723
724         if (strlen(p) != 17) {
725                 printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p));
726                 printf("ERROR: Bad MAC address format: %s\n", string);
727                 return -1;
728         }
729
730         for (i = 0; i < 17; i++) {
731                 if ((i % 3) == 2) {
732                         if (p[i] != ':') {
733                                 err++;
734                                 printf("ERROR: mac: p[%i] != :, found: `%c'\n",
735                                        i, p[i]);
736                                 break;
737                         }
738                         continue;
739                 } else if (!is_hex(p[i])) {
740                         err++;
741                         printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n",
742                                i, p[i]);
743                         break;
744                 }
745         }
746
747         if (err != 0) {
748                 printf("ERROR: Bad MAC address format: %s\n", string);
749                 return -1;
750         }
751
752         /* Convert string to binary */
753         for (i = 0, p = (char *)string; i < 6; i++) {
754                 buf[i] = p ? hextoul(p, &end) : 0;
755                 if (p)
756                         p = (*end) ? end + 1 : end;
757         }
758
759         if (!is_valid_ethaddr((u8 *)buf)) {
760                 printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n");
761                 printf("ERROR: Bad MAC address format: %s\n", string);
762                 return -1;
763         }
764
765         return 0;
766 }
767
768 /**
769  *  set_date
770  *
771  *  Validates the format of the data string
772  *
773  *  This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss)
774  *  and validates that the format is correct. If so the string is copied
775  *  to the supplied buffer.
776  */
777 static int set_date(char *buf, const char *string)
778 {
779         int i;
780
781         if (!string) {
782                 printf("ERROR: NULL date string passed in.\n");
783                 return -1;
784         }
785
786         if (strlen(string) != 19) {
787                 printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string));
788                 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
789                        string);
790                 return -1;
791         }
792
793         for (i = 0; string[i] != 0; i++) {
794                 switch (i) {
795                 case 2:
796                 case 5:
797                         if (string[i] != '/') {
798                                 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
799                                        string);
800                                 return -1;
801                         }
802                         break;
803                 case 10:
804                         if (string[i] != ' ') {
805                                 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
806                                        string);
807                                 return -1;
808                         }
809                         break;
810                 case 13:
811                 case 16:
812                         if (string[i] != ':') {
813                                 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
814                                        string);
815                                 return -1;
816                         }
817                         break;
818                 default:
819                         if (!is_digit(string[i])) {
820                                 printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n",
821                                        string);
822                                 return -1;
823                         }
824                         break;
825                 }
826         }
827
828         strcpy(buf, string);
829         return 0;
830 }
831
832 /**
833  *  set_bytes
834  *
835  *  Converts a space-separated string of decimal numbers into a
836  *  buffer of bytes.
837  *
838  *  This function takes a pointer to a space-separated string of decimal
839  *  numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers
840  *  and converts them to an array of bytes.
841  */
842 static int set_bytes(char *buf, const char *string, int *converted_accum)
843 {
844         char *p = (char *)string;
845         int   i;
846         uint  byte;
847
848         if (!p) {
849                 printf("ERROR: NULL string passed in.\n");
850                 return -1;
851         }
852
853         /* Convert string to bytes */
854         for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0);
855                         i++) {
856                 while ((*p == ' ') || (*p == '\t') || (*p == ',') ||
857                        (*p == ';')) {
858                         p++;
859                 }
860                 if (*p != 0) {
861                         if (!is_digit(*p)) {
862                                 printf("ERROR: Non-digit found in byte string: (%s)\n",
863                                        string);
864                                 return -1;
865                         }
866                         byte = simple_strtoul(p, &p, 0);
867                         if (byte >= 256) {
868                                 printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n",
869                                        byte, string);
870                                 return -1;
871                         }
872                         buf[i] = byte & 0xFF;
873                 }
874         }
875
876         if (i == TLV_VALUE_MAX_LEN && (*p != 0)) {
877                 printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n",
878                        TLV_VALUE_MAX_LEN, string);
879                 return -1;
880         }
881
882         *converted_accum = i;
883         return 0;
884 }
885
886 static void show_tlv_devices(void)
887 {
888         unsigned int dev;
889
890         for (dev = 0; dev < MAX_TLV_DEVICES; dev++)
891                 if (tlv_devices[dev])
892                         printf("TLV: %u%s\n", dev,
893                                (dev == current_dev) ? " (*)" : "");
894 }
895
896 static int find_tlv_devices(struct udevice **tlv_devices_p)
897 {
898         int ret;
899         int count_dev = 0;
900         struct udevice *dev;
901
902         for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev);
903                         dev;
904                         ret = uclass_next_device_check(&dev)) {
905                 if (ret == 0)
906                         tlv_devices_p[count_dev++] = dev;
907                 if (count_dev >= MAX_TLV_DEVICES)
908                         break;
909         }
910
911         return (count_dev == 0) ? -ENODEV : 0;
912 }
913
914 static struct udevice *find_tlv_device_by_index(int dev_num)
915 {
916         struct udevice *local_tlv_devices[MAX_TLV_DEVICES] = {};
917         struct udevice **tlv_devices_p;
918         int ret;
919
920         if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) {
921                 /* Assume BSS is initialized; use static data */
922                 if (tlv_devices[dev_num])
923                         return tlv_devices[dev_num];
924                 tlv_devices_p = tlv_devices;
925         } else {
926                 tlv_devices_p = local_tlv_devices;
927         }
928
929         ret = find_tlv_devices(tlv_devices_p);
930         if (ret == 0 && tlv_devices_p[dev_num])
931                 return tlv_devices_p[dev_num];
932
933         return NULL;
934 }
935
936 /**
937  * read_tlv_eeprom - read the hwinfo from i2c EEPROM
938  */
939 int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num)
940 {
941         struct udevice *dev;
942
943         if (dev_num >= MAX_TLV_DEVICES)
944                 return -EINVAL;
945
946         dev = find_tlv_device_by_index(dev_num);
947         if (!dev)
948                 return -ENODEV;
949
950         return i2c_eeprom_read(dev, offset, eeprom, len);
951 }
952
953 /**
954  * write_tlv_eeprom - write the hwinfo to i2c EEPROM
955  */
956 int write_tlv_eeprom(void *eeprom, int len)
957 {
958         if (!(gd->flags & GD_FLG_RELOC))
959                 return -ENODEV;
960         if (!tlv_devices[current_dev])
961                 return -ENODEV;
962
963         return i2c_eeprom_write(tlv_devices[current_dev], 0, eeprom, len);
964 }
965
966 int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr,
967                             struct tlvinfo_tlv **first_entry, int dev_num)
968 {
969         int ret;
970         struct tlvinfo_header *tlv_hdr;
971         struct tlvinfo_tlv *tlv_ent;
972
973         /* Read TLV header */
974         ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num);
975         if (ret < 0)
976                 return ret;
977
978         tlv_hdr = eeprom;
979         if (!is_valid_tlvinfo_header(tlv_hdr))
980                 return -EINVAL;
981
982         /* Read TLV entries */
983         tlv_ent = to_entry(&tlv_hdr[1]);
984         ret = read_tlv_eeprom(tlv_ent, HDR_SIZE,
985                               be16_to_cpu(tlv_hdr->totallen), dev_num);
986         if (ret < 0)
987                 return ret;
988         if (!is_checksum_valid(eeprom))
989                 return -EINVAL;
990
991         *hdr = tlv_hdr;
992         *first_entry = tlv_ent;
993
994         return 0;
995 }
996
997 /**
998  *  mac_read_from_eeprom
999  *
1000  *  Read the MAC addresses from EEPROM
1001  *
1002  *  This function reads the MAC addresses from EEPROM and sets the
1003  *  appropriate environment variables for each one read.
1004  *
1005  *  The environment variables are only set if they haven't been set already.
1006  *  This ensures that any user-saved variables are never overwritten.
1007  *
1008  *  This function must be called after relocation.
1009  */
1010 int mac_read_from_eeprom(void)
1011 {
1012         unsigned int i;
1013         int eeprom_index;
1014         struct tlvinfo_tlv *eeprom_tlv;
1015         int maccount;
1016         u8 macbase[6];
1017         struct tlvinfo_header *eeprom_hdr = to_header(eeprom);
1018
1019         puts("EEPROM: ");
1020
1021         if (read_eeprom(eeprom)) {
1022                 printf("Read failed.\n");
1023                 return -1;
1024         }
1025
1026         maccount = 1;
1027         if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) {
1028                 eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1029                 maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1];
1030         }
1031
1032         memcpy(macbase, "\0\0\0\0\0\0", 6);
1033         if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) {
1034                 eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1035                 memcpy(macbase, eeprom_tlv->value, 6);
1036         }
1037
1038         for (i = 0; i < maccount; i++) {
1039                 if (is_valid_ethaddr(macbase)) {
1040                         char ethaddr[18];
1041                         char enetvar[11];
1042
1043                         sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
1044                                 macbase[0], macbase[1], macbase[2],
1045                                 macbase[3], macbase[4], macbase[5]);
1046                         sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
1047                         /* Only initialize environment variables that are blank
1048                          * (i.e. have not yet been set)
1049                          */
1050                         if (!env_get(enetvar))
1051                                 env_set(enetvar, ethaddr);
1052
1053                         macbase[5]++;
1054                         if (macbase[5] == 0) {
1055                                 macbase[4]++;
1056                                 if (macbase[4] == 0) {
1057                                         macbase[3]++;
1058                                         if (macbase[3] == 0) {
1059                                                 macbase[0] = 0;
1060                                                 macbase[1] = 0;
1061                                                 macbase[2] = 0;
1062                                         }
1063                                 }
1064                         }
1065                 }
1066         }
1067
1068         printf("%s v%u len=%u\n", eeprom_hdr->signature, eeprom_hdr->version,
1069                be16_to_cpu(eeprom_hdr->totallen));
1070
1071         return 0;
1072 }
1073
1074 /**
1075  *  populate_serial_number - read the serial number from EEPROM
1076  *
1077  *  This function reads the serial number from the EEPROM and sets the
1078  *  appropriate environment variable.
1079  *
1080  *  The environment variable is only set if it has not been set
1081  *  already.  This ensures that any user-saved variables are never
1082  *  overwritten.
1083  *
1084  *  This function must be called after relocation.
1085  */
1086 int populate_serial_number(void)
1087 {
1088         char serialstr[257];
1089         int eeprom_index;
1090         struct tlvinfo_tlv *eeprom_tlv;
1091
1092         if (env_get("serial#"))
1093                 return 0;
1094
1095         if (read_eeprom(eeprom)) {
1096                 printf("Read failed.\n");
1097                 return -1;
1098         }
1099
1100         if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) {
1101                 eeprom_tlv = to_entry(&eeprom[eeprom_index]);
1102                 memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length);
1103                 serialstr[eeprom_tlv->length] = 0;
1104                 env_set("serial#", serialstr);
1105         }
1106
1107         return 0;
1108 }