From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFF463E866B; Tue, 30 Jun 2026 09:25:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782811545; cv=none; b=gsC7GbhPKf4Y6UZ0ctmIc09IWLryyLRFdGpx7dBLDlIjGb7L3/cboPaPeQSCkiaYXAwR03JzsN2u/X1ziM3JoAssXV1IG+Z3uGaESFsP2eH3VJup5Cei0d/2/M4B23cEKwT002Zb6UsgVhhgf9Ipls3D5PK9QM8LxU2qwhvfTYA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782811545; c=relaxed/simple; bh=eKEUYIBQEhKwXOzUvAoCyNOGzX0WSCoAmeMWd7TtAgs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TG88q+9dsCjhk0aHQA1owKQQp96goCT6Y6IqSoWxiGVkxaNGaugGr2CdL0RKYol9gjbl/le18ZM7j2E1CTknznDDmdWs5RXeV6xE1RIszL82S90UAcggxoEXUacbLzOVJv+WBUHI1Zk9V9qwXROSJIxQzBrDiuTL3yuTCdR9Hsw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=nildlPdx; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="nildlPdx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1782811543; x=1814347543; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eKEUYIBQEhKwXOzUvAoCyNOGzX0WSCoAmeMWd7TtAgs=; b=nildlPdxzUQRplr8KNMHsny5EglBgrKorDn55sUF6bzGHBNVRf9d2a09 NP59lN1qMlqqfY+Edn/Q1QqOCm+72UG6WuPPz0nKIQ6J1C1DUg9KqvfeS GzW5bZCOWiEHcRH/4rEjzf3fETmIhB87zYXDIDm0zBuRlO2cL86+uExQL lTZ2A0YG1JaCA2/GN0CTBBWZqCJbAfTLmSbc1i5/+26+asLyoUkcxn5tZ vLh3Sibz+6HhSl3xv8uSHS3JrO5QWiqc4CWVtY6wMoCPuLGPYUrNXvh6i 6O2vKR0kHukkDyuy/Nh0S6S1SYEFbFHnba+mO9XZ+fvmzGDQG+IpvwANL w==; X-CSE-ConnectionGUID: rRbGhdQuSX65s4SOjtefIA== X-CSE-MsgGUID: lXY7/63OQ8CSbfDKqniurQ== X-IronPort-AV: E=Sophos;i="6.24,233,1774335600"; d="scan'208";a="291266492" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Jun 2026 02:25:42 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex3.mchp-main.com (10.10.87.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.43; Tue, 30 Jun 2026 02:25:41 -0700 Received: from che-ll-i67131.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.58 via Frontend Transport; Tue, 30 Jun 2026 02:25:30 -0700 From: Manikandan Muralidharan To: , , , , , , , , , , , , , , , , , , , , , , CC: Manikandan Muralidharan Subject: [PATCH v4 4/7] nvmem: layouts: add Microchip/SST SFDP EUI layout driver Date: Tue, 30 Jun 2026 14:54:03 +0530 Message-ID: <20260630092406.150587-5-manikandan.m@microchip.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260630092406.150587-1-manikandan.m@microchip.com> References: <20260630092406.150587-1-manikandan.m@microchip.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain Add an NVMEM layout that exposes the factory-programmed EUI-48 identifier from the Microchip/SST vendor SFDP parameter table (e.g. SST26VF064BEUI) as a "mac-address" cell, for use as a network MAC address. The vendor table is located at runtime via the SFDP NVMEM device (no offset in DT), and a read_post_process callback reverses the LSB-first bytes into canonical MAC order. Binds to an "nvmem-layout" node with compatible "microchip,sst26vf-sfdp-eui". Signed-off-by: Manikandan Muralidharan --- MAINTAINERS | 6 + drivers/nvmem/layouts/Kconfig | 10 ++ drivers/nvmem/layouts/Makefile | 1 + drivers/nvmem/layouts/sst26vf-sfdp-eui.c | 182 +++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 drivers/nvmem/layouts/sst26vf-sfdp-eui.c diff --git a/MAINTAINERS b/MAINTAINERS index 15011f5752a9..dc3411b0c3b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17812,6 +17812,12 @@ F: Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml F: drivers/misc/atmel-ssc.c F: include/linux/atmel-ssc.h +MICROCHIP SST SFDP EUI NVMEM LAYOUT DRIVER +M: Manikandan Muralidharan +S: Maintained +F: Documentation/devicetree/bindings/nvmem/layouts/microchip,sst26vf-sfdp-eui.yaml +F: drivers/nvmem/layouts/sst26vf-sfdp-eui.c + Microchip Timer Counter Block (TCB) Capture Driver M: Kamel Bouhara L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) diff --git a/drivers/nvmem/layouts/Kconfig b/drivers/nvmem/layouts/Kconfig index 5e586dfebe47..855c7db530da 100644 --- a/drivers/nvmem/layouts/Kconfig +++ b/drivers/nvmem/layouts/Kconfig @@ -26,6 +26,16 @@ config NVMEM_LAYOUT_ONIE_TLV If unsure, say N. +config NVMEM_LAYOUT_SST26VF_SFDP_EUI + tristate "Microchip/SST SFDP EUI-48 layout support" + help + Say Y here if you want to expose the factory-programmed EUI-48 + identifier stored in the Microchip/SST vendor-specific SFDP parameter + table (e.g. SST26VF064BEUI) as NVMEM cells, so that network drivers + can use them as a MAC address. + + If unsure, say N. + config NVMEM_LAYOUT_U_BOOT_ENV tristate "U-Boot environment variables layout" select CRC32 diff --git a/drivers/nvmem/layouts/Makefile b/drivers/nvmem/layouts/Makefile index 4940c9db0665..b99eac1f63f2 100644 --- a/drivers/nvmem/layouts/Makefile +++ b/drivers/nvmem/layouts/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o +obj-$(CONFIG_NVMEM_LAYOUT_SST26VF_SFDP_EUI) += sst26vf-sfdp-eui.o obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o diff --git a/drivers/nvmem/layouts/sst26vf-sfdp-eui.c b/drivers/nvmem/layouts/sst26vf-sfdp-eui.c new file mode 100644 index 000000000000..641318d6f0af --- /dev/null +++ b/drivers/nvmem/layouts/sst26vf-sfdp-eui.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * NVMEM layout for the factory-programmed EUI-48 identifier stored in the + * Microchip/SST vendor-specific SFDP parameter table (e.g. SST26VF064BEUI). + * + * The whole SFDP is exposed as a read-only NVMEM device by the SPI NOR core. + * This layout locates the Microchip vendor parameter table at runtime and + * registers the EUI-48 address as an NVMEM cell, so that a network driver can + * consume it as a MAC address. No offset is hardcoded in the device tree. + * + * Copyright (C) 2026 Microchip Technology Inc. and its subsidiaries + * + * Author: Manikandan Muralidharan + */ + +#include +#include +#include +#include +#include +#include +#include + +/* SFDP header and parameter header, as laid out on the flash. */ +struct sfdp_header { + u8 signature[4]; + u8 minor; + u8 major; + u8 nph; + u8 unused; +}; + +struct sfdp_parameter_header { + u8 id_lsb; + u8 minor; + u8 major; + u8 length; + u8 parameter_table_pointer[3]; + u8 id_msb; +}; + +#define SFDP_SIGNATURE 0x50444653U + +#define SFDP_PARAM_HEADER_ID(h) (((h)->id_msb << 8) | (h)->id_lsb) +#define SFDP_PARAM_HEADER_PTP(h) get_unaligned_le24((h)->parameter_table_pointer) + +/* Microchip (vendor) parameter table identifier: id_msb << 8 | id_lsb. */ +#define SFDP_MCHP_VENDOR_ID 0x01bf + +#define SFDP_MCHP_EUI48_MARKER_OFFSET 0x60 +#define SFDP_MCHP_EUI48_MARKER 0x30 +#define SFDP_MCHP_EUI48_OFFSET 0x61 + +static int sfdp_eui_read_post_process(void *priv, const char *id, int index, + unsigned int offset, void *buf, + size_t bytes) +{ + u8 *data = buf; + int i; + + /* SFDP stores the address least-significant octet first; reverse it. */ + for (i = 0; i < bytes / 2; i++) + swap(data[i], data[bytes - 1 - i]); + + if (bytes == ETH_ALEN && !is_valid_ether_addr(buf)) + return -EINVAL; + + return 0; +} + +static int sfdp_eui_find_vendor_table(struct nvmem_device *nvmem, u32 *ptp) +{ + struct sfdp_parameter_header ph; + struct sfdp_header hdr; + int nph, i, ret; + + ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); + if (ret < 0) + return ret; + + if (get_unaligned_le32(hdr.signature) != SFDP_SIGNATURE) + return -EINVAL; + + /* The number of parameter headers (NPH) field is zero-based. */ + nph = hdr.nph; + + for (i = 0; i <= nph; i++) { + ret = nvmem_device_read(nvmem, sizeof(hdr) + i * sizeof(ph), + sizeof(ph), &ph); + if (ret < 0) + return ret; + + if (SFDP_PARAM_HEADER_ID(&ph) != SFDP_MCHP_VENDOR_ID) + continue; + + *ptp = SFDP_PARAM_HEADER_PTP(&ph); + return 0; + } + + return -ENOENT; +} + +static int sfdp_eui_add_cells(struct nvmem_layout *layout) +{ + struct nvmem_device *nvmem = layout->nvmem; + struct device *dev = &layout->dev; + struct nvmem_cell_info info = { }; + struct device_node *layout_np; + u32 base = 0; + u8 marker; + int ret; + + ret = sfdp_eui_find_vendor_table(nvmem, &base); + if (ret == -ENOENT) { + dev_dbg(dev, "no Microchip SFDP vendor table found\n"); + return 0; + } + if (ret) + return ret; + + /* The EUI-48 is present only if its marker byte is programmed. */ + ret = nvmem_device_read(nvmem, base + SFDP_MCHP_EUI48_MARKER_OFFSET, + 1, &marker); + if (ret < 0) + return ret; + if (marker != SFDP_MCHP_EUI48_MARKER) { + dev_dbg(dev, "EUI-48 not programmed (marker 0x%02x)\n", marker); + return 0; + } + + layout_np = of_nvmem_layout_get_container(nvmem); + if (!layout_np) + return -ENOENT; + + info.name = "mac-address"; + info.offset = base + SFDP_MCHP_EUI48_OFFSET; + info.bytes = ETH_ALEN; + info.np = of_get_child_by_name(layout_np, "mac-address"); + info.read_post_process = sfdp_eui_read_post_process; + + ret = nvmem_add_one_cell(nvmem, &info); + if (ret) + of_node_put(info.np); + else + dev_dbg(dev, "exposed EUI-48 at SFDP offset 0x%x\n", info.offset); + + of_node_put(layout_np); + + return ret; +} + +static int sfdp_eui_probe(struct nvmem_layout *layout) +{ + layout->add_cells = sfdp_eui_add_cells; + + return nvmem_layout_register(layout); +} + +static void sfdp_eui_remove(struct nvmem_layout *layout) +{ + nvmem_layout_unregister(layout); +} + +static const struct of_device_id sfdp_eui_of_match_table[] = { + { .compatible = "microchip,sst26vf-sfdp-eui" }, + {} +}; +MODULE_DEVICE_TABLE(of, sfdp_eui_of_match_table); + +static struct nvmem_layout_driver sfdp_eui_layout = { + .driver = { + .name = "microchip-sst26vf-sfdp-eui-layout", + .of_match_table = sfdp_eui_of_match_table, + }, + .probe = sfdp_eui_probe, + .remove = sfdp_eui_remove, +}; +module_nvmem_layout_driver(sfdp_eui_layout); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Manikandan Muralidharan "); +MODULE_DESCRIPTION("NVMEM layout for the EUI-48 in the Microchip/SST SFDP vendor table"); -- 2.43.0