diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2021-12-23 15:27:47 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-12-29 14:32:58 +0300 |
commit | 9ed319e411915e882bb4ed99be3ae78667a70022 (patch) | |
tree | 86d3dd383f24874ffec5736536e8f8b6c0d58f63 /net/core/of_net.c | |
parent | 271d3be1c3b6b0be083a99254a0ecac41789929b (diff) | |
download | linux-9ed319e411915e882bb4ed99be3ae78667a70022.tar.xz |
of: net: support NVMEM cells with MAC in text format
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>
Diffstat (limited to 'net/core/of_net.c')
-rw-r--r-- | net/core/of_net.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/net/core/of_net.c b/net/core/of_net.c index f1a9bf7578e7..95a64c813ae5 100644 --- a/net/core/of_net.c +++ b/net/core/of_net.c @@ -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; } /** |