diff --git a/target/linux/generic/pending-6.6/809-01-nvmem-core-generalize-mac-base-cells-handling.patch b/target/linux/generic/pending-6.6/809-01-nvmem-core-generalize-mac-base-cells-handling.patch index 9cdee61edb0..525f131ea88 100644 --- a/target/linux/generic/pending-6.6/809-01-nvmem-core-generalize-mac-base-cells-handling.patch +++ b/target/linux/generic/pending-6.6/809-01-nvmem-core-generalize-mac-base-cells-handling.patch @@ -1,4 +1,4 @@ -From 995a6e0d3fdd1e4fb38465f224db8a4c7b1e279d Mon Sep 17 00:00:00 2001 +From fd0e523037439520813db7c57df5bd37cdf40f7e Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 3 Feb 2025 00:10:18 +0100 Subject: [PATCH 1/2] nvmem: core: generalize "mac-base" cells handling @@ -13,43 +13,95 @@ exposing a common helper. Such helper will change the nvmem_info_cell and apply the correct post process function to correctly parse the mac address. +Since the API requires OF and is only related to layout, move the +function in layouts.c to correctly handle non-OF NVMEM. + Signed-off-by: Christian Marangi --- - drivers/nvmem/core.c | 41 +++++++++++++++++++--------------- - include/linux/nvmem-provider.h | 4 ++++ - 2 files changed, 27 insertions(+), 18 deletions(-) + drivers/nvmem/core.c | 79 +-------------------------------- + drivers/nvmem/layouts.c | 80 ++++++++++++++++++++++++++++++++++ + include/linux/nvmem-provider.h | 4 ++ + 3 files changed, 86 insertions(+), 77 deletions(-) --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c -@@ -855,6 +855,27 @@ static int nvmem_mac_base_hex_read(void +@@ -7,12 +7,9 @@ + */ + + #include +-#include +-#include + #include + #include + #include +-#include + #include + #include + #include +@@ -799,62 +796,6 @@ static int nvmem_validate_keepouts(struc return 0; } -+void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) -+{ -+ if (!of_device_is_compatible(info->np, "mac-base")) -+ return; -+ -+ if (info->bytes == ETH_ALEN) { -+ info->raw_len = info->bytes; -+ info->bytes = ETH_ALEN; -+ info->read_post_process = nvmem_mac_base_raw_read; -+ } else if (info->bytes == 2 * ETH_ALEN) { -+ info->raw_len = info->bytes; -+ info->bytes = ETH_ALEN; -+ info->read_post_process = nvmem_mac_base_hex_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; -+ } -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_parse_mac_base); -+ +-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_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, +- void *buf, size_t bytes) +-{ +- u8 mac[ETH_ALEN], *hexstr; +- int i; +- +- if (WARN_ON(bytes != 2 * ETH_ALEN)) +- return -EINVAL; +- +- hexstr = (u8 *)buf; +- for (i = 0; i < ETH_ALEN; i++) { +- if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) +- return -EINVAL; +- +- mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); +- } +- +- 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 device *dev = &nvmem->dev; -@@ -894,24 +915,8 @@ static int nvmem_add_cells_from_dt(struc +@@ -894,24 +835,8 @@ static int nvmem_add_cells_from_dt(struc if (nvmem->fixup_dt_cell_info) nvmem->fixup_dt_cell_info(nvmem, &info); @@ -76,6 +128,104 @@ Signed-off-by: Christian Marangi ret = nvmem_add_one_cell(nvmem, &info); kfree(info.name); +--- a/drivers/nvmem/layouts.c ++++ b/drivers/nvmem/layouts.c +@@ -6,8 +6,11 @@ + * Author: Miquel Raynal + #include + #include ++#include ++#include + #include + #include + #include +@@ -21,6 +24,83 @@ + #define to_nvmem_layout_device(_dev) \ + container_of((_dev), struct nvmem_layout, dev) + ++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_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, ++ void *buf, size_t bytes) ++{ ++ u8 mac[ETH_ALEN], *hexstr; ++ int i; ++ ++ if (WARN_ON(bytes != 2 * ETH_ALEN)) ++ return -EINVAL; ++ ++ hexstr = (u8 *)buf; ++ for (i = 0; i < ETH_ALEN; i++) { ++ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) ++ return -EINVAL; ++ ++ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); ++ } ++ ++ if (index) ++ eth_addr_add(mac, index); ++ ++ ether_addr_copy(buf, mac); ++ ++ return 0; ++} ++ ++void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) ++{ ++ if (!of_device_is_compatible(info->np, "mac-base")) ++ return; ++ ++ if (info->bytes == ETH_ALEN) { ++ info->raw_len = info->bytes; ++ info->bytes = ETH_ALEN; ++ info->read_post_process = nvmem_mac_base_raw_read; ++ } else if (info->bytes == 2 * ETH_ALEN) { ++ info->raw_len = info->bytes; ++ info->bytes = ETH_ALEN; ++ info->read_post_process = nvmem_mac_base_hex_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; ++ } ++} ++EXPORT_SYMBOL_GPL(nvmem_layout_parse_mac_base); ++ + static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv) + { + return of_driver_match_device(dev, drv); --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -242,6 +242,8 @@ static inline void nvmem_layout_unregist @@ -91,7 +241,7 @@ Signed-off-by: Christian Marangi #else /* CONFIG_NVMEM && CONFIG_OF */ -+static inline void nvmem_layout_parse_mac_base(void) {} ++static inline void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) {} + static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) { diff --git a/target/linux/generic/pending-6.6/809-02-nvmem-layouts-add-support-for-ascii-env-driver.patch b/target/linux/generic/pending-6.6/809-02-nvmem-layouts-add-support-for-ascii-env-driver.patch index dd4af0f2968..0906e0f725f 100644 --- a/target/linux/generic/pending-6.6/809-02-nvmem-layouts-add-support-for-ascii-env-driver.patch +++ b/target/linux/generic/pending-6.6/809-02-nvmem-layouts-add-support-for-ascii-env-driver.patch @@ -18,8 +18,8 @@ Signed-off-by: Christian Marangi --- drivers/nvmem/layouts/Kconfig | 13 +++ drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/ascii-env.c | 131 ++++++++++++++++++++++++++++++ - 3 files changed, 145 insertions(+) + drivers/nvmem/layouts/ascii-env.c | 140 ++++++++++++++++++++++++++++++ + 3 files changed, 154 insertions(+) create mode 100644 drivers/nvmem/layouts/ascii-env.c --- a/drivers/nvmem/layouts/Kconfig @@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi +obj-$(CONFIG_NVMEM_LAYOUT_ASCII_ENV) += ascii-env.o --- /dev/null +++ b/drivers/nvmem/layouts/ascii-env.c -@@ -0,0 +1,131 @@ +@@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Christian Marangi @@ -65,6 +65,10 @@ Signed-off-by: Christian Marangi +#include +#include + ++struct ascii_env_match_data { ++ const char delim; ++}; ++ +/* + * Parse a buffer as an ASCII text with name delimiter value and each pattern separated + * with a new line char '\n' @@ -86,7 +90,9 @@ Signed-off-by: Christian Marangi + */ + for (var = data; var < data + data_len && *var; + var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; ++ struct nvmem_cell_info info = {}; ++ struct device_node *child; ++ const char *label; + + eq = strchr(var, delim); + if (!eq) @@ -106,6 +112,13 @@ Signed-off-by: Christian Marangi + info.offset = value - data; + info.bytes = strlen(value); + info.np = of_get_child_by_name(dev->of_node, info.name); ++ for_each_child_of_node(dev->of_node, child) { ++ if (!of_property_read_string(child, "label", &label) && ++ !strncmp(info.name, label, info.bytes)) ++ info.np = child; ++ else if (of_node_name_eq(child, info.name)) ++ info.np = child; ++ } + + nvmem_layout_parse_mac_base(&info); + @@ -118,15 +131,15 @@ Signed-off-by: Christian Marangi +static int ascii_env_add_cells(struct nvmem_layout *layout) +{ + struct nvmem_device *nvmem = layout->nvmem; ++ const struct ascii_env_match_data *data; + struct device *dev = &layout->dev; + size_t dev_size; + uint8_t *buf; -+ char delim; + int bytes; + int ret; + + /* Get the delimiter for name value pattern */ -+ delim = device_get_match_data(dev); ++ data = device_get_match_data(dev); + + dev_size = nvmem_dev_size(nvmem); + @@ -146,7 +159,7 @@ Signed-off-by: Christian Marangi + } + + buf[dev_size - 1] = '\0'; -+ ret = ascii_env_parse_cells(dev, nvmem, buf, dev_size, delim); ++ ret = ascii_env_parse_cells(dev, nvmem, buf, dev_size, data->delim); + +err_kfree: + kfree(buf); @@ -166,8 +179,12 @@ Signed-off-by: Christian Marangi + nvmem_layout_unregister(layout); +} + ++static const struct ascii_env_match_data ascii_env_eq = { ++ .delim = '=', ++}; ++ +static const struct of_device_id ascii_env_of_match_table[] = { -+ { .compatible = "ascii-eq-delim-env", .data = (void *)'=', }, ++ { .compatible = "ascii-eq-delim-env", .data = &ascii_env_eq, }, + {}, +}; +