
Rewrite tlv_eeprom command for using the new tlv library, and drop all unused functions. From this point on, tlv_eeprom command internal functions shall not be reused externally.
mac_read_from_eeprom & populate_serial_number are kept in place for now as is, however these probably deserve a new location.
Signed-off-by: Josua Mayer josua@solid-run.com --- cmd/Kconfig | 9 +- cmd/tlv_eeprom.c | 507 +++++++------------------------------ configs/clearfog_defconfig | 2 +- include/tlv_eeprom.h | 148 ----------- 4 files changed, 92 insertions(+), 574 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig index 9c2149dc881..4b7ea8cd358 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -190,19 +190,14 @@ config CMD_REGINFO
config CMD_TLV_EEPROM bool "tlv_eeprom" - depends on I2C_EEPROM - depends on !EEPROM_TLV_LIB - select CRC32 + depends on EEPROM_TLV_LIB help Display and program the system EEPROM data block in ONIE Tlvinfo format. TLV stands for Type-Length-Value.
config SPL_CMD_TLV_EEPROM bool "tlv_eeprom for SPL" - depends on SPL_I2C_EEPROM - depends on !SPL_EEPROM_TLV_LIB - select SPL_DRIVERS_MISC - select SPL_CRC32 + depends on SPL_EEPROM_TLV_LIB help Read system EEPROM data block in ONIE Tlvinfo format from SPL.
diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c index 0ca4d714645..02e1dd88d35 100644 --- a/cmd/tlv_eeprom.c +++ b/cmd/tlv_eeprom.c @@ -7,69 +7,36 @@ * Copyright (C) 2014 Srideep srideep_devireddy@dell.com * Copyright (C) 2013 Miles Tseng miles_tseng@accton.com * Copyright (C) 2014,2016 david_yang david_yang@accton.com + * Copyright (C) 2023 Josua Mayer josua@solid-run.com */
-#include <common.h> #include <command.h> -#include <dm.h> -#include <i2c.h> -#include <i2c_eeprom.h> -#include <env.h> -#include <init.h> +#include <linux/err.h> #include <net.h> -#include <asm/global_data.h> -#include <linux/ctype.h> -#include <u-boot/crc.h> - -#include "tlv_eeprom.h" +#include <stdio.h> +#include <tlv_eeprom.h> +#include <vsprintf.h>
DECLARE_GLOBAL_DATA_PTR;
-#define MAX_TLV_DEVICES 2 +#define DEBUG
-/* File scope function prototypes */ -static bool is_checksum_valid(u8 *eeprom); -static int read_eeprom(int devnum, u8 *eeprom); -static void show_eeprom(int devnum, u8 *eeprom); static void decode_tlv(struct tlvinfo_tlv *tlv); -static void update_crc(u8 *eeprom); -static int prog_eeprom(int devnum, u8 *eeprom); -static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); -static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); -static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval); +static bool tlvinfo_add_tlv(struct tlvinfo_priv *header, int tcode, char *strval); static int set_mac(char *buf, const char *string); static int set_date(char *buf, const char *string); static int set_bytes(char *buf, const char *string, int *converted_accum); -static void show_tlv_devices(int current_dev);
-/* The EERPOM contents after being read into memory */ +/* The EEPROM contents after being read into memory */ static u8 eeprom[TLV_INFO_MAX_LEN];
-static struct udevice *tlv_devices[MAX_TLV_DEVICES]; - -#define to_header(p) ((struct tlvinfo_header *)p) -#define to_entry(p) ((struct tlvinfo_tlv *)p) - -#define HDR_SIZE sizeof(struct tlvinfo_header) -#define ENT_SIZE sizeof(struct tlvinfo_tlv) +static void show_tlv_devices(int current_dev);
static inline bool is_digit(char c) { return (c >= '0' && c <= '9'); }
-/** - * is_valid_tlv - * - * Perform basic sanity checks on a TLV field. The TLV is pointed to - * by the parameter provided. - * 1. The type code is not reserved (0x00 or 0xFF) - */ -static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv) -{ - return((tlv->type != 0x00) && (tlv->type != 0xFF)); -} - /** * is_hex * @@ -78,79 +45,8 @@ static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv) static inline u8 is_hex(char p) { return (((p >= '0') && (p <= '9')) || - ((p >= 'A') && (p <= 'F')) || - ((p >= 'a') && (p <= 'f'))); -} - -/** - * is_checksum_valid - * - * Validate the checksum in the provided TlvInfo EEPROM data. First, - * verify that the TlvInfo header is valid, then make sure the last - * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data - * and compare it to the value stored in the EEPROM CRC-32 TLV. - */ -static bool is_checksum_valid(u8 *eeprom) -{ - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_crc; - unsigned int calc_crc; - unsigned int stored_crc; - - // Is the eeprom header valid? - if (!is_valid_tlvinfo_header(eeprom_hdr)) - return false; - - // Is the last TLV a CRC? - eeprom_crc = to_entry(&eeprom[HDR_SIZE + - be16_to_cpu(eeprom_hdr->totallen) - (ENT_SIZE + 4)]); - if (eeprom_crc->type != TLV_CODE_CRC_32 || eeprom_crc->length != 4) - return false; - - // Calculate the checksum - calc_crc = crc32(0, (void *)eeprom, - HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); - stored_crc = (eeprom_crc->value[0] << 24) | - (eeprom_crc->value[1] << 16) | - (eeprom_crc->value[2] << 8) | - eeprom_crc->value[3]; - return calc_crc == stored_crc; -} - -/** - * read_eeprom - * - * Read the EEPROM into memory, if it hasn't already been read. - */ -static int read_eeprom(int devnum, u8 *eeprom) -{ - int ret; - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]); - - /* Read the header */ - ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, devnum); - /* If the header was successfully read, read the TLVs */ - if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr)) - ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE, - be16_to_cpu(eeprom_hdr->totallen), devnum); - else if (ret == -ENODEV) - return ret; - - // If the contents are invalid, start over with default contents - if (!is_valid_tlvinfo_header(eeprom_hdr) || - !is_checksum_valid(eeprom)) { - strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); - eeprom_hdr->version = TLV_INFO_VERSION; - eeprom_hdr->totallen = cpu_to_be16(0); - update_crc(eeprom); - } - -#ifdef DEBUG - show_eeprom(devnum, eeprom); -#endif - - return ret; + ((p >= 'A') && (p <= 'F')) || + ((p >= 'a') && (p <= 'f'))); }
/** @@ -158,20 +54,13 @@ static int read_eeprom(int devnum, u8 *eeprom) * * Display the contents of the EEPROM */ -static void show_eeprom(int devnum, u8 *eeprom) +static void show_eeprom(int devnum, struct tlvinfo_priv *tlv) { - int tlv_end; - int curr_tlv; #ifdef DEBUG int i; #endif - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_tlv; - - if (!is_valid_tlvinfo_header(eeprom_hdr)) { - printf("EEPROM does not contain data in a valid TlvInfo format.\n"); - return; - } + struct tlvinfo_tlv *entry = NULL; + struct tlvinfo_header *eeprom_hdr = tlv_header_get(tlv);
printf("TLV: %u\n", devnum); printf("TlvInfo Header:\n"); @@ -181,21 +70,13 @@ static void show_eeprom(int devnum, u8 *eeprom)
printf("TLV Name Code Len Value\n"); printf("-------------------- ---- --- -----\n"); - curr_tlv = HDR_SIZE; - tlv_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); - while (curr_tlv < tlv_end) { - eeprom_tlv = to_entry(&eeprom[curr_tlv]); - if (!is_valid_tlv(eeprom_tlv)) { - printf("Invalid TLV field starting at EEPROM offset %d\n", - curr_tlv); - return; - } - decode_tlv(eeprom_tlv); - curr_tlv += ENT_SIZE + eeprom_tlv->length; + entry = tlv_entry_next(tlv, entry); + while (!IS_ERR(entry)) { + decode_tlv(entry); + entry = tlv_entry_next(tlv, entry); } - - printf("Checksum is %s.\n", - is_checksum_valid(eeprom) ? "valid" : "invalid"); + if (PTR_ERR(entry) != -ENOENT) + printf("Failed to get next entry: %ld\n", PTR_ERR(entry));
#ifdef DEBUG printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN); @@ -341,66 +222,6 @@ static void decode_tlv(struct tlvinfo_tlv *tlv) printf("%-20s 0x%02X %3d %s\n", name, tlv->type, tlv->length, value); }
-/** - * update_crc - * - * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then - * one is added. This function should be called after each update to the - * EEPROM structure, to make sure the CRC is always correct. - */ -static void update_crc(u8 *eeprom) -{ - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_crc; - unsigned int calc_crc; - int eeprom_index; - - // Discover the CRC TLV - if (!tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) { - unsigned int totallen = be16_to_cpu(eeprom_hdr->totallen); - - if ((totallen + ENT_SIZE + 4) > TLV_TOTAL_LEN_MAX) - return; - eeprom_index = HDR_SIZE + totallen; - eeprom_hdr->totallen = cpu_to_be16(totallen + ENT_SIZE + 4); - } - eeprom_crc = to_entry(&eeprom[eeprom_index]); - eeprom_crc->type = TLV_CODE_CRC_32; - eeprom_crc->length = 4; - - // Calculate the checksum - calc_crc = crc32(0, (void *)eeprom, - HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); - eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF; - eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF; - eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF; - eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF; -} - -/** - * prog_eeprom - * - * Write the EEPROM data from CPU memory to the hardware. - */ -static int prog_eeprom(int devnum, u8 *eeprom) -{ - int ret = 0; - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - int eeprom_len; - - update_crc(eeprom); - - eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); - ret = write_tlv_eeprom(eeprom, eeprom_len, devnum); - if (ret) { - printf("Programming failed.\n"); - return -1; - } - - printf("Programming passed.\n"); - return 0; -} - /** * show_tlv_code_list - Display the list of TLV codes and names */ @@ -425,7 +246,8 @@ void show_tlv_code_list(void) int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char cmd; - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_priv *tlv; + struct tlvinfo_tlv *entry; static unsigned int current_dev; /* Set to 1 if we've read EEPROM into memory */ static int has_been_read; @@ -434,15 +256,17 @@ int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) // If no arguments, read the EERPOM and display its contents if (argc == 1) { if (!has_been_read) { - ret = read_eeprom(current_dev, eeprom); - if (ret) { - printf("Failed to read EEPROM data from device.\n"); + tlv = tlv_eeprom_read(tlv_eeprom_get_by_index(current_dev), + 0, eeprom, ARRAY_SIZE(eeprom)); + if (IS_ERR(tlv)) { + printf("Failed to read EEPROM data from device: %ld\n", + PTR_ERR(tlv)); return 0; }
has_been_read = 1; } - show_eeprom(current_dev, eeprom); + show_eeprom(current_dev, tlv); return 0; }
@@ -469,9 +293,11 @@ int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) // Read the EEPROM contents if (cmd == 'r') { has_been_read = 0; - ret = read_eeprom(current_dev, eeprom); - if (ret) { - printf("Failed to read EEPROM data from device.\n"); + tlv = tlv_eeprom_read(tlv_eeprom_get_by_index(current_dev), + 0, eeprom, ARRAY_SIZE(eeprom)); + if (IS_ERR(tlv)) { + printf("Failed to read EEPROM data from device: %ld\n", + PTR_ERR(tlv)); return 0; }
@@ -489,13 +315,20 @@ int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 2) { switch (cmd) { case 'w': /* write */ - prog_eeprom(current_dev, eeprom); + ret = tlv_eeprom_write(tlv_eeprom_get_by_index(current_dev), 0, tlv); + if (ret) + printf("Programming failed: %i\n", ret); + else + printf("Programming passed.\n"); break; case 'e': /* erase */ - strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); - eeprom_hdr->version = TLV_INFO_VERSION; - eeprom_hdr->totallen = cpu_to_be16(0); - update_crc(eeprom); + tlv = tlv_init(eeprom, ARRAY_SIZE(eeprom)); + if (IS_ERR(tlv)) { + printf("Failed to initiailise TLV structure in memory: %ld\n", + PTR_ERR(tlv)); + return 0; + } + printf("EEPROM data in memory reset.\n"); break; case 'l': /* list */ @@ -521,9 +354,14 @@ int do_tlv_eeprom(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int tcode;
tcode = simple_strtoul(argv[2], NULL, 0); - tlvinfo_delete_tlv(eeprom, tcode); + entry = tlv_entry_next_by_code(tlv, NULL, tcode); + ret = tlv_entry_remove(tlv, tlv_entry_next_by_code(tlv, NULL, tcode)); + if (ret != ENOENT) { + printf("Failed to remove existing tlv entry: %d.\n", ret); + return 0; + } if (argc == 4) - tlvinfo_add_tlv(eeprom, tcode, argv[3]); + tlvinfo_add_tlv(tlv, tcode, argv[3]); } else { return CMD_RET_USAGE; } @@ -557,64 +395,6 @@ U_BOOT_CMD(tlv_eeprom, 4, 1, do_tlv_eeprom, " - List the understood TLV codes and names.\n" );
-/** - * tlvinfo_find_tlv - * - * This function finds the TLV with the supplied code in the EERPOM. - * An offset from the beginning of the EEPROM is returned in the - * eeprom_index parameter if the TLV is found. - */ -static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) -{ - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_tlv; - int eeprom_end; - - // Search through the TLVs, looking for the first one which matches the - // supplied type code. - *eeprom_index = HDR_SIZE; - eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); - while (*eeprom_index < eeprom_end) { - eeprom_tlv = to_entry(&eeprom[*eeprom_index]); - if (!is_valid_tlv(eeprom_tlv)) - return false; - if (eeprom_tlv->type == tcode) - return true; - *eeprom_index += ENT_SIZE + eeprom_tlv->length; - } - return(false); -} - -/** - * tlvinfo_delete_tlv - * - * This function deletes the TLV with the specified type code from the - * EEPROM. - */ -static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) -{ - int eeprom_index; - int tlength; - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_tlv; - - // Find the TLV and then move all following TLVs "forward" - if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) { - eeprom_tlv = to_entry(&eeprom[eeprom_index]); - tlength = ENT_SIZE + eeprom_tlv->length; - memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength], - HDR_SIZE + - be16_to_cpu(eeprom_hdr->totallen) - eeprom_index - - tlength); - eeprom_hdr->totallen = - cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - - tlength); - update_crc(eeprom); - return true; - } - return false; -} - /** * tlvinfo_add_tlv * @@ -622,14 +402,13 @@ static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) * the format in which it will be stored in the EEPROM. */ #define MAX_TLV_VALUE_LEN 256 -static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval) +static bool tlvinfo_add_tlv(struct tlvinfo_priv *tlv, int tcode, char *strval) { - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); - struct tlvinfo_tlv *eeprom_tlv; + int ret; + struct tlvinfo_tlv *entry; int new_tlv_len = 0; u32 value; char data[MAX_TLV_VALUE_LEN]; - int eeprom_index;
// Encode each TLV type into the format to be stored in the EERPOM switch (tcode) { @@ -688,29 +467,21 @@ static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval) break; }
- // Is there room for this TLV? - if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) > - TLV_TOTAL_LEN_MAX) { + entry = tlv_entry_add(tlv, NULL, tcode, new_tlv_len); + if (IS_ERR(entry) && PTR_ERR(entry) == -ENOMEM) { printf("ERROR: There is not enough room in the EERPOM to save data.\n"); return false; + } else if (IS_ERR(entry)) { + printf("Failed to create new tlv entry: %ld\n", PTR_ERR(entry)); + return false; }
- // Add TLV at the end, overwriting CRC TLV if it exists - if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) - eeprom_hdr->totallen = - cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - - ENT_SIZE - 4); - else - eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); - eeprom_tlv = to_entry(&eeprom[eeprom_index]); - eeprom_tlv->type = tcode; - eeprom_tlv->length = new_tlv_len; - memcpy(eeprom_tlv->value, data, new_tlv_len); - - // Update the total length and calculate (add) a new CRC-32 TLV - eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) + - ENT_SIZE + new_tlv_len); - update_crc(eeprom); + // copy data into new entry + ret = tlv_entry_set_raw(entry, data, new_tlv_len); + if (ret) { + printf("Failed to set new tlv entry value: %d\n", ret); + return false; + }
return true; } @@ -901,115 +672,15 @@ static int set_bytes(char *buf, const char *string, int *converted_accum)
static void show_tlv_devices(int current_dev) { - unsigned int dev; + int dev; + int i;
- for (dev = 0; dev < MAX_TLV_DEVICES; dev++) - if (tlv_devices[dev]) + for (i = 0; i < MAX_TLV_DEVICES; i++) + if (!IS_ERR(tlv_eeprom_get_by_index(dev))) printf("TLV: %u%s\n", dev, (dev == current_dev) ? " (*)" : ""); }
-static int find_tlv_devices(struct udevice **tlv_devices_p) -{ - int ret; - int count_dev = 0; - struct udevice *dev; - - for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev); - dev; - ret = uclass_next_device_check(&dev)) { - if (ret == 0) - tlv_devices_p[count_dev++] = dev; - if (count_dev >= MAX_TLV_DEVICES) - break; - } - - return (count_dev == 0) ? -ENODEV : 0; -} - -static struct udevice *find_tlv_device_by_index(int dev_num) -{ - struct udevice *local_tlv_devices[MAX_TLV_DEVICES] = {}; - struct udevice **tlv_devices_p; - int ret; - - if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) { - /* Assume BSS is initialized; use static data */ - if (tlv_devices[dev_num]) - return tlv_devices[dev_num]; - tlv_devices_p = tlv_devices; - } else { - tlv_devices_p = local_tlv_devices; - } - - ret = find_tlv_devices(tlv_devices_p); - if (ret == 0 && tlv_devices_p[dev_num]) - return tlv_devices_p[dev_num]; - - return NULL; -} - -/** - * read_tlv_eeprom - read the hwinfo from i2c EEPROM - */ -int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num) -{ - struct udevice *dev; - - if (dev_num >= MAX_TLV_DEVICES) - return -EINVAL; - - dev = find_tlv_device_by_index(dev_num); - if (!dev) - return -ENODEV; - - return i2c_eeprom_read(dev, offset, eeprom, len); -} - -/** - * write_tlv_eeprom - write the hwinfo to i2c EEPROM - */ -int write_tlv_eeprom(void *eeprom, int len, int dev) -{ - if (!(gd->flags & GD_FLG_RELOC)) - return -ENODEV; - if (!tlv_devices[dev]) - return -ENODEV; - - return i2c_eeprom_write(tlv_devices[dev], 0, eeprom, len); -} - -int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, - struct tlvinfo_tlv **first_entry, int dev_num) -{ - int ret; - struct tlvinfo_header *tlv_hdr; - struct tlvinfo_tlv *tlv_ent; - - /* Read TLV header */ - ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num); - if (ret < 0) - return ret; - - tlv_hdr = eeprom; - if (!is_valid_tlvinfo_header(tlv_hdr)) - return -EINVAL; - - /* Read TLV entries */ - tlv_ent = to_entry(&tlv_hdr[1]); - ret = read_tlv_eeprom(tlv_ent, HDR_SIZE, - be16_to_cpu(tlv_hdr->totallen), dev_num); - if (ret < 0) - return ret; - if (!is_checksum_valid(eeprom)) - return -EINVAL; - - *hdr = tlv_hdr; - *first_entry = tlv_ent; - - return 0; -} - /** * mac_read_from_eeprom * @@ -1026,31 +697,31 @@ int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, int mac_read_from_eeprom(void) { unsigned int i; - int eeprom_index; + struct tlvinfo_header *eeprom_hdr; struct tlvinfo_tlv *eeprom_tlv; - int maccount; + uint16_t maccount; u8 macbase[6]; - struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_priv *tlv; int devnum = 0; // TODO: support multiple EEPROMs
puts("EEPROM: ");
- if (read_eeprom(devnum, eeprom)) { + tlv = tlv_eeprom_read(tlv_eeprom_get_by_index(devnum), 0, eeprom, ARRAY_SIZE(eeprom)); + if (IS_ERR(tlv)) { printf("Read failed.\n"); return -1; } + eeprom_hdr = tlv_header_get(tlv);
- maccount = 1; - if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) { - eeprom_tlv = to_entry(&eeprom[eeprom_index]); - maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1]; - } + maccount = 0; + eeprom_tlv = tlv_entry_next_by_code(tlv, NULL, TLV_CODE_MAC_SIZE); + if (!IS_ERR(eeprom_tlv)) + tlv_entry_get_uint16(eeprom_tlv, &maccount);
memcpy(macbase, "\0\0\0\0\0\0", 6); - if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) { - eeprom_tlv = to_entry(&eeprom[eeprom_index]); - memcpy(macbase, eeprom_tlv->value, 6); - } + eeprom_tlv = tlv_entry_next_by_code(tlv, NULL, TLV_CODE_MAC_BASE); + if (!IS_ERR(eeprom_tlv)) + tlv_entry_get_raw(eeprom_tlv, macbase, ARRAY_SIZE(macbase));
for (i = 0; i < maccount; i++) { if (is_valid_ethaddr(macbase)) { @@ -1103,22 +774,22 @@ int mac_read_from_eeprom(void) int populate_serial_number(void) { char serialstr[257]; - int eeprom_index; + struct tlvinfo_priv *tlv; struct tlvinfo_tlv *eeprom_tlv; int devnum = 0; // TODO: support multiple EEPROMs
if (env_get("serial#")) return 0;
- if (read_eeprom(devnum, eeprom)) { + tlv = tlv_eeprom_read(tlv_eeprom_get_by_index(devnum), 0, eeprom, ARRAY_SIZE(eeprom)); + if (IS_ERR(tlv)) { printf("Read failed.\n"); return -1; }
- if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) { - eeprom_tlv = to_entry(&eeprom[eeprom_index]); - memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length); - serialstr[eeprom_tlv->length] = 0; + eeprom_tlv = tlv_entry_next_by_code(tlv, NULL, TLV_CODE_SERIAL_NUMBER); + if (!IS_ERR(eeprom_tlv)) { + tlv_entry_get_string(eeprom_tlv, serialstr, ARRAY_SIZE(serialstr)); env_set("serial#", serialstr); }
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig index fa86b23ef40..98a87068f59 100644 --- a/configs/clearfog_defconfig +++ b/configs/clearfog_defconfig @@ -35,7 +35,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_I2C=y CONFIG_SYS_MAXARGS=32 -# CONFIG_CMD_TLV_EEPROM is not set +CONFIG_CMD_TLV_EEPROM=y CONFIG_SPL_CMD_TLV_EEPROM=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h index b08c98a5833..e8f07b233c0 100644 --- a/include/tlv_eeprom.h +++ b/include/tlv_eeprom.h @@ -7,153 +7,6 @@ #ifndef __TLV_EEPROM_H_ #define __TLV_EEPROM_H_
-#if !defined(CONFIG_EEPROM_TLV_LIB) && !defined(CONFIG_SPL_EEPROM_TLV_LIB) - -/* - * The Definition of the TlvInfo EEPROM format can be found at onie.org or - * github.com/onie - */ - -/* - * TlvInfo header: Layout of the header for the TlvInfo format - * - * See the end of this file for details of this eeprom format - */ -struct __attribute__ ((__packed__)) tlvinfo_header { - char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ - u8 version; /* 0x08 Structure version */ - u16 totallen; /* 0x09 - 0x0A Length of all data which follows */ -}; - -// Header Field Constants -#define TLV_INFO_ID_STRING "TlvInfo" -#define TLV_INFO_VERSION 0x01 -#define TLV_INFO_MAX_LEN 2048 -#define TLV_TOTAL_LEN_MAX (TLV_INFO_MAX_LEN - \ - sizeof(struct tlvinfo_header)) - -/* - * TlvInfo TLV: Layout of a TLV field - */ -struct __attribute__ ((__packed__)) tlvinfo_tlv { - u8 type; - u8 length; - u8 value[0]; -}; - -/* Maximum length of a TLV value in bytes */ -#define TLV_VALUE_MAX_LEN 255 - -/** - * The TLV Types. - * - * Keep these in sync with tlv_code_list in cmd/tlv_eeprom.c - */ -#define TLV_CODE_PRODUCT_NAME 0x21 -#define TLV_CODE_PART_NUMBER 0x22 -#define TLV_CODE_SERIAL_NUMBER 0x23 -#define TLV_CODE_MAC_BASE 0x24 -#define TLV_CODE_MANUF_DATE 0x25 -#define TLV_CODE_DEVICE_VERSION 0x26 -#define TLV_CODE_LABEL_REVISION 0x27 -#define TLV_CODE_PLATFORM_NAME 0x28 -#define TLV_CODE_ONIE_VERSION 0x29 -#define TLV_CODE_MAC_SIZE 0x2A -#define TLV_CODE_MANUF_NAME 0x2B -#define TLV_CODE_MANUF_COUNTRY 0x2C -#define TLV_CODE_VENDOR_NAME 0x2D -#define TLV_CODE_DIAG_VERSION 0x2E -#define TLV_CODE_SERVICE_TAG 0x2F -#define TLV_CODE_VENDOR_EXT 0xFD -#define TLV_CODE_CRC_32 0xFE - -#if CONFIG_IS_ENABLED(CMD_TLV_EEPROM) - -/** - * read_tlv_eeprom - Read the EEPROM binary data from the hardware - * @eeprom: Pointer to buffer to hold the binary data - * @offset: Offset within EEPROM block to read data from - * @len : Maximum size of buffer - * @dev : EEPROM device to read - * - * Note: this routine does not validate the EEPROM data. - * - */ - -int read_tlv_eeprom(void *eeprom, int offset, int len, int dev); - -/** - * write_tlv_eeprom - Write the entire EEPROM binary data to the hardware - * @eeprom: Pointer to buffer to hold the binary data - * @len : Maximum size of buffer - * @dev : EEPROM device to write - * - * Note: this routine does not validate the EEPROM data. - * - */ -int write_tlv_eeprom(void *eeprom, int len, int dev); - -/** - * read_tlvinfo_tlv_eeprom - Read the TLV from EEPROM, and validate - * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer - * of size at least TLV_INFO_MAX_LEN. - * @hdr : Points to pointer to TLV header (output) - * @first_entry : Points to pointer to first TLV entry (output) - * @dev : EEPROM device to read - * - * Store the raw EEPROM data from EEPROM @dev in the @eeprom buffer. If TLV is - * valid set *@hdr and *@first_entry. - * - * Returns 0 when read from EEPROM is successful, and the data is valid. - * Returns <0 error value when EEPROM read fails. Return -EINVAL when TLV is - * invalid. - * - */ - -int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, - struct tlvinfo_tlv **first_entry, int dev); - -#else /* !CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ - -static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev) -{ - return -ENOSYS; -} - -static inline int write_tlv_eeprom(void *eeprom, int len) -{ - return -ENOSYS; -} - -static inline int -read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, - struct tlvinfo_tlv **first_entry, int dev) -{ - return -ENOSYS; -} - -#endif /* CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ - -/** - * is_valid_tlvinfo_header - * - * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM - * data pointed to by the parameter: - * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" - * 2. Version byte is 1 - * 3. Total length bytes contain value which is less than or equal - * to the allowed maximum (2048-11) - * - */ -static inline bool is_valid_tlvinfo_header(struct tlvinfo_header *hdr) -{ - return ((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && - (hdr->version == TLV_INFO_VERSION) && - (be16_to_cpu(hdr->totallen) <= TLV_TOTAL_LEN_MAX)); -} - -#else - /* * The Definition of the TlvInfo EEPROM format can be found at onie.org or * github.com/onie @@ -421,5 +274,4 @@ int tlv_entry_get_uint32(struct tlvinfo_tlv *entry, u32 *buffer); */ int tlv_entry_set_uint32(struct tlvinfo_tlv *entry, const u32 value);
-#endif #endif /* __TLV_EEPROM_H_ */