From patchwork Mon Mar 4 15:21:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 1907664 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=U0fPyJa0; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TpMr85nXRz23cm for ; Tue, 5 Mar 2024 02:22:16 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1938D87FB8; Mon, 4 Mar 2024 16:22:02 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="U0fPyJa0"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 02E6987F6E; Mon, 4 Mar 2024 16:22:01 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B15AA87FB8 for ; Mon, 4 Mar 2024 16:21:56 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=kabel@kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 7EAAB60C75; Mon, 4 Mar 2024 15:21:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C151C43390; Mon, 4 Mar 2024 15:21:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1709565715; bh=CPI2gKiG9DChqjU3BXpW/kEvZIAj3lNMnwvG9IhUR7k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U0fPyJa0hCBDKTYyBbtjt6HMuizI+TmQKqnxGXcyF4qNanWVMxuW4atBEb+JhOni/ kNfYZS4T/86zVzZK9We6BF7mdF9nCqzi0aC5d2SbJlUge1VlFHijv8R6Oq/WjfV/ml c2dxXne4jmR6COSW5kIHVEyDkUysV+xBMoUU/iP2UKnRFQIEEJJJL/n2JaI60LG6+h tfi7aIhA8PIkXhC5nMhsjsoxDFP43RBZk9qjRNOIM9HjvZ8Pfvtf7DNo7Tnh2ed7Hd Nb8H6gTIZcvDai/pcABefEO1BtmcmKM3hN/PDx1Osi8Bz6Uq1eBRf+5gtSoe5+2UBY 86/2bZYK2kGjw== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: Stefan Roese Cc: u-boot@lists.denx.de, =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH u-boot-mvebu 2/4] arm: mvebu: turris_omnia: Implement getting board information from MCU Date: Mon, 4 Mar 2024 16:21:46 +0100 Message-ID: <20240304152148.3847-3-kabel@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240304152148.3847-1-kabel@kernel.org> References: <20240304152148.3847-1-kabel@kernel.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean 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 --- board/CZ.NIC/turris_atsha_otp.c | 27 +------ board/CZ.NIC/turris_common.c | 42 ++++++++++ board/CZ.NIC/turris_common.h | 10 +++ board/CZ.NIC/turris_omnia/Makefile | 2 +- board/CZ.NIC/turris_omnia/turris_omnia.c | 98 +++++++++++++++++++++++- 5 files changed, 149 insertions(+), 30 deletions(-) create mode 100644 board/CZ.NIC/turris_common.c create mode 100644 board/CZ.NIC/turris_common.h diff --git a/board/CZ.NIC/turris_atsha_otp.c b/board/CZ.NIC/turris_atsha_otp.c index a29fe362317..85eebcdf18e 100644 --- a/board/CZ.NIC/turris_atsha_otp.c +++ b/board/CZ.NIC/turris_atsha_otp.c @@ -11,6 +11,7 @@ #include #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_common.c b/board/CZ.NIC/turris_common.c new file mode 100644 index 00000000000..1717dda82eb --- /dev/null +++ b/board/CZ.NIC/turris_common.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Marek Behún + */ + +#include +#include + +#include "turris_common.h" + +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); +} + +void turris_init_mac_addresses(int first_idx, const u8 *first_mac) +{ + u8 mac[6]; + + memcpy(mac, first_mac, sizeof(mac)); + + 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); +} diff --git a/board/CZ.NIC/turris_common.h b/board/CZ.NIC/turris_common.h new file mode 100644 index 00000000000..5565ea9fd2a --- /dev/null +++ b/board/CZ.NIC/turris_common.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef TURRIS_COMMON_H +#define TURRIS_COMMON_H + +#include + +void turris_init_mac_addresses(int first_idx, const u8 *first_mac); + +#endif diff --git a/board/CZ.NIC/turris_omnia/Makefile b/board/CZ.NIC/turris_omnia/Makefile index dc39b44ae19..341378b4e54 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 -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 b285e959d06..7a51ed3ace5 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -18,18 +18,21 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #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; @@ -71,6 +74,9 @@ enum mcu_commands { /* available if EXT_CMD bit set in features */ CMD_EXT_CONTROL = 0x12, + + /* available if BOARD_INFO it set in features */ + CMD_BOARD_INFO_GET = 0x2c, }; enum status_word_bits { @@ -88,6 +94,7 @@ enum status_word_bits { enum features_e { FEAT_PERIPH_MCU = BIT(0), FEAT_EXT_CMDS = BIT(1), + FEAT_BOARD_INFO = BIT(15), }; /* CMD_EXT_CONTROL */ @@ -214,6 +221,70 @@ static bool omnia_mcu_has_feature(u16 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; @@ -989,14 +1060,24 @@ 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("Model: Turris Omnia\n"); 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; @@ -1004,8 +1085,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; }