From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6AA4FC77B7F for ; Tue, 16 May 2023 11:43:11 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 64F378664A; Tue, 16 May 2023 13:42:35 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=solid-run.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=solidrn.onmicrosoft.com header.i=@solidrn.onmicrosoft.com header.b="X63u8UYv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9A92D86647; Tue, 16 May 2023 13:42:33 +0200 (CEST) Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2061d.outbound.protection.outlook.com [IPv6:2a01:111:f400:7e1b::61d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7F37A86640 for ; Tue, 16 May 2023 13:42:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=solid-run.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=josua@solid-run.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=j5UDbW5/lvA8nOmA59TdmtjdkfUyJSOeUfN9GRKa6MkOy1BojPOYhB3SU4srcQ4ntkiAe9drJYu2Zw2wQJwBARkSEHrfEPrsDUij2EgUulECb726ZkwWuHUXaNSxxZsTHVIolyYEFPHdR4xoSMf63Nh9v5e3sCFvbfFhscZjKAeuUkXpds/d27fqq1th8SZsbihNa3bVEgb+8A7V5VhpZxjYqpFM2B/q5BQRg7PUAqnpioVwPRIqpKNNRKP+7Mrh0ssDq+GpQI9Vq65aC4kZBMR8mNceY6Wn8zma8aldLPc9S5VTZ35vYHh/HZTFDYdmTRp14PqduSBSW63JM9ywRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Dzi+EOeqGMpzmDsxXI1EU5tINk6QW7k1jusHn6dsfU0=; b=k53404OOoU/B6ySPHHjlDFmAL0cTA29snyZJwfUupEtgpqFaAveiNK1EL3SsEUA21OrG981VKWrMymwlTeWFxq0DIiKJXfE8Nzu+afqaylx47Ik0/2+fKi017lyLvQZz5tQyJ0lrByuNW6hsaTvA8n8XWW1b+JgvESW3VbKOqZL+h5gTM/fLTqNqp56Bcl9i8Up7EaZQrPFNvf0Qpsb/GSaKw/05ADxhxtBO1YKmi69ww+BFGf6UUVb8G8lUxcNVeeS/4PDIEjS9YK8iYl/Q5z5F0vdo6dZLTBiApXjgXoyDwMPr0FUeR7L2dUJEcgc3DHISqQOXo6ROu/OnGvXgUQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=solid-run.com; dmarc=pass action=none header.from=solid-run.com; dkim=pass header.d=solid-run.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=solidrn.onmicrosoft.com; s=selector1-solidrn-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Dzi+EOeqGMpzmDsxXI1EU5tINk6QW7k1jusHn6dsfU0=; b=X63u8UYvz1f9ByqQM1TotqEC30onQDIvixnChF2CWrlUyawk89A4OCJvb2YGSK3PH7kbyffxhsEbBVBjeci9dWQqoI340Fo2nIQ9axdWz3AerNtOmra5TdeHzEoA23PMQ1kWeCuhMeIrG9i9b8E1dSoMQnoKInG2rkeDmcDo3i0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=solid-run.com; Received: from AS8PR04MB8963.eurprd04.prod.outlook.com (2603:10a6:20b:42e::18) by PA4PR04MB9270.eurprd04.prod.outlook.com (2603:10a6:102:2a5::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6387.30; Tue, 16 May 2023 11:42:24 +0000 Received: from AS8PR04MB8963.eurprd04.prod.outlook.com ([fe80::9e27:8c41:a8d:938e]) by AS8PR04MB8963.eurprd04.prod.outlook.com ([fe80::9e27:8c41:a8d:938e%6]) with mapi id 15.20.6387.032; Tue, 16 May 2023 11:42:24 +0000 From: Josua Mayer To: u-boot@lists.denx.de Cc: Josua Mayer Subject: [RFC v2 3/3] cmd: tlv_eeprom: port to new shared tlv library Date: Tue, 16 May 2023 14:41:53 +0300 Message-Id: <20230516114153.3896-4-josua@solid-run.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230516114153.3896-1-josua@solid-run.com> References: <20230516114153.3896-1-josua@solid-run.com> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: FR2P281CA0143.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:98::16) To AS8PR04MB8963.eurprd04.prod.outlook.com (2603:10a6:20b:42e::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8PR04MB8963:EE_|PA4PR04MB9270:EE_ X-MS-Office365-Filtering-Correlation-Id: f05531b6-8f0d-4154-2bbe-08db56029de6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: tncxWo2AoehEjzLQ+rVyfdhMZIRf96Jyg+b9BAXh57GQav3KNW6fX6La8/poysX2X6K4ekAp+1Cj2nJMltwX4L7HJ/EnxY3GuVZFoeX3EcqhAK+rDwgPJyKLuAUBAKfgUHXlVlr6xlsOmWOr+PDFava/NtJfmrBIXz8c5RbWYhOHj46rHtx62gtc+vM9Ff881jSGmm2g/j04whIfTPXxExymGZVxwrnU8JnwEDuLBVqxYUigVgzFTXHsUt4gxGhmFm8WMOjv6XHd1bLPhwcgYOxK0I6Pd16ZVSsrq09bns4rSkYYEiKzZFxgKYRNKad9Ado+y+5px7G0+HK30+yIxL6i6NxLDHIWd7NfeMgm2rS87IeIJe+4tkYVo+MjFha8VkuL5cnJiY2iSjLD40fS5Th/wr0AOQFZJbp+i7SZmm9fFwyCfJ6mZn4Ek2VriaB1QSBtbuZvyCKsaHN2e//NBYgSFOQZtnWQu0GEcgKunHjzEpgPS9O5SGpoUi78tYwlcYNPiaDNlkHbipuM//MmIDkgqkMtAx9Z9voTg+XMtVw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AS8PR04MB8963.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230028)(376002)(39840400004)(136003)(366004)(346002)(396003)(451199021)(83380400001)(478600001)(52116002)(6666004)(6512007)(6486002)(2616005)(1076003)(107886003)(186003)(6506007)(2906002)(30864003)(36756003)(6916009)(4326008)(38100700002)(66556008)(66476007)(66946007)(8936002)(41300700001)(316002)(5660300002)(84970400001)(8676002)(86362001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?I6n+Bjpex00f7NZzg8j2qGO5u4YtqvtAR4v50k1OWFFLqgCtdI0o9fcDbZBw?= =?us-ascii?Q?qGtVBjMSZn0MUy7O1daDeXKppo9eLLFc2dnaHCDLJDJ6UZsCqTH4uCAKgVMT?= =?us-ascii?Q?AVkN/6qKw1452P4zkeQnhtFaIAaxrvpB1wNBbT2uMHzHKXFrHAquvAxyi9bs?= =?us-ascii?Q?f/TW96VhmVjd60WoKpVPF4N/UOUDkHyYKazF9wyCIcaWhditIq9UGCfrGQhh?= =?us-ascii?Q?wn/V2SUnGxRnVKoyTrdFuzaFur6y9qeLT9P5kUys/1/LYlCvRbrrTMeIyj88?= =?us-ascii?Q?5NhTrnbwSMvs3hrahV4rnWZtgsEx6rfmnYjeEv57uxDF61vLj9sBvT4zQ5V7?= =?us-ascii?Q?32nAz8RIqsRMRVvATx/ir/7niTIoRE4pQdIKlINDz7MiaQwxPI8diJw3/XGm?= =?us-ascii?Q?YDFgfOANBG2bV/BU22hQENOiciUPrZq0i5eiH3AKcn2tRus0TKjzEjGLP1Ws?= =?us-ascii?Q?kXI1qAM9j4kCQr/BlisjgJgsVkwxUS5efnM+bJvE99xqQ+DDiHRg/Sa2MGLR?= =?us-ascii?Q?znK0bGx/GxbQrJ6atP4Ta4+8rlwGclimrpy9Viryce0PNL+oGMjMEHf00iV6?= =?us-ascii?Q?CXddEm9fizz0frsF0vKWKy3HNUDCVu0U8sCoEtWeqVSFBAR9ItSDziztdU2S?= =?us-ascii?Q?eQkpPzKCMHB87sqh3go2UHdYfP2bEAKSlh+S8LQ8d4yajR5Dgb4pngIxSObg?= =?us-ascii?Q?JR0IbpHqoGhhz/wjbzXRjkkkLhhpewfZZPfaJpzeoSbW0HEF7gP/2EUVw3PJ?= =?us-ascii?Q?qLwEU9zPWhF5TtstnIfCCk3kXSdCfalSAuUtKApLtJ3YxpZgfpqHRVfdGCnZ?= =?us-ascii?Q?uapot9uL3zrGSxGWK3WcLCvJJoamadY1v4LO+uHr66Azi+6rML0FEVDBxr57?= =?us-ascii?Q?GNrx4LkGy+yIhf6ZaOtc7a6JwYXW9B8UVowDYjYdHukkK0AGzrOVc7/uwJhz?= =?us-ascii?Q?p4CTRrlm74XnGgCYSTs2eQcXUM9tuAjxjsZjk9UVYCeZgP0wLswYRbclOzry?= =?us-ascii?Q?uHkJ546Q02WNXuAz9M44v+rjUad9VszYsunjElNv18Nhawv/TmQ2TurtapZy?= =?us-ascii?Q?kEyAsNBkABZKCyt9tV1O1rel2dPUQBLnOsYhYqV/h4MvvCUbSUSCrA5vdOiQ?= =?us-ascii?Q?doKx2o74yqw8/PsLa3mk3A2venw/RzfP+6MyxUb3UgeZ9292mogyqevBw84h?= =?us-ascii?Q?CezkmeH7zJhI9lw1s9U1Xakx4PhilP5qIzMmjbPegkp4DydoQjnT8KXUzNkk?= =?us-ascii?Q?z3lmfCxzuPVwBeEkdKLUDZwdtgYKr0qjWsvzCMvIMWKuhg7WUkgmNM8bEtUT?= =?us-ascii?Q?j4RAY44eVgqNcTDBM9Ied1hFvJxSJGSTAI8f8+WXPjPtxDOvppw8GekAFZzp?= =?us-ascii?Q?LKsQ7UXqb2H9wqRo3fv/TfDUcO66mX+hu0aIpA4LDM4/4nQzql52tScbhNyW?= =?us-ascii?Q?74Z6wkZeXlO1c6QYA8hJ9hErNi2FNYafiuFSM1mmSy6cGBoilanYgclIPbgi?= =?us-ascii?Q?U2vOyiBvzeCQC5/JshnYkreUu/ey4oHPZWn9dzk01cetxv+Y5ARQkC7HWEBM?= =?us-ascii?Q?DOktKiITEveBkFOY/OFYReuvVsA4yBTvyVmPvWGsEc32N3MVq5DlNH56YeBi?= =?us-ascii?Q?+WSEDnN6G4Gvr/AIzqQfoNM=3D?= X-OriginatorOrg: solid-run.com X-MS-Exchange-CrossTenant-Network-Message-Id: f05531b6-8f0d-4154-2bbe-08db56029de6 X-MS-Exchange-CrossTenant-AuthSource: AS8PR04MB8963.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 May 2023 11:42:24.6111 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a4a8aaf3-fd27-4e27-add2-604707ce5b82 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Ln513A5Xnwy1NPNeRDefanNFgUoFPrbzJ1WRYU7J6iX4ArHFUyPgahO5JCCzvSA0WUiFSV7WElv3DAp0CsUEmg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PA4PR04MB9270 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 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 --- 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 * Copyright (C) 2013 Miles Tseng * Copyright (C) 2014,2016 david_yang + * Copyright (C) 2023 Josua Mayer */ -#include #include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include - -#include "tlv_eeprom.h" +#include +#include +#include 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