From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 13 Jul 2023 18:29:19 +0200 Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used for base MAC address (that can be used for calculating relative addresses). It can be stored in a raw binary format or as an ASCII string. --- --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig NVMEM bool "NVMEM Support" + select GENERIC_NET_UTILS help Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -7,9 +7,11 @@ */ #include +#include #include #include #include +#include #include #include #include @@ -696,6 +698,37 @@ static int nvmem_validate_keepouts(struc return 0; } +static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, + void *buf, size_t bytes) +{ + if (WARN_ON(bytes != ETH_ALEN)) + return -EINVAL; + + if (index) + eth_addr_add(buf, index); + + return 0; +} + +static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, + void *buf, size_t bytes) +{ + u8 mac[ETH_ALEN]; + + if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) + return -EINVAL; + + if (!mac_pton(buf, mac)) + return -EINVAL; + + if (index) + eth_addr_add(mac, index); + + ether_addr_copy(buf, mac); + + return 0; +} + static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) { struct nvmem_layout *layout = nvmem->layout; @@ -731,6 +764,20 @@ static int nvmem_add_cells_from_dt(struc if (layout && layout->fixup_cell_info) layout->fixup_cell_info(nvmem, layout, &info); + if (of_device_is_compatible(np, "fixed-layout")) { + if (of_device_is_compatible(child, "mac-base")) { + if (info.bytes == 6) { + info.raw_len = info.bytes; + info.bytes = ETH_ALEN; + info.read_post_process = nvmem_mac_base_raw_read; + } else if (info.bytes == 3 * ETH_ALEN - 1) { + info.raw_len = info.bytes; + info.bytes = ETH_ALEN; + info.read_post_process = nvmem_mac_base_ascii_read; + } + } + } + ret = nvmem_add_one_cell(nvmem, &info); kfree(info.name); if (ret) {