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