[RFC v2 3/3] cmd: tlv_eeprom: port to new shared tlv library

Josua Mayer josua at solid-run.com
Tue May 16 13:41:53 CEST 2023


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 at 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 at dell.com>
  * Copyright (C) 2013 Miles Tseng <miles_tseng at accton.com>
  * Copyright (C) 2014,2016 david_yang <david_yang at accton.com>
+ * Copyright (C) 2023 Josua Mayer <josua at 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_ */
-- 
2.35.3



More information about the U-Boot mailing list