All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marek Behún" <kabel@kernel.org>
To: Stefan Roese <sr@denx.de>
Cc: u-boot@lists.denx.de, "Marek Behún" <kabel@kernel.org>
Subject: [PATCH u-boot-mvebu v2 05/18] arm: mvebu: turris_omnia: Implement getting board information from MCU
Date: Sat, 23 Mar 2024 19:06:58 +0100	[thread overview]
Message-ID: <20240323180711.5498-6-kabel@kernel.org> (raw)
In-Reply-To: <20240323180711.5498-1-kabel@kernel.org>

Implement reading board serial number, first MAC address and board
version from MCU. MCU supports board information if the FEAT_BOARD_INFO
feature bit is set in MCU features.

Prefer getting board information from MCU if supported, fallback to
Atmel SHA chip.

Signed-off-by: Marek Behún <kabel@kernel.org>
---
 board/CZ.NIC/turris_atsha_otp.c          | 27 +------
 board/CZ.NIC/turris_omnia/Makefile       |  2 +-
 board/CZ.NIC/turris_omnia/turris_omnia.c | 94 +++++++++++++++++++++++-
 3 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/board/CZ.NIC/turris_atsha_otp.c b/board/CZ.NIC/turris_atsha_otp.c
index a29fe36231..85eebcdf18 100644
--- a/board/CZ.NIC/turris_atsha_otp.c
+++ b/board/CZ.NIC/turris_atsha_otp.c
@@ -11,6 +11,7 @@
 #include <atsha204a-i2c.h>
 
 #include "turris_atsha_otp.h"
+#include "turris_common.h"
 
 #define TURRIS_ATSHA_OTP_VERSION	0
 #define TURRIS_ATSHA_OTP_SERIAL		1
@@ -32,26 +33,6 @@ static struct udevice *get_atsha204a_dev(void)
 	return dev;
 }
 
-static void increment_mac(u8 *mac)
-{
-	int i;
-
-	for (i = 5; i >= 3; i--) {
-		mac[i] += 1;
-		if (mac[i])
-			break;
-	}
-}
-
-static void set_mac_if_invalid(int i, u8 *mac)
-{
-	u8 oldmac[6];
-
-	if (is_valid_ethaddr(mac) &&
-	    !eth_env_get_enetaddr_by_index("eth", i, oldmac))
-		eth_env_set_enetaddr_by_index("eth", i, mac);
-}
-
 int turris_atsha_otp_init_mac_addresses(int first_idx)
 {
 	struct udevice *dev = get_atsha204a_dev();
@@ -84,11 +65,7 @@ int turris_atsha_otp_init_mac_addresses(int first_idx)
 	mac[4] = mac1[2];
 	mac[5] = mac1[3];
 
-	set_mac_if_invalid((first_idx + 0) % 3, mac);
-	increment_mac(mac);
-	set_mac_if_invalid((first_idx + 1) % 3, mac);
-	increment_mac(mac);
-	set_mac_if_invalid((first_idx + 2) % 3, mac);
+	turris_init_mac_addresses(first_idx, mac);
 
 	return 0;
 }
diff --git a/board/CZ.NIC/turris_omnia/Makefile b/board/CZ.NIC/turris_omnia/Makefile
index dc39b44ae1..341378b4e5 100644
--- a/board/CZ.NIC/turris_omnia/Makefile
+++ b/board/CZ.NIC/turris_omnia/Makefile
@@ -2,4 +2,4 @@
 #
 # Copyright (C) 2017 Marek Behún <kabel@kernel.org>
 
-obj-y	:= turris_omnia.o ../turris_atsha_otp.o
+obj-y	:= turris_omnia.o ../turris_atsha_otp.o ../turris_common.o
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 6dfde5ee7a..f63640ad64 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -18,6 +18,7 @@
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
+#include <asm/unaligned.h>
 #include <dm/uclass.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <fdt_support.h>
@@ -25,12 +26,14 @@
 #include <time.h>
 #include <turris-omnia-mcu-interface.h>
 #include <linux/bitops.h>
+#include <linux/bitrev.h>
 #include <linux/delay.h>
 #include <u-boot/crc.h>
 
 #include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include <../serdes/a38x/high_speed_env_spec.h>
 #include "../turris_atsha_otp.h"
+#include "../turris_common.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -186,6 +189,70 @@ static bool omnia_mcu_has_feature(u32 feature)
 	return feature & features;
 }
 
+static u32 omnia_mcu_crc32(const void *p, size_t len)
+{
+	u32 val, crc = 0;
+
+	compiletime_assert(!(len % 4), "length has to be a multiple of 4");
+
+	while (len) {
+		val = bitrev32(get_unaligned_le32(p));
+		crc = crc32(crc, (void *)&val, 4);
+		p += 4;
+		len -= 4;
+	}
+
+	return ~bitrev32(crc);
+}
+
+/* Can only be called after relocation, since it needs cleared BSS */
+static int omnia_mcu_board_info(char *serial, u8 *mac, char *version)
+{
+	static u8 reply[17];
+	static bool cached;
+
+	if (!cached) {
+		u8 csum;
+		int ret;
+
+		ret = omnia_mcu_read(CMD_BOARD_INFO_GET, reply, sizeof(reply));
+		if (ret)
+			return ret;
+
+		if (reply[0] != 16)
+			return -EBADMSG;
+
+		csum = reply[16];
+		reply[16] = 0;
+
+		if ((omnia_mcu_crc32(&reply[1], 16) & 0xff) != csum)
+			return -EBADMSG;
+
+		cached = true;
+	}
+
+	if (serial) {
+		const char *serial_env;
+
+		serial_env = env_get("serial#");
+		if (serial_env && strlen(serial_env) == 16) {
+			strcpy(serial, serial_env);
+		} else {
+			sprintf(serial, "%016llX",
+				get_unaligned_le64(&reply[1]));
+			env_set("serial#", serial);
+		}
+	}
+
+	if (mac)
+		memcpy(mac, &reply[9], ETH_ALEN);
+
+	if (version)
+		sprintf(version, "%u", reply[15]);
+
+	return 0;
+}
+
 static void enable_a385_watchdog(unsigned int timeout_minutes)
 {
 	struct sar_freq_modes sar_freq;
@@ -965,13 +1032,23 @@ int board_late_init(void)
 
 int checkboard(void)
 {
-	char serial[17];
+	char serial[17], version[4];
+	bool has_version;
 	int err;
 
-	err = turris_atsha_otp_get_serial_number(serial);
 	printf("  MCU type: %s\n", omnia_get_mcu_type());
 	printf("  MCU version: %s\n", omnia_get_mcu_version());
 	printf("  RAM size: %i MiB\n", omnia_get_ram_size_gb() * 1024);
+
+	if (omnia_mcu_has_feature(FEAT_BOARD_INFO)) {
+		err = omnia_mcu_board_info(serial, NULL, version);
+		has_version = !err;
+	} else {
+		err = turris_atsha_otp_get_serial_number(serial);
+		has_version = false;
+	}
+
+	printf("  Board version: %s\n", has_version ? version : "unknown");
 	printf("  Serial Number: %s\n", !err ? serial : "unknown");
 
 	return 0;
@@ -979,8 +1056,17 @@ int checkboard(void)
 
 int misc_init_r(void)
 {
-	turris_atsha_otp_init_mac_addresses(1);
-	turris_atsha_otp_init_serial_number();
+	if (omnia_mcu_has_feature(FEAT_BOARD_INFO)) {
+		char serial[17];
+		u8 first_mac[6];
+
+		if (!omnia_mcu_board_info(serial, first_mac, NULL))
+			turris_init_mac_addresses(1, first_mac);
+	} else {
+		turris_atsha_otp_init_mac_addresses(1);
+		turris_atsha_otp_init_serial_number();
+	}
+
 	return 0;
 }
 
-- 
2.43.2


  parent reply	other threads:[~2024-03-23 18:08 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-23 18:06 [PATCH u-boot-mvebu v2 00/18] Turris Omnia - New board revision support Marek Behún
2024-03-23 18:06 ` [PATCH u-boot-mvebu v2 01/18] arm: mvebu: turris_omnia: Enable LTO by default on Turris Omnia Marek Behún
2024-03-23 18:06 ` [PATCH u-boot-mvebu v2 02/18] arm: mvebu: turris_omnia: Add header containing MCU command interface and use it Marek Behún
2024-03-23 18:06 ` [PATCH u-boot-mvebu v2 03/18] arm: mvebu: turris_{omnia, mox}: Don't print model two times Marek Behún
2024-03-23 18:06 ` [PATCH u-boot-mvebu v2 04/18] arm: mvebu: turris_omnia: Update MCU status and features reading Marek Behún
2024-03-23 18:06 ` Marek Behún [this message]
2024-03-23 18:06 ` [PATCH u-boot-mvebu v2 06/18] arm: mvebu: turris_omnia: Print board ECDSA public key if available Marek Behún
2024-03-25 17:37   ` Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 07/18] arm: mvebu: turris_omnia: Disable Atmel SHA node if not present Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 08/18] arm: mvebu: spl: Do not build mvebu-reset in SPL Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 09/18] arm: mvebu: system-controller: Rework to use UCLASS_SYSCON Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 10/18] arm: mvebu: system-controller: Select mvebu-reset if DM_RESET && PCI_MVEBU Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 11/18] arm: mvebu: system-controller: Add support for SYSRESET Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 12/18] gpio: turris_omnia_mcu: Use byteorder conversion functions Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 13/18] gpio: turris_omnia_mcu: Update firmware features reading Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 14/18] gpio: turris_omnia_mcu: Add support for system power off via sysreset Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 15/18] arm: mvebu: turris_omnia: Enable poweroff command via sysreset in defconfig Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 16/18] cmd: rng: Print "Abort" on -EINTR Marek Behún
2024-03-23 18:30   ` Heinrich Schuchardt
2024-03-23 18:53     ` Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 17/18] misc: turris_omnia_mcu: Add support for rng provided by MCU Marek Behún
2024-03-23 18:07 ` [PATCH u-boot-mvebu v2 18/18] arm: mvebu: turris_omnia: Enable rng command in defconfig Marek Behún

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=20240323180711.5498-6-kabel@kernel.org \
    --to=kabel@kernel.org \
    --cc=sr@denx.de \
    --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.