diff options
Diffstat (limited to 'drivers/of/of_net.c')
-rw-r--r-- | drivers/of/of_net.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c index 810ab0fbcccb..6f1be80e8c4e 100644 --- a/drivers/of/of_net.c +++ b/drivers/of/of_net.c @@ -7,10 +7,11 @@ */ #include <linux/etherdevice.h> #include <linux/kernel.h> -#include <linux/nvmem-consumer.h> #include <linux/of_net.h> +#include <linux/of_platform.h> #include <linux/phy.h> #include <linux/export.h> +#include <linux/device.h> /** * of_get_phy_mode - Get phy mode for given device_node @@ -48,12 +49,38 @@ static const void *of_get_mac_addr(struct device_node *np, const char *name) return NULL; } +static const void *of_get_mac_addr_nvmem(struct device_node *np) +{ + int ret; + const void *mac; + u8 nvmem_mac[ETH_ALEN]; + struct platform_device *pdev = of_find_device_by_node(np); + + if (!pdev) + return ERR_PTR(-ENODEV); + + ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac); + if (ret) { + put_device(&pdev->dev); + return ERR_PTR(ret); + } + + mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL); + put_device(&pdev->dev); + if (!mac) + return ERR_PTR(-ENOMEM); + + return mac; +} + /** * Search the device tree for the best MAC address to use. 'mac-address' is * checked first, because that is supposed to contain to "most recent" MAC * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. If any + * of the above isn't set, then try to get MAC address from nvmem cell named + * 'mac-address'. * * Note that the 'address' property is supposed to contain a virtual address of * the register set, but some DTS files have redefined that property to be the @@ -65,6 +92,8 @@ static const void *of_get_mac_addr(struct device_node *np, const char *name) * addresses. Some older U-Boots only initialized 'local-mac-address'. In * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists * but is all zeros. + * + * Return: Will be a valid pointer on success and ERR_PTR in case of error. */ const void *of_get_mac_address(struct device_node *np) { @@ -78,6 +107,10 @@ const void *of_get_mac_address(struct device_node *np) if (addr) return addr; - return of_get_mac_addr(np, "address"); + addr = of_get_mac_addr(np, "address"); + if (addr) + return addr; + + return of_get_mac_addr_nvmem(np); } EXPORT_SYMBOL(of_get_mac_address); |