Factor out the common NVMEM EUI-48 retrieval logic from
of_get_mac_address_nvmem() into a new of_get_nvmem_eui48() helper that
accepts the NVMEM cell name as a parameter. This allows other subsystems
(e.g. Bluetooth) to reuse the same lookup-validate-copy pattern with a
different cell name, without duplicating code.

of_get_mac_address_nvmem() is updated to call of_get_nvmem_eui48() with
"mac-address", preserving its existing behavior.

Reviewed-by: Bartosz Golaszewski <[email protected]>
Signed-off-by: Loic Poulain <[email protected]>
---
 include/linux/of_net.h |  7 +++++++
 net/core/of_net.c      | 49 +++++++++++++++++++++++++++++++++++++------------
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/include/linux/of_net.h b/include/linux/of_net.h
index 
d88715a0b3a52f87af23d47791bea3baf5be5200..7854ba555d9a55f3d020a37fe00a27ae52e0e5dc
 100644
--- a/include/linux/of_net.h
+++ b/include/linux/of_net.h
@@ -15,6 +15,7 @@ struct net_device;
 extern int of_get_phy_mode(struct device_node *np, phy_interface_t *interface);
 extern int of_get_mac_address(struct device_node *np, u8 *mac);
 extern int of_get_mac_address_nvmem(struct device_node *np, u8 *mac);
+int of_get_nvmem_eui48(struct device_node *np, const char *cell_name, u8 
*addr);
 int of_get_ethdev_address(struct device_node *np, struct net_device *dev);
 extern struct net_device *of_find_net_device_by_node(struct device_node *np);
 #else
@@ -34,6 +35,12 @@ static inline int of_get_mac_address_nvmem(struct 
device_node *np, u8 *mac)
        return -ENODEV;
 }
 
+static inline int of_get_nvmem_eui48(struct device_node *np,
+                                     const char *cell_name, u8 *addr)
+{
+       return -ENODEV;
+}
+
 static inline int of_get_ethdev_address(struct device_node *np, struct 
net_device *dev)
 {
        return -ENODEV;
diff --git a/net/core/of_net.c b/net/core/of_net.c
index 
93ea425b9248a23f4f95a336e9cdbf0053248e32..75341c186123e949fbe21f1e51fce3ac74d4f56b
 100644
--- a/net/core/of_net.c
+++ b/net/core/of_net.c
@@ -61,9 +61,7 @@ static int of_get_mac_addr(struct device_node *np, const char 
*name, u8 *addr)
 int of_get_mac_address_nvmem(struct device_node *np, u8 *addr)
 {
        struct platform_device *pdev = of_find_device_by_node(np);
-       struct nvmem_cell *cell;
-       const void *mac;
-       size_t len;
+       u8 mac[ETH_ALEN];
        int ret;
 
        /* Try lookup by device first, there might be a nvmem_cell_lookup
@@ -75,27 +73,54 @@ int of_get_mac_address_nvmem(struct device_node *np, u8 
*addr)
                return ret;
        }
 
-       cell = of_nvmem_cell_get(np, "mac-address");
+       ret = of_get_nvmem_eui48(np, "mac-address", mac);
+       if (ret)
+               return ret;
+
+       if (!is_valid_ether_addr(mac))
+               return -EINVAL;
+
+       ether_addr_copy(addr, mac);
+       return 0;
+}
+EXPORT_SYMBOL(of_get_mac_address_nvmem);
+
+/**
+ * of_get_nvmem_eui48 - Read a 6-byte EUI-48 address from a named NVMEM cell.
+ * @np:                Device node to look up the NVMEM cell from.
+ * @cell_name: Name of the NVMEM cell (e.g. "mac-address", "local-bd-address").
+ * @addr:      Output buffer for the 6-byte address.
+ *
+ * Reads the named NVMEM cell and validates that it contains a non-zero 6-byte
+ * address. Returns 0 on success, negative errno on failure.
+ */
+int of_get_nvmem_eui48(struct device_node *np, const char *cell_name, u8 *addr)
+{
+       struct nvmem_cell *cell;
+       const void *eui48;
+       size_t len;
+
+       cell = of_nvmem_cell_get(np, cell_name);
        if (IS_ERR(cell))
                return PTR_ERR(cell);
 
-       mac = nvmem_cell_read(cell, &len);
+       eui48 = nvmem_cell_read(cell, &len);
        nvmem_cell_put(cell);
 
-       if (IS_ERR(mac))
-               return PTR_ERR(mac);
+       if (IS_ERR(eui48))
+               return PTR_ERR(eui48);
 
-       if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
-               kfree(mac);
+       if (len != ETH_ALEN || !memchr_inv(eui48, 0, ETH_ALEN)) {
+               kfree(eui48);
                return -EINVAL;
        }
 
-       memcpy(addr, mac, ETH_ALEN);
-       kfree(mac);
+       memcpy(addr, eui48, ETH_ALEN);
+       kfree(eui48);
 
        return 0;
 }
-EXPORT_SYMBOL(of_get_mac_address_nvmem);
+EXPORT_SYMBOL_GPL(of_get_nvmem_eui48);
 
 /**
  * of_get_mac_address()

-- 
2.34.1


Reply via email to