adde0ffc4b1786ef8d82d36c893c008f0fe11035
[openwrt/staging/ldir.git] /
1 From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
3 Date: Tue, 4 Apr 2023 18:21:43 +0100
4 Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 U-Boot environment variables are stored in ASCII format so "ethaddr"
10 requires parsing into binary to make it work with Ethernet interfaces.
11
12 This includes support for indexes to support #nvmem-cell-cells = <1>.
13
14 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
15 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
16 Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org
17 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18 ---
19 drivers/nvmem/Kconfig | 1 +
20 drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++
21 2 files changed, 27 insertions(+)
22
23 --- a/drivers/nvmem/Kconfig
24 +++ b/drivers/nvmem/Kconfig
25 @@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV
26 tristate "U-Boot environment variables support"
27 depends on OF && MTD
28 select CRC32
29 + select GENERIC_NET_UTILS
30 help
31 U-Boot stores its setup as environment variables. This driver adds
32 support for verifying & exporting such data. It also exposes variables
33 --- a/drivers/nvmem/u-boot-env.c
34 +++ b/drivers/nvmem/u-boot-env.c
35 @@ -4,6 +4,8 @@
36 */
37
38 #include <linux/crc32.h>
39 +#include <linux/etherdevice.h>
40 +#include <linux/if_ether.h>
41 #include <linux/mod_devicetable.h>
42 #include <linux/module.h>
43 #include <linux/mtd/mtd.h>
44 @@ -70,6 +72,25 @@ static int u_boot_env_read(void *context
45 return 0;
46 }
47
48 +static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
49 + unsigned int offset, void *buf, size_t bytes)
50 +{
51 + u8 mac[ETH_ALEN];
52 +
53 + if (bytes != 3 * ETH_ALEN - 1)
54 + return -EINVAL;
55 +
56 + if (!mac_pton(buf, mac))
57 + return -EINVAL;
58 +
59 + if (index)
60 + eth_addr_add(mac, index);
61 +
62 + ether_addr_copy(buf, mac);
63 +
64 + return 0;
65 +}
66 +
67 static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
68 size_t data_offset, size_t data_len)
69 {
70 @@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u
71 priv->cells[idx].offset = data_offset + value - data;
72 priv->cells[idx].bytes = strlen(value);
73 priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
74 + if (!strcmp(var, "ethaddr")) {
75 + priv->cells[idx].raw_len = strlen(value);
76 + priv->cells[idx].bytes = ETH_ALEN;
77 + priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
78 + }
79 }
80
81 if (WARN_ON(idx != priv->ncells))