All of lore.kernel.org
 help / color / mirror / Atom feed
From: Josua Mayer <josua@solid-run.com>
To: u-boot@lists.denx.de
Cc: Josua Mayer <josua@solid-run.com>
Subject: [RFC v2 3/3] cmd: tlv_eeprom: port to new shared tlv library
Date: Tue, 16 May 2023 14:41:53 +0300	[thread overview]
Message-ID: <20230516114153.3896-4-josua@solid-run.com> (raw)
In-Reply-To: <20230516114153.3896-1-josua@solid-run.com>

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_ */
-- 
2.35.3


      parent reply	other threads:[~2023-05-16 11:43 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-16 11:41 [RFC v2 0/3] lib: tlv_eeprom: refactor API Josua Mayer
2023-05-16 11:41 ` [RFC v2 1/3] lib: add tlv_eeprom library Josua Mayer
2023-05-16 11:41 ` [RFC v2 2/3] mvebu: clearfog: convert tlv parsing to use new library Josua Mayer
2023-05-16 11:41 ` Josua Mayer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230516114153.3896-4-josua@solid-run.com \
    --to=josua@solid-run.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.