1 From: Yousong Zhou <yszhou4tech@gmail.com>
2 Subject: [PATCH] of: net: add nvmem cell mac-address-ascii support
4 This is needed for devices with mac address stored in ascii format,
5 e.g. HiWiFi HC6361 to be ported in the following patch.
7 Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
9 net/core/of_net.c | 83 ++++++++++++------
10 1 files changed, 72 insertions(+), 11 deletions(-)
12 --- a/net/core/of_net.c
13 +++ b/net/core/of_net.c
14 @@ -57,13 +57,70 @@ static int of_get_mac_addr(struct device
18 +static void *nvmem_cell_get_mac_address(struct nvmem_cell *cell)
23 + mac = nvmem_cell_read(cell, &len);
26 + if (len != ETH_ALEN) {
28 + return ERR_PTR(-EINVAL);
33 +static void *nvmem_cell_get_mac_address_ascii(struct nvmem_cell *cell)
40 + mac_ascii = nvmem_cell_read(cell, &len);
41 + if (IS_ERR(mac_ascii))
43 + if (len != ETH_ALEN*2+5) {
45 + return ERR_PTR(-EINVAL);
47 + mac = kmalloc(ETH_ALEN, GFP_KERNEL);
50 + return ERR_PTR(-ENOMEM);
52 + ret = sscanf(mac_ascii, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
53 + &mac[0], &mac[1], &mac[2],
54 + &mac[3], &mac[4], &mac[5]);
56 + if (ret == ETH_ALEN)
59 + return ERR_PTR(-EINVAL);
62 +static struct nvmem_cell_mac_address_property {
64 + void *(*read)(struct nvmem_cell *);
65 +} nvmem_cell_mac_address_properties[] = {
67 + .name = "mac-address",
68 + .read = nvmem_cell_get_mac_address,
70 + .name = "mac-address-ascii",
71 + .read = nvmem_cell_get_mac_address_ascii,
75 static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
77 struct platform_device *pdev = of_find_device_by_node(np);
78 + struct nvmem_cell_mac_address_property *property;
79 struct nvmem_cell *cell;
85 /* Try lookup by device first, there might be a nvmem_cell_lookup
86 * associated with a given device.
87 @@ -74,17 +131,26 @@ static int of_get_mac_addr_nvmem(struct
91 - cell = of_nvmem_cell_get(np, "mac-address");
92 + for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
93 + property = &nvmem_cell_mac_address_properties[i];
94 + cell = of_nvmem_cell_get(np, property->name);
95 + /* For -EPROBE_DEFER don't try other properties.
96 + * We'll get back to this one.
98 + if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
103 return PTR_ERR(cell);
105 - mac = nvmem_cell_read(cell, &len);
106 + mac = property->read(cell);
107 nvmem_cell_put(cell);
112 - if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
113 + if (!is_valid_ether_addr(mac)) {