[PATCH u-boot-marvell 08/16] arm: mvebu: turris_omnia: Implement EEPROM layout for the 'eeprom' command

Marek Behún kabel at kernel.org
Tue Jun 18 17:34:31 CEST 2024


Implement Turris Omnia EEPROM layout for the 'eeprom' command.

When the 'eeprom' command (with layout support) is enabled, we can now
use the 'eeprom print' and 'eeprom update' commands, for example:

  => eeprom print
  Magic constant                34a04103
  RAM size in GB                2
  Wi-Fi Region
  CRC32 checksum                cecbc2a1

Signed-off-by: Marek Behún <kabel at kernel.org>
---
 board/CZ.NIC/turris_omnia/Makefile |   1 +
 board/CZ.NIC/turris_omnia/eeprom.c | 109 +++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+)
 create mode 100644 board/CZ.NIC/turris_omnia/eeprom.c

diff --git a/board/CZ.NIC/turris_omnia/Makefile b/board/CZ.NIC/turris_omnia/Makefile
index 341378b4e5..216e11958a 100644
--- a/board/CZ.NIC/turris_omnia/Makefile
+++ b/board/CZ.NIC/turris_omnia/Makefile
@@ -3,3 +3,4 @@
 # Copyright (C) 2017 Marek Behún <kabel at kernel.org>
 
 obj-y	:= turris_omnia.o ../turris_atsha_otp.o ../turris_common.o
+obj-$(CONFIG_CMD_EEPROM_LAYOUT)	+= eeprom.o
diff --git a/board/CZ.NIC/turris_omnia/eeprom.c b/board/CZ.NIC/turris_omnia/eeprom.c
new file mode 100644
index 0000000000..a4f1dab469
--- /dev/null
+++ b/board/CZ.NIC/turris_omnia/eeprom.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Marek Behún <kabel at kernel.org>
+ */
+
+#include <asm/unaligned.h>
+#include <ctype.h>
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <eeprom_field.h>
+#include <eeprom_layout.h>
+#include <u-boot/crc.h>
+
+#define _DEF_FIELD(_n, _s, _t) \
+	{ _n, _s, NULL, eeprom_field_print_ ## _t, eeprom_field_update_ ## _t }
+
+static void eeprom_field_print_ramsz(const struct eeprom_field *field)
+{
+	printf(PRINT_FIELD_SEGMENT, field->name);
+	printf("%u\n", get_unaligned_le32(field->buf));
+}
+
+static int eeprom_field_update_ramsz(struct eeprom_field *field, char *value)
+{
+	u32 sz;
+
+	if (value[0] == '1' || value[0] == '2' || value[0] == '4')
+		sz = value[0] - '0';
+	else
+		return -1;
+
+	if (value[1] != '\0')
+		return -1;
+
+	put_unaligned_le32(sz, field->buf);
+
+	return 0;
+}
+
+static void eeprom_field_print_region(const struct eeprom_field *field)
+{
+	eeprom_field_print_ascii(field);
+}
+
+static int eeprom_field_update_region(struct eeprom_field *field, char *value)
+{
+	if (strlen(value) != 2) {
+		printf("%s: has to be 2 characters\n", field->name);
+		return -1;
+	}
+
+	memcpy(field->buf, value, 2);
+	memset(&field->buf[2], '\0', 2);
+
+	return 0;
+}
+
+static struct eeprom_field omnia_layout[] = {
+	_DEF_FIELD("Magic constant", 4, bin),
+	_DEF_FIELD("RAM size in GB", 4, ramsz),
+	_DEF_FIELD("Wi-Fi Region", 4, region),
+	_DEF_FIELD("CRC32 checksum", 4, bin),
+};
+
+static struct eeprom_field *crc_field = &omnia_layout[3];
+
+static int omnia_update_field(struct eeprom_layout *layout, char *field_name,
+			      char *new_data)
+{
+	struct eeprom_field *field;
+	int err;
+
+	if (!new_data)
+		return 0;
+
+	if (!field_name)
+		return -1;
+
+	field = eeprom_layout_find_field(layout, field_name, true);
+	if (!field)
+		return -1;
+
+	err = field->update(field, new_data);
+	if (err) {
+		printf("Invalid data for field %s\n", field_name);
+		return err;
+	}
+
+	if (field < crc_field) {
+		u32 crc = crc32(0, layout->data, 12);
+		put_unaligned_le32(crc, crc_field->buf);
+	}
+
+	return 0;
+}
+
+void eeprom_layout_assign(struct eeprom_layout *layout, int)
+{
+	layout->fields = omnia_layout;
+	layout->num_of_fields = ARRAY_SIZE(omnia_layout);
+	layout->update = omnia_update_field;
+	layout->data_size = 16;
+}
+
+int eeprom_layout_detect(unsigned char *)
+{
+	/* Turris Omnia has only one version of EEPROM layout */
+	return 0;
+}
-- 
2.44.2



More information about the U-Boot mailing list