of: net: support NVMEM cells with MAC in text format
authorRafał Miłecki <rafal@milecki.pl>
Thu, 23 Dec 2021 12:27:47 +0000 (13:27 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Dec 2021 11:32:58 +0000 (11:32 +0000)
Some NVMEM devices have text based cells. In such cases MAC is stored in
a XX:XX:XX:XX:XX:XX format. Use mac_pton() to parse such data and
support those NVMEM cells. This is required to support e.g. a very
popular U-Boot and its environment variables.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/of_net.c

index f1a9bf7578e7a758f1201fcc38c821abbe7fcb03..95a64c813ae59e4dd2199f1d060348d90e72561e 100644 (file)
@@ -61,7 +61,7 @@ static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
 {
        struct platform_device *pdev = of_find_device_by_node(np);
        struct nvmem_cell *cell;
-       const void *mac;
+       const void *buf;
        size_t len;
        int ret;
 
@@ -78,21 +78,32 @@ static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
        if (IS_ERR(cell))
                return PTR_ERR(cell);
 
-       mac = nvmem_cell_read(cell, &len);
+       buf = nvmem_cell_read(cell, &len);
        nvmem_cell_put(cell);
 
-       if (IS_ERR(mac))
-               return PTR_ERR(mac);
-
-       if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
-               kfree(mac);
-               return -EINVAL;
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
+
+       ret = 0;
+       if (len == ETH_ALEN) {
+               if (is_valid_ether_addr(buf))
+                       memcpy(addr, buf, ETH_ALEN);
+               else
+                       ret = -EINVAL;
+       } else if (len == 3 * ETH_ALEN - 1) {
+               u8 mac[ETH_ALEN];
+
+               if (mac_pton(buf, mac))
+                       memcpy(addr, mac, ETH_ALEN);
+               else
+                       ret = -EINVAL;
+       } else {
+               ret = -EINVAL;
        }
 
-       memcpy(addr, mac, ETH_ALEN);
-       kfree(mac);
+       kfree(buf);
 
-       return 0;
+       return ret;
 }
 
 /**