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