treewide: backport support for nvmem on non platform devices
authorAnsuel Smith <ansuelsmth@gmail.com>
Fri, 23 Jul 2021 18:19:43 +0000 (20:19 +0200)
committerDavid Bauer <mail@david-bauer.net>
Wed, 4 Aug 2021 23:46:26 +0000 (01:46 +0200)
In the current state, nvmem cells are only detected on platform device.
To quickly fix the problem, we register the affected problematic driver
with the of_platform but that is more an hack than a real solution.
Backport from net-next the required patch so that nvmem can work also
with non-platform devices and rework our current patch.
Drop the mediatek and dsa workaround and rework the ath10k patches.
Rework every driver that use the of_get_mac_address api.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
36 files changed:
package/kernel/ath10k-ct/patches/203-ath10k-Try-to-get-mac-address-from-dts.patch
package/kernel/mac80211/patches/ath/984-ath10k-Try-to-get-mac-address-from-dts.patch [deleted file]
package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch [new file with mode: 0644]
package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch
package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [new file with mode: 0644]
package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [new file with mode: 0644]
target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
target/linux/bcm4908/patches-5.4/074-v5.13-0001-net-broadcom-bcm4908_enet-read-MAC-from-OF.patch
target/linux/bmips/files/arch/mips/bmips/ath9k-fixup.c
target/linux/bmips/files/arch/mips/bmips/b43-sprom.c
target/linux/bmips/files/drivers/net/ethernet/broadcom/bcm6368-enetsw.c
target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch [new file with mode: 0644]
target/linux/generic/hack-5.10/780-drivers-net-mediatek-register-of_platform-for-every-.patch [deleted file]
target/linux/generic/hack-5.10/781-dsa-register-every-port-with-of_platform.patch [deleted file]
target/linux/generic/hack-5.4/780-drivers-net-mediatek-register-of_platform-for-every-.patch [deleted file]
target/linux/generic/hack-5.4/781-dsa-register-every-port-with-of_platform.patch [deleted file]
target/linux/generic/pending-5.10/681-NET-add-mtd-mac-address-support-to-of_get_mac_addres.patch
target/linux/generic/pending-5.10/682-of_net-add-mac-address-increment-support.patch
target/linux/generic/pending-5.10/683-of_net-add-mac-address-to-of-tree.patch
target/linux/generic/pending-5.4/681-NET-add-mtd-mac-address-support-to-of_get_mac_addres.patch
target/linux/generic/pending-5.4/682-of_net-add-mac-address-increment-support.patch
target/linux/generic/pending-5.4/683-of_net-add-mac-address-to-of-tree.patch
target/linux/ipq40xx/files/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
target/linux/lantiq/patches-5.10/0028-NET-lantiq-various-etop-fixes.patch
target/linux/lantiq/patches-5.4/0028-NET-lantiq-various-etop-fixes.patch
target/linux/layerscape/patches-5.4/701-net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch
target/linux/layerscape/patches-5.4/701-net-0286-staging-fsl_ppfe-eth-introduce-pfe-driver.patch
target/linux/layerscape/patches-5.4/701-net-0313-staging-fsl_ppfe-eth-reorganize-platform-phy-paramet.patch
target/linux/layerscape/patches-5.4/701-net-0399-staging-fsl_ppfe-eth-Enhance-error-checking-in-platf.patch
target/linux/octeon/patches-5.10/700-allocate_interface_by_label.patch
target/linux/octeon/patches-5.4/700-allocate_interface_by_label.patch
target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c

index b5c53baf67e85d1e834e6a7b01258effbefcdbcb..3b5d9d45ac9802ce697d3b05dd0ea502fe85a711 100644 (file)
@@ -20,38 +20,19 @@ diff --git a/ath10k-5.10/core.c b/ath10k-5.10/core.c
 index 5f4e12196..9ed7b9883 100644
 --- a/ath10k-5.10/core.c
 +++ b/ath10k-5.10/core.c
-@@ -8,6 +8,9 @@
+@@ -8,6 +8,7 @@
  #include <linux/module.h>
  #include <linux/firmware.h>
  #include <linux/of.h>
 +#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+#include <linux/property.h>
  #include <linux/property.h>
  #include <linux/dmi.h>
  #include <linux/ctype.h>
-@@ -2961,8 +2963,14 @@ EXPORT_SYMBOL(ath10k_core_stop);
- static int ath10k_core_probe_fw(struct ath10k *ar)
- {
-       struct bmi_target_info target_info;
-+      const char *mac;
-       int ret = 0;
-+#ifdef CONFIG_OF
-+      /* register the platform to be found by the of api */
-+      of_platform_device_create(ar->dev->of_node, NULL, NULL);
-+#endif
-+
-       ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
-       if (ret) {
-               ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
-@@ -3062,6 +3068,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
+@@ -3062,6 +3068,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
  
        device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
  
-+      mac = of_get_mac_address(ar->dev->of_node);
-+      if (!IS_ERR(mac))
-+              ether_addr_copy(ar->mac_addr, mac);
++      of_get_mac_address(ar->dev->of_node, ar->mac_addr);
 +
        ret = ath10k_core_init_firmware_features(ar);
        if (ret) {
diff --git a/package/kernel/mac80211/patches/ath/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath/984-ath10k-Try-to-get-mac-address-from-dts.patch
deleted file mode 100644 (file)
index d0eb43f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Sun, 27 Sep 2020 19:23:35 +0200
-Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts
-
-Most of embedded device that have the ath10k wifi integrated store the
-mac-address in nvmem partitions. Try to fetch the mac-address using the
-standard 'of_get_mac_address' than in all the check also try to fetch the
-address using the nvmem api searching for a defined 'mac-address' cell.
-Mac-address defined in the dts have priority than any other address found.
-
-Tested-on: QCA9984 hw1.0 PCI 10.4
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
-index 5f4e12196..9ed7b9883 100644
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -8,6 +8,9 @@
- #include <linux/module.h>
- #include <linux/firmware.h>
- #include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+#include <linux/property.h>
- #include <linux/property.h>
- #include <linux/dmi.h>
- #include <linux/ctype.h>
-@@ -2961,8 +2963,14 @@ EXPORT_SYMBOL(ath10k_core_stop);
- static int ath10k_core_probe_fw(struct ath10k *ar)
- {
-       struct bmi_target_info target_info;
-+      const char *mac;
-       int ret = 0;
-+#ifdef CONFIG_OF
-+      /* register the platform to be found by the of api */
-+      of_platform_device_create(ar->dev->of_node, NULL, NULL);
-+#endif
-+
-       ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
-       if (ret) {
-               ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
-@@ -3062,6 +3068,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
-       device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
-+      mac = of_get_mac_address(ar->dev->of_node);
-+      if (!IS_ERR(mac))
-+              ether_addr_copy(ar->mac_addr, mac);
-+
-       ret = ath10k_core_init_firmware_features(ar);
-       if (ret) {
-               ath10k_err(ar, "fatal problem with firmware features: %d\n",
--- 
-2.27.0
-
diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch
new file mode 100644 (file)
index 0000000..5f427f6
--- /dev/null
@@ -0,0 +1,42 @@
+From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 27 Sep 2020 19:23:35 +0200
+Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts
+
+Most of embedded device that have the ath10k wifi integrated store the
+mac-address in nvmem partitions. Try to fetch the mac-address using the
+standard 'of_get_mac_address' than in all the check also try to fetch the
+address using the nvmem api searching for a defined 'mac-address' cell.
+Mac-address defined in the dts have priority than any other address found.
+
+Tested-on: QCA9984 hw1.0 PCI 10.4
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+---
+ drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 5f4e12196..9ed7b9883 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -8,6 +8,7 @@
+ #include <linux/module.h>
+ #include <linux/firmware.h>
+ #include <linux/of.h>
++#include <linux/of_net.h>
+ #include <linux/property.h>
+ #include <linux/dmi.h>
+ #include <linux/ctype.h>
+@@ -3062,6 +3068,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
+       device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
++      of_get_mac_address(ar->dev->of_node, ar->mac_addr);
++
+       ret = ath10k_core_init_firmware_features(ar);
+       if (ret) {
+               ath10k_err(ar, "fatal problem with firmware features: %d\n",
+-- 
+2.27.0
+
index b5b2c6103797af2fe64fa36595b8bba86465e782..79f99ffdf4a23e6ba4751e15cd59747bc784ad52 100644 (file)
@@ -1,19 +1,18 @@
 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80
+@@ -990,6 +990,12 @@ static void rt2x00lib_rate(struct ieee80
  
  void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
  {
 +      struct rt2x00_platform_data *pdata;
-       const char *mac_addr;
++
 +      pdata = rt2x00dev->dev->platform_data;
 +      if (pdata && pdata->mac_address)
 +              ether_addr_copy(eeprom_mac_addr, pdata->mac_address);
 +
-       mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
-       if (!IS_ERR(mac_addr))
-               ether_addr_copy(eeprom_mac_addr, mac_addr);
+       of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+       if (!is_valid_ether_addr(eeprom_mac_addr)) {
 --- a/include/linux/rt2x00_platform.h
 +++ b/include/linux/rt2x00_platform.h
 @@ -14,6 +14,7 @@
diff --git a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
new file mode 100644 (file)
index 0000000..b973155
--- /dev/null
@@ -0,0 +1,245 @@
+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:17 +0200
+Subject: of: net: pass the dst buffer to of_get_mac_address()
+
+of_get_mac_address() returns a "const void*" pointer to a MAC address.
+Lately, support to fetch the MAC address by an NVMEM provider was added.
+But this will only work with platform devices. It will not work with
+PCI devices (e.g. of an integrated root complex) and esp. not with DSA
+ports.
+
+There is an of_* variant of the nvmem binding which works without
+devices. The returned data of a nvmem_cell_read() has to be freed after
+use. On the other hand the return of_get_mac_address() points to some
+static data without a lifetime. The trick for now, was to allocate a
+device resource managed buffer which is then returned. This will only
+work if we have an actual device.
+
+Change it, so that the caller of of_get_mac_address() has to supply a
+buffer where the MAC address is written to. Unfortunately, this will
+touch all drivers which use the of_get_mac_address().
+
+Usually the code looks like:
+
+  const char *addr;
+  addr = of_get_mac_address(np);
+  if (!IS_ERR(addr))
+    ether_addr_copy(ndev->dev_addr, addr);
+
+This can then be simply rewritten as:
+
+  of_get_mac_address(np, ndev->dev_addr);
+
+Sometimes is_valid_ether_addr() is used to test the MAC address.
+of_get_mac_address() already makes sure, it just returns a valid MAC
+address. Thus we can just test its return code. But we have to be
+careful if there are still other sources for the MAC address before the
+of_get_mac_address(). In this case we have to keep the
+is_valid_ether_addr() call.
+
+The following coccinelle patch was used to convert common cases to the
+new style. Afterwards, I've manually gone over the drivers and fixed the
+return code variable: either used a new one or if one was already
+available use that. Mansour Moufid, thanks for that coccinelle patch!
+
+<spml>
+@a@
+identifier x;
+expression y, z;
+@@
+- x = of_get_mac_address(y);
++ x = of_get_mac_address(y, z);
+  <...
+- ether_addr_copy(z, x);
+  ...>
+
+@@
+identifier a.x;
+@@
+- if (<+... x ...+>) {}
+
+@@
+identifier a.x;
+@@
+  if (<+... x ...+>) {
+      ...
+  }
+- else {}
+
+@@
+identifier a.x;
+expression e;
+@@
+- if (<+... x ...+>@e)
+-     {}
+- else
++ if (!(e))
+      {...}
+
+@@
+expression x, y, z;
+@@
+- x = of_get_mac_address(y, z);
++ of_get_mac_address(y, z);
+  ... when != x
+</spml>
+
+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
+compile-time tested.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
+ arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
+ drivers/net/ethernet/aeroflex/greth.c              |  6 +--
+ drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
+ drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
+ drivers/net/ethernet/arc/emac_main.c               |  8 +--
+ drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
+ drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
+ drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
+ drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
+ drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
+ drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
+ drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
+ drivers/net/ethernet/ethoc.c                       |  6 +--
+ drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
+ drivers/net/ethernet/freescale/fec_main.c          |  7 +--
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
+ drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
+ drivers/net/ethernet/freescale/gianfar.c           |  8 +--
+ drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
+ drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
+ drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
+ drivers/net/ethernet/marvell/mvneta.c              |  6 +--
+ .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
+ drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
+ drivers/net/ethernet/marvell/sky2.c                |  8 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
+ drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
+ drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
+ drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
+ drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
+ drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
+ drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
+ drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
+ drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
+ drivers/net/ethernet/ti/cpsw.c                     |  7 +--
+ drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
+ drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
+ drivers/net/ethernet/ti/netcp_core.c               |  7 +--
+ drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
+ drivers/net/ethernet/wiznet/w5100.c                |  2 +-
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
+ drivers/net/wireless/ath/ath9k/init.c              |  5 +-
+ drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
+ drivers/of/of_net.c                                | 60 ++++++++++------------
+ drivers/staging/octeon/ethernet.c                  | 10 ++--
+ drivers/staging/wfx/main.c                         |  7 ++-
+ include/linux/of_net.h                             |  6 +--
+ include/net/dsa.h                                  |  2 +-
+ net/dsa/dsa2.c                                     |  2 +-
+ net/dsa/slave.c                                    |  2 +-
+ net/ethernet/eth.c                                 | 11 ++--
+ 85 files changed, 218 insertions(+), 364 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index 01f9c26f9bf37..e9a36dd7144f1 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -617,7 +617,6 @@ static int ath9k_of_init(struct ath_softc *sc)
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
+-      const char *mac;
+       char eeprom_name[100];
+       int ret;
+@@ -640,9 +639,7 @@ static int ath9k_of_init(struct ath_softc *sc)
+               ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(common->macaddr, mac);
++      of_get_mac_address(np, common->macaddr);
+       return 0;
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
+index 665b54c5c8ae5..6d895738222ad 100644
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -91,15 +91,9 @@ void
+ void
+ mt76_eeprom_override(struct mt76_dev *dev)
+ {
+-#ifdef CONFIG_OF
+       struct device_node *np = dev->dev->of_node;
+-      const u8 *mac = NULL;
+-      if (np)
+-              mac = of_get_mac_address(np);
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->macaddr, mac);
+-#endif
++      of_get_mac_address(np, dev->macaddr);
+       if (!is_valid_ether_addr(dev->macaddr)) {
+               eth_random_addr(dev->macaddr);
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+index 61a4f1ad31e28..e95c101c27111 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -989,11 +989,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry,
+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+ {
+-      const char *mac_addr;
+-
+-      mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(eeprom_mac_addr, mac_addr);
++      of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+       if (!is_valid_ether_addr(eeprom_mac_addr)) {
+               eth_random_addr(eeprom_mac_addr);
+-- 
+cgit 1.2.3-1.el7
diff --git a/package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mt76/patches/001-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
new file mode 100644 (file)
index 0000000..66075f2
--- /dev/null
@@ -0,0 +1,206 @@
+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:17 +0200
+Subject: of: net: pass the dst buffer to of_get_mac_address()
+
+of_get_mac_address() returns a "const void*" pointer to a MAC address.
+Lately, support to fetch the MAC address by an NVMEM provider was added.
+But this will only work with platform devices. It will not work with
+PCI devices (e.g. of an integrated root complex) and esp. not with DSA
+ports.
+
+There is an of_* variant of the nvmem binding which works without
+devices. The returned data of a nvmem_cell_read() has to be freed after
+use. On the other hand the return of_get_mac_address() points to some
+static data without a lifetime. The trick for now, was to allocate a
+device resource managed buffer which is then returned. This will only
+work if we have an actual device.
+
+Change it, so that the caller of of_get_mac_address() has to supply a
+buffer where the MAC address is written to. Unfortunately, this will
+touch all drivers which use the of_get_mac_address().
+
+Usually the code looks like:
+
+  const char *addr;
+  addr = of_get_mac_address(np);
+  if (!IS_ERR(addr))
+    ether_addr_copy(ndev->dev_addr, addr);
+
+This can then be simply rewritten as:
+
+  of_get_mac_address(np, ndev->dev_addr);
+
+Sometimes is_valid_ether_addr() is used to test the MAC address.
+of_get_mac_address() already makes sure, it just returns a valid MAC
+address. Thus we can just test its return code. But we have to be
+careful if there are still other sources for the MAC address before the
+of_get_mac_address(). In this case we have to keep the
+is_valid_ether_addr() call.
+
+The following coccinelle patch was used to convert common cases to the
+new style. Afterwards, I've manually gone over the drivers and fixed the
+return code variable: either used a new one or if one was already
+available use that. Mansour Moufid, thanks for that coccinelle patch!
+
+<spml>
+@a@
+identifier x;
+expression y, z;
+@@
+- x = of_get_mac_address(y);
++ x = of_get_mac_address(y, z);
+  <...
+- ether_addr_copy(z, x);
+  ...>
+
+@@
+identifier a.x;
+@@
+- if (<+... x ...+>) {}
+
+@@
+identifier a.x;
+@@
+  if (<+... x ...+>) {
+      ...
+  }
+- else {}
+
+@@
+identifier a.x;
+expression e;
+@@
+- if (<+... x ...+>@e)
+-     {}
+- else
++ if (!(e))
+      {...}
+
+@@
+expression x, y, z;
+@@
+- x = of_get_mac_address(y, z);
++ of_get_mac_address(y, z);
+  ... when != x
+</spml>
+
+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
+compile-time tested.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
+ arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
+ drivers/net/ethernet/aeroflex/greth.c              |  6 +--
+ drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
+ drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
+ drivers/net/ethernet/arc/emac_main.c               |  8 +--
+ drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
+ drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
+ drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
+ drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
+ drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
+ drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
+ drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
+ drivers/net/ethernet/ethoc.c                       |  6 +--
+ drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
+ drivers/net/ethernet/freescale/fec_main.c          |  7 +--
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
+ drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
+ drivers/net/ethernet/freescale/gianfar.c           |  8 +--
+ drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
+ drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
+ drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
+ drivers/net/ethernet/marvell/mvneta.c              |  6 +--
+ .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
+ drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
+ drivers/net/ethernet/marvell/sky2.c                |  8 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
+ drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
+ drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
+ drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
+ drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
+ drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
+ drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
+ drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
+ drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
+ drivers/net/ethernet/ti/cpsw.c                     |  7 +--
+ drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
+ drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
+ drivers/net/ethernet/ti/netcp_core.c               |  7 +--
+ drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
+ drivers/net/ethernet/wiznet/w5100.c                |  2 +-
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
+ drivers/net/wireless/ath/ath9k/init.c              |  5 +-
+ drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
+ drivers/of/of_net.c                                | 60 ++++++++++------------
+ drivers/staging/octeon/ethernet.c                  | 10 ++--
+ drivers/staging/wfx/main.c                         |  7 ++-
+ include/linux/of_net.h                             |  6 +--
+ include/net/dsa.h                                  |  2 +-
+ net/dsa/dsa2.c                                     |  2 +-
+ net/dsa/slave.c                                    |  2 +-
+ net/ethernet/eth.c                                 | 11 ++--
+ 85 files changed, 218 insertions(+), 364 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
+index 665b54c5c8ae5..6d895738222ad 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -91,15 +91,9 @@ void
+ {
+       struct mt76_dev *dev = phy->dev;
+-#ifdef CONFIG_OF
+       struct device_node *np = dev->dev->of_node;
+-      const u8 *mac = NULL;
+-      if (np)
+-              mac = of_get_mac_address(np);
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(phy->macaddr, mac);
+-#endif
++      of_get_mac_address(np, phy->macaddr);
+       if (!is_valid_ether_addr(phy->macaddr)) {
+               eth_random_addr(phy->macaddr);
+-- 
+cgit 1.2.3-1.el7
+
index 463083628fbeeefe05d45bd0cf2c29ff21021212..607cc0b93440b5ecbb8a54884f191f9c0f286bc6 100644 (file)
@@ -1519,7 +1519,6 @@ static int ag71xx_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct resource *res;
        struct ag71xx *ag;
-       const void *mac_addr;
        u32 max_frame_len;
        int tx_size, err;
 
@@ -1668,12 +1667,10 @@ static int ag71xx_probe(struct platform_device *pdev)
        ag->stop_desc->ctrl = 0;
        ag->stop_desc->next = (u32) ag->stop_desc_dma;
 
-       mac_addr = of_get_mac_address(np);
-       if (IS_ERR_OR_NULL(mac_addr) || !is_valid_ether_addr(mac_addr)) {
+       of_get_mac_address(np, dev->dev_addr);
+       if (!is_valid_ether_addr(dev->dev_addr)) {
                dev_err(&pdev->dev, "invalid MAC address, using random address\n");
                eth_random_addr(dev->dev_addr);
-       } else {
-               memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
        }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,10,0)
index 4b8e1f83b883219593dd82aa0787ce3128fefde7..df004c0480af2f2073e11f382d45f8b0de73132a 100644 (file)
@@ -25,23 +25,13 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  #include <linux/platform_device.h>
  #include <linux/slab.h>
  #include <linux/string.h>
-@@ -620,6 +621,7 @@ static int bcm4908_enet_probe(struct pla
-       struct device *dev = &pdev->dev;
-       struct net_device *netdev;
-       struct bcm4908_enet *enet;
-+      const u8 *mac;
-       int err;
-       netdev = devm_alloc_etherdev(dev, sizeof(*enet));
-@@ -647,7 +649,11 @@ static int bcm4908_enet_probe(struct pla
+@@ -647,7 +649,9 @@ static int bcm4908_enet_probe(struct pla
                return err;
  
        SET_NETDEV_DEV(netdev, &pdev->dev);
 -      eth_hw_addr_random(netdev);
-+      mac = of_get_mac_address(dev->of_node);
-+      if (!IS_ERR(mac))
-+              ether_addr_copy(netdev->dev_addr, mac);
-+      else
++      of_get_mac_address(dev->of_node, netdev->dev_addr);
++      if (!is_valid_ether_addr(netdev->dev_addr))
 +              eth_hw_addr_random(netdev);
        netdev->netdev_ops = &bcm4908_enet_netdev_ops;
        netdev->min_mtu = ETH_ZLEN;
index dd13ac62567ec5b4a6430c12604ac33d60105024..fc034165076c5d3e707adbfef4ca9a3650a973ca 100644 (file)
@@ -167,7 +167,6 @@ static int ath9k_fixup_probe(struct platform_device *pdev)
        struct device_node *node = dev->of_node;
        struct ath9k_fixup *priv;
        struct resource *res;
-       const void *mac;
        int ret;
 
        if (ath9k_num_fixups >= ATH9K_MAX_FIXUPS)
@@ -200,9 +199,8 @@ static int ath9k_fixup_probe(struct platform_device *pdev)
        priv->pdata.led_active_high = of_property_read_bool(node,
                "ath,led-active-high");
 
-       mac = of_get_mac_address(node);
-       if (!IS_ERR_OR_NULL(mac)) {
-               memcpy(priv->mac, mac, ETH_ALEN);
+       of_get_mac_address(node, priv->mac);
+       if (is_valid_ether_addr(priv->mac)) {
                dev_info(dev, "mtd mac %pM\n", priv->mac);
        } else {
                random_ether_addr(priv->mac);
index 2348bd1fe27f5318b87e57b0f3e9ad6939998d3b..edc7fb145b82f8ca96e22af20b78200b354a03d6 100644 (file)
@@ -1119,7 +1119,6 @@ static int b43_sprom_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct device_node *node = dev->of_node;
        struct b43_sprom *priv = &b43_sprom;
-       const void *mac;
        int ret;
 
        priv->dev = dev;
@@ -1129,9 +1128,8 @@ static int b43_sprom_probe(struct platform_device *pdev)
        of_property_read_u32(node, "pci-bus", &priv->pci_bus);
        of_property_read_u32(node, "pci-dev", &priv->pci_dev);
 
-       mac = of_get_mac_address(node);
-       if (!IS_ERR_OR_NULL(mac)) {
-               memcpy(priv->mac, mac, ETH_ALEN);
+       of_get_mac_address(node, priv->mac);
+       if (is_valid_ether_addr(priv->mac)) {
                dev_info(dev, "mtd mac %pM\n", priv->mac);
        } else {
                random_ether_addr(priv->mac);
index 2a27118aa749d73309fd868f6400349367b00450..d9ecba518862f2190ddd322ffb3921cf9259fc9f 100644 (file)
@@ -864,7 +864,6 @@ static int bcm6368_enetsw_probe(struct platform_device *pdev)
        struct device_node *node = dev->of_node;
        struct net_device *ndev;
        struct resource *res;
-       const void *mac;
        unsigned i;
        int ret;
 
@@ -953,9 +952,8 @@ static int bcm6368_enetsw_probe(struct platform_device *pdev)
        priv->dma_chan_int_mask = DMAC_IR_PKTDONE_MASK;
        priv->dma_chan_width = DMA_CHAN_WIDTH;
 
-       mac = of_get_mac_address(node);
-       if (!IS_ERR_OR_NULL(mac)) {
-               memcpy(ndev->dev_addr, mac, ETH_ALEN);
+       of_get_mac_address(node, ndev->dev_addr);
+       if (is_valid_ether_addr(ndev->dev_addr)) {
                dev_info(dev, "mtd mac %pM\n", ndev->dev_addr);
        } else {
                random_ether_addr(ndev->dev_addr);
diff --git a/target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.10/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
new file mode 100644 (file)
index 0000000..b97cb13
--- /dev/null
@@ -0,0 +1,1935 @@
+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:17 +0200
+Subject: of: net: pass the dst buffer to of_get_mac_address()
+
+of_get_mac_address() returns a "const void*" pointer to a MAC address.
+Lately, support to fetch the MAC address by an NVMEM provider was added.
+But this will only work with platform devices. It will not work with
+PCI devices (e.g. of an integrated root complex) and esp. not with DSA
+ports.
+
+There is an of_* variant of the nvmem binding which works without
+devices. The returned data of a nvmem_cell_read() has to be freed after
+use. On the other hand the return of_get_mac_address() points to some
+static data without a lifetime. The trick for now, was to allocate a
+device resource managed buffer which is then returned. This will only
+work if we have an actual device.
+
+Change it, so that the caller of of_get_mac_address() has to supply a
+buffer where the MAC address is written to. Unfortunately, this will
+touch all drivers which use the of_get_mac_address().
+
+Usually the code looks like:
+
+  const char *addr;
+  addr = of_get_mac_address(np);
+  if (!IS_ERR(addr))
+    ether_addr_copy(ndev->dev_addr, addr);
+
+This can then be simply rewritten as:
+
+  of_get_mac_address(np, ndev->dev_addr);
+
+Sometimes is_valid_ether_addr() is used to test the MAC address.
+of_get_mac_address() already makes sure, it just returns a valid MAC
+address. Thus we can just test its return code. But we have to be
+careful if there are still other sources for the MAC address before the
+of_get_mac_address(). In this case we have to keep the
+is_valid_ether_addr() call.
+
+The following coccinelle patch was used to convert common cases to the
+new style. Afterwards, I've manually gone over the drivers and fixed the
+return code variable: either used a new one or if one was already
+available use that. Mansour Moufid, thanks for that coccinelle patch!
+
+<spml>
+@a@
+identifier x;
+expression y, z;
+@@
+- x = of_get_mac_address(y);
++ x = of_get_mac_address(y, z);
+  <...
+- ether_addr_copy(z, x);
+  ...>
+
+@@
+identifier a.x;
+@@
+- if (<+... x ...+>) {}
+
+@@
+identifier a.x;
+@@
+  if (<+... x ...+>) {
+      ...
+  }
+- else {}
+
+@@
+identifier a.x;
+expression e;
+@@
+- if (<+... x ...+>@e)
+-     {}
+- else
++ if (!(e))
+      {...}
+
+@@
+expression x, y, z;
+@@
+- x = of_get_mac_address(y, z);
++ of_get_mac_address(y, z);
+  ... when != x
+</spml>
+
+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
+compile-time tested.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
+ arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
+ drivers/net/ethernet/aeroflex/greth.c              |  6 +--
+ drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
+ drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
+ drivers/net/ethernet/arc/emac_main.c               |  8 +--
+ drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
+ drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
+ drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
+ drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
+ drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
+ drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
+ drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
+ drivers/net/ethernet/ethoc.c                       |  6 +--
+ drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
+ drivers/net/ethernet/freescale/fec_main.c          |  7 +--
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
+ drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
+ drivers/net/ethernet/freescale/gianfar.c           |  8 +--
+ drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
+ drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
+ drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
+ drivers/net/ethernet/marvell/mvneta.c              |  6 +--
+ .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
+ drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
+ drivers/net/ethernet/marvell/sky2.c                |  8 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
+ drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
+ drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
+ drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
+ drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
+ drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
+ drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
+ drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
+ drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
+ drivers/net/ethernet/ti/cpsw.c                     |  7 +--
+ drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
+ drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
+ drivers/net/ethernet/ti/netcp_core.c               |  7 +--
+ drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
+ drivers/net/ethernet/wiznet/w5100.c                |  2 +-
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
+ drivers/net/wireless/ath/ath9k/init.c              |  5 +-
+ drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
+ drivers/of/of_net.c                                | 60 ++++++++++------------
+ drivers/staging/octeon/ethernet.c                  | 10 ++--
+ drivers/staging/wfx/main.c                         |  7 ++-
+ include/linux/of_net.h                             |  6 +--
+ include/net/dsa.h                                  |  2 +-
+ net/dsa/dsa2.c                                     |  2 +-
+ net/dsa/slave.c                                    |  2 +-
+ net/ethernet/eth.c                                 | 11 ++--
+ 85 files changed, 218 insertions(+), 364 deletions(-)
+
+--- a/arch/arm/mach-mvebu/kirkwood.c
++++ b/arch/arm/mach-mvebu/kirkwood.c
+@@ -84,6 +84,7 @@ static void __init kirkwood_dt_eth_fixup
+               struct device_node *pnp = of_get_parent(np);
+               struct clk *clk;
+               struct property *pmac;
++              u8 tmpmac[ETH_ALEN];
+               void __iomem *io;
+               u8 *macaddr;
+               u32 reg;
+@@ -93,7 +94,7 @@ static void __init kirkwood_dt_eth_fixup
+               /* skip disabled nodes or nodes with valid MAC address*/
+               if (!of_device_is_available(pnp) ||
+-                  !IS_ERR(of_get_mac_address(np)))
++                  !of_get_mac_address(np, tmpmac))
+                       goto eth_fixup_skip;
+               clk = of_clk_get(pnp, 0);
+--- a/arch/powerpc/sysdev/tsi108_dev.c
++++ b/arch/powerpc/sysdev/tsi108_dev.c
+@@ -73,7 +73,6 @@ static int __init tsi108_eth_of_init(voi
+               struct device_node *phy, *mdio;
+               hw_info tsi_eth_data;
+               const unsigned int *phy_id;
+-              const void *mac_addr;
+               const phandle *ph;
+               memset(r, 0, sizeof(r));
+@@ -101,9 +100,7 @@ static int __init tsi108_eth_of_init(voi
+                       goto err;
+               }
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(tsi_eth_data.mac_addr, mac_addr);
++              of_get_mac_address(np, tsi_eth_data.mac_addr);
+               ph = of_get_property(np, "mdio-handle", NULL);
+               mdio = of_find_node_by_phandle(*ph);
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -1449,10 +1449,10 @@ static int greth_of_probe(struct platfor
+                       break;
+       }
+       if (i == 6) {
+-              const u8 *addr;
++              u8 addr[ETH_ALEN];
+-              addr = of_get_mac_address(ofdev->dev.of_node);
+-              if (!IS_ERR(addr)) {
++              err = of_get_mac_address(ofdev->dev.of_node, addr);
++              if (!err) {
+                       for (i = 0; i < 6; i++)
+                               macaddr[i] = (unsigned int) addr[i];
+               } else {
+--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
++++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
+@@ -790,7 +790,6 @@ static int emac_probe(struct platform_de
+       struct emac_board_info *db;
+       struct net_device *ndev;
+       int ret = 0;
+-      const char *mac_addr;
+       ndev = alloc_etherdev(sizeof(struct emac_board_info));
+       if (!ndev) {
+@@ -853,12 +852,9 @@ static int emac_probe(struct platform_de
+       }
+       /* Read MAC-address from DT */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* Check if the MAC address is valid, if not get a random one */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the MAC address is invalid get a random one */
+               eth_hw_addr_random(ndev);
+               dev_warn(&pdev->dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/altera/altera_tse_main.c
++++ b/drivers/net/ethernet/altera/altera_tse_main.c
+@@ -1351,7 +1351,6 @@ static int altera_tse_probe(struct platf
+       struct resource *control_port;
+       struct resource *dma_res;
+       struct altera_tse_private *priv;
+-      const unsigned char *macaddr;
+       void __iomem *descmap;
+       const struct of_device_id *of_id = NULL;
+@@ -1525,10 +1524,8 @@ static int altera_tse_probe(struct platf
+       priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;
+       /* get default MAC address from device tree */
+-      macaddr = of_get_mac_address(pdev->dev.of_node);
+-      if (!IS_ERR(macaddr))
+-              ether_addr_copy(ndev->dev_addr, macaddr);
+-      else
++      ret = of_get_mac_address(pdev->dev.of_node, ndev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(ndev);
+       /* get phy addr and create mdio */
+--- a/drivers/net/ethernet/arc/emac_main.c
++++ b/drivers/net/ethernet/arc/emac_main.c
+@@ -857,7 +857,6 @@ int arc_emac_probe(struct net_device *nd
+       struct device_node *phy_node;
+       struct phy_device *phydev = NULL;
+       struct arc_emac_priv *priv;
+-      const char *mac_addr;
+       unsigned int id, clock_frequency, irq;
+       int err;
+@@ -942,11 +941,8 @@ int arc_emac_probe(struct net_device *nd
+       }
+       /* Get MAC address from device tree */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       arc_emac_set_address_internal(ndev);
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1856,7 +1856,6 @@ static int ag71xx_probe(struct platform_
+       const struct ag71xx_dcfg *dcfg;
+       struct net_device *ndev;
+       struct resource *res;
+-      const void *mac_addr;
+       int tx_size, err, i;
+       struct ag71xx *ag;
+@@ -1957,10 +1956,8 @@ static int ag71xx_probe(struct platform_
+       ag->stop_desc->ctrl = 0;
+       ag->stop_desc->next = (u32)ag->stop_desc_dma;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+-      if (IS_ERR(mac_addr) || !is_valid_ether_addr(ndev->dev_addr)) {
++      err = of_get_mac_address(np, ndev->dev_addr);
++      if (err) {
+               netif_err(ag, probe, ndev, "invalid MAC address, using random address\n");
+               eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -2465,7 +2465,6 @@ static int bcm_sysport_probe(struct plat
+       struct bcm_sysport_priv *priv;
+       struct device_node *dn;
+       struct net_device *dev;
+-      const void *macaddr;
+       u32 txq, rxq;
+       int ret;
+@@ -2560,12 +2559,10 @@ static int bcm_sysport_probe(struct plat
+       }
+       /* Initialize netdevice members */
+-      macaddr = of_get_mac_address(dn);
+-      if (IS_ERR(macaddr)) {
++      ret = of_get_mac_address(dn, dev->dev_addr);
++      if (ret) {
+               dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+               eth_hw_addr_random(dev);
+-      } else {
+-              ether_addr_copy(dev->dev_addr, macaddr);
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -115,7 +115,7 @@ static int bgmac_probe(struct bcma_devic
+       struct ssb_sprom *sprom = &core->bus->sprom;
+       struct mii_bus *mii_bus;
+       struct bgmac *bgmac;
+-      const u8 *mac = NULL;
++      const u8 *mac;
+       int err;
+       bgmac = bgmac_alloc(&core->dev);
+@@ -128,11 +128,10 @@ static int bgmac_probe(struct bcma_devic
+       bcma_set_drvdata(core, bgmac);
+-      if (bgmac->dev->of_node)
+-              mac = of_get_mac_address(bgmac->dev->of_node);
++      err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
+       /* If no MAC address assigned via device tree, check SPROM */
+-      if (IS_ERR_OR_NULL(mac)) {
++      if (err) {
+               switch (core->core_unit) {
+               case 0:
+                       mac = sprom->et0mac;
+@@ -149,10 +148,9 @@ static int bgmac_probe(struct bcma_devic
+                       err = -ENOTSUPP;
+                       goto err;
+               }
++              ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+       }
+-      ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+-
+       /* On BCM4706 we need common core to access PHY */
+       if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
+           !core->bus->drv_gmac_cmn.core) {
+--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
+@@ -173,7 +173,7 @@ static int bgmac_probe(struct platform_d
+       struct device_node *np = pdev->dev.of_node;
+       struct bgmac *bgmac;
+       struct resource *regs;
+-      const u8 *mac_addr;
++      int ret;
+       bgmac = bgmac_alloc(&pdev->dev);
+       if (!bgmac)
+@@ -192,11 +192,10 @@ static int bgmac_probe(struct platform_d
+       bgmac->dev = &pdev->dev;
+       bgmac->dma_dev = &pdev->dev;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr);
+-      else
+-              dev_warn(&pdev->dev, "MAC address not present in device tree\n");
++      ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
++      if (ret)
++              dev_warn(&pdev->dev,
++                       "MAC address not present in device tree\n");
+       bgmac->irq = platform_get_irq(pdev, 0);
+       if (bgmac->irq < 0)
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -4453,7 +4453,6 @@ static int macb_probe(struct platform_de
+       struct net_device *dev;
+       struct resource *regs;
+       void __iomem *mem;
+-      const char *mac;
+       struct macb *bp;
+       int err, val;
+@@ -4566,15 +4565,11 @@ static int macb_probe(struct platform_de
+       if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
+               bp->rx_intr_mask |= MACB_BIT(RXUBR);
+-      mac = of_get_mac_address(np);
+-      if (PTR_ERR(mac) == -EPROBE_DEFER) {
+-              err = -EPROBE_DEFER;
++      err = of_get_mac_address(np, bp->dev->dev_addr);
++      if (err == -EPROBE_DEFER)
+               goto err_out_free_netdev;
+-      } else if (!IS_ERR_OR_NULL(mac)) {
+-              ether_addr_copy(bp->dev->dev_addr, mac);
+-      } else {
++      else if (err)
+               macb_get_hwaddr(bp);
+-      }
+       err = of_get_phy_mode(np, &interface);
+       if (err)
+--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
++++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+@@ -1385,7 +1385,6 @@ static int octeon_mgmt_probe(struct plat
+       struct net_device *netdev;
+       struct octeon_mgmt *p;
+       const __be32 *data;
+-      const u8 *mac;
+       struct resource *res_mix;
+       struct resource *res_agl;
+       struct resource *res_agl_prt_ctl;
+@@ -1502,11 +1501,8 @@ static int octeon_mgmt_probe(struct plat
+       netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
+       netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;
+-      mac = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(netdev->dev_addr, mac);
+-      else
++      result = of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
++      if (result)
+               eth_hw_addr_random(netdev);
+       p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1474,7 +1474,6 @@ static int bgx_init_of_phy(struct bgx *b
+       device_for_each_child_node(&bgx->pdev->dev, fwn) {
+               struct phy_device *pd;
+               struct device_node *phy_np;
+-              const char *mac;
+               /* Should always be an OF node.  But if it is not, we
+                * cannot handle it, so exit the loop.
+@@ -1483,9 +1482,7 @@ static int bgx_init_of_phy(struct bgx *b
+               if (!node)
+                       break;
+-              mac = of_get_mac_address(node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(bgx->lmac[lmac].mac, mac);
++              of_get_mac_address(node, bgx->lmac[lmac].mac);
+               SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
+               bgx->lmac[lmac].lmacid = lmac;
+--- a/drivers/net/ethernet/davicom/dm9000.c
++++ b/drivers/net/ethernet/davicom/dm9000.c
+@@ -1388,7 +1388,7 @@ static struct dm9000_plat_data *dm9000_p
+ {
+       struct dm9000_plat_data *pdata;
+       struct device_node *np = dev->of_node;
+-      const void *mac_addr;
++      int ret;
+       if (!IS_ENABLED(CONFIG_OF) || !np)
+               return ERR_PTR(-ENXIO);
+@@ -1402,11 +1402,9 @@ static struct dm9000_plat_data *dm9000_p
+       if (of_find_property(np, "davicom,no-eeprom", NULL))
+               pdata->flags |= DM9000_PLATF_NO_EEPROM;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->dev_addr, mac_addr);
+-      else if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
+-              return ERR_CAST(mac_addr);
++      ret = of_get_mac_address(np, pdata->dev_addr);
++      if (ret == -EPROBE_DEFER)
++              return ERR_PTR(ret);
+       return pdata;
+ }
+--- a/drivers/net/ethernet/ethoc.c
++++ b/drivers/net/ethernet/ethoc.c
+@@ -1151,11 +1151,7 @@ static int ethoc_probe(struct platform_d
+               ether_addr_copy(netdev->dev_addr, pdata->hwaddr);
+               priv->phy_id = pdata->phy_id;
+       } else {
+-              const void *mac;
+-
+-              mac = of_get_mac_address(pdev->dev.of_node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(netdev->dev_addr, mac);
++              of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
+               priv->phy_id = -1;
+       }
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -575,7 +575,6 @@ static s32 nps_enet_probe(struct platfor
+       struct net_device *ndev;
+       struct nps_enet_priv *priv;
+       s32 err = 0;
+-      const char *mac_addr;
+       if (!dev->of_node)
+               return -ENODEV;
+@@ -602,10 +601,8 @@ static s32 nps_enet_probe(struct platfor
+       dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base);
+       /* set kernel MAC address to dev */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       /* Get IRQ number */
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1664,6 +1664,7 @@ static void fec_get_mac(struct net_devic
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
+       unsigned char *iap, tmpaddr[ETH_ALEN];
++      int ret;
+       /*
+        * try to get mac address in following order:
+@@ -1679,9 +1680,9 @@ static void fec_get_mac(struct net_devic
+       if (!is_valid_ether_addr(iap)) {
+               struct device_node *np = fep->pdev->dev.of_node;
+               if (np) {
+-                      const char *mac = of_get_mac_address(np);
+-                      if (!IS_ERR(mac))
+-                              iap = (unsigned char *) mac;
++                      ret = of_get_mac_address(np, tmpaddr);
++                      if (!ret)
++                              iap = tmpaddr;
+               }
+       }
+--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
++++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
+@@ -813,7 +813,6 @@ static int mpc52xx_fec_probe(struct plat
+       const u32 *prop;
+       int prop_size;
+       struct device_node *np = op->dev.of_node;
+-      const char *mac_addr;
+       phys_addr_t rx_fifo;
+       phys_addr_t tx_fifo;
+@@ -891,10 +890,8 @@ static int mpc52xx_fec_probe(struct plat
+        *
+        * First try to read MAC address from DT
+        */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      } else {
++      rv = of_get_mac_address(np, ndev->dev_addr);
++      if (rv) {
+               struct mpc52xx_fec __iomem *fec = priv->fec;
+               /*
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -605,7 +605,6 @@ static int mac_probe(struct platform_dev
+       struct platform_device  *of_dev;
+       struct resource          res;
+       struct mac_priv_s       *priv;
+-      const u8                *mac_addr;
+       u32                      val;
+       u8                      fman_id;
+       phy_interface_t          phy_if;
+@@ -723,11 +722,9 @@ static int mac_probe(struct platform_dev
+       priv->cell_index = (u8)val;
+       /* Get the MAC address */
+-      mac_addr = of_get_mac_address(mac_node);
+-      if (IS_ERR(mac_addr))
++      err = of_get_mac_address(mac_node, mac_dev->addr);
++      if (err)
+               dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
+-      else
+-              ether_addr_copy(mac_dev->addr, mac_addr);
+       /* Get the port handles */
+       nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
+@@ -853,7 +850,7 @@ static int mac_probe(struct platform_dev
+       if (err < 0)
+               dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
+-      if (!IS_ERR(mac_addr))
++      if (!is_zero_ether_addr(mac_dev->addr))
+               dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
+       priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
+--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+@@ -918,7 +918,6 @@ static int fs_enet_probe(struct platform
+       const u32 *data;
+       struct clk *clk;
+       int err;
+-      const u8 *mac_addr;
+       const char *phy_connection_type;
+       int privsize, len, ret = -ENODEV;
+@@ -1006,9 +1005,7 @@ static int fs_enet_probe(struct platform
+       spin_lock_init(&fep->lock);
+       spin_lock_init(&fep->tx_lock);
+-      mac_addr = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
++      of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
+       ret = fep->ops->allocate_bd(ndev);
+       if (ret)
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -641,7 +641,6 @@ static phy_interface_t gfar_get_interfac
+ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+ {
+       const char *model;
+-      const void *mac_addr;
+       int err = 0, i;
+       phy_interface_t interface;
+       struct net_device *dev = NULL;
+@@ -783,11 +782,8 @@ static int gfar_of_init(struct platform_
+       if (stash_len || stash_idx)
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+-      mac_addr = of_get_mac_address(np);
+-
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-      } else {
++      err = of_get_mac_address(np, dev->dev_addr);
++      if (err) {
+               eth_hw_addr_random(dev);
+               dev_info(&ofdev->dev, "Using random MAC address: %pM\n", dev->dev_addr);
+       }
+--- a/drivers/net/ethernet/freescale/ucc_geth.c
++++ b/drivers/net/ethernet/freescale/ucc_geth.c
+@@ -3696,7 +3696,6 @@ static int ucc_geth_probe(struct platfor
+       int err, ucc_num, max_speed = 0;
+       const unsigned int *prop;
+       const char *sprop;
+-      const void *mac_addr;
+       phy_interface_t phy_interface;
+       static const int enet_to_speed[] = {
+               SPEED_10, SPEED_10, SPEED_10,
+@@ -3906,9 +3905,7 @@ static int ucc_geth_probe(struct platfor
+               goto err_free_netdev;
+       }
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      of_get_mac_address(np, dev->dev_addr);
+       ugeth->ug_info = ug_info;
+       ugeth->dev = device;
+--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
++++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
+@@ -772,7 +772,6 @@ static int hisi_femac_drv_probe(struct p
+       struct net_device *ndev;
+       struct hisi_femac_priv *priv;
+       struct phy_device *phy;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(*priv));
+@@ -842,10 +841,8 @@ static int hisi_femac_drv_probe(struct p
+                          (unsigned long)phy->phy_id,
+                          phy_modes(phy->interface));
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
++++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+@@ -1098,7 +1098,6 @@ static int hix5hd2_dev_probe(struct plat
+       struct net_device *ndev;
+       struct hix5hd2_priv *priv;
+       struct mii_bus *bus;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(struct hix5hd2_priv));
+@@ -1220,10 +1219,8 @@ static int hix5hd2_dev_probe(struct plat
+               goto out_phy_node;
+       }
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               netdev_warn(ndev, "using random MAC address %pM\n",
+                           ndev->dev_addr);
+--- a/drivers/net/ethernet/lantiq_xrx200.c
++++ b/drivers/net/ethernet/lantiq_xrx200.c
+@@ -435,7 +435,6 @@ static int xrx200_probe(struct platform_
+       struct resource *res;
+       struct xrx200_priv *priv;
+       struct net_device *net_dev;
+-      const u8 *mac;
+       int err;
+       /* alloc the network device */
+@@ -479,10 +478,8 @@ static int xrx200_probe(struct platform_
+               return PTR_ERR(priv->clk);
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(net_dev->dev_addr, mac);
+-      else
++      err = of_get_mac_address(np, net_dev->dev_addr);
++      if (err)
+               eth_hw_addr_random(net_dev);
+       /* bring up the dma engine and IP core */
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2700,7 +2700,6 @@ static int mv643xx_eth_shared_of_add_por
+       struct platform_device *ppdev;
+       struct mv643xx_eth_platform_data ppd;
+       struct resource res;
+-      const char *mac_addr;
+       int ret;
+       int dev_num = 0;
+@@ -2731,9 +2730,7 @@ static int mv643xx_eth_shared_of_add_por
+               return -EINVAL;
+       }
+-      mac_addr = of_get_mac_address(pnp);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ppd.mac_addr, mac_addr);
++      of_get_mac_address(pnp, ppd.mac_addr);
+       mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
+       mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -5062,7 +5062,6 @@ static int mvneta_probe(struct platform_
+       struct net_device *dev;
+       struct phylink *phylink;
+       struct phy *comphy;
+-      const char *dt_mac_addr;
+       char hw_mac_addr[ETH_ALEN];
+       phy_interface_t phy_mode;
+       const char *mac_from;
+@@ -5158,10 +5157,9 @@ static int mvneta_probe(struct platform_
+               goto err_free_ports;
+       }
+-      dt_mac_addr = of_get_mac_address(dn);
+-      if (!IS_ERR(dt_mac_addr)) {
++      err = of_get_mac_address(dn, dev->dev_addr);
++      if (!err) {
+               mac_from = "device tree";
+-              ether_addr_copy(dev->dev_addr, dt_mac_addr);
+       } else {
+               mvneta_get_mac_addr(pp, hw_mac_addr);
+               if (is_valid_ether_addr(hw_mac_addr)) {
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -462,20 +462,17 @@ static int prestera_switch_set_base_mac_
+ {
+       struct device_node *base_mac_np;
+       struct device_node *np;
+-      const char *base_mac;
++      int ret;
+       np = of_find_compatible_node(NULL, NULL, "marvell,prestera");
+       base_mac_np = of_parse_phandle(np, "base-mac-provider", 0);
+-      base_mac = of_get_mac_address(base_mac_np);
+-      of_node_put(base_mac_np);
+-      if (!IS_ERR(base_mac))
+-              ether_addr_copy(sw->base_mac, base_mac);
+-
+-      if (!is_valid_ether_addr(sw->base_mac)) {
++      ret = of_get_mac_address(base_mac_np, sw->base_mac);
++      if (ret) {
+               eth_random_addr(sw->base_mac);
+               dev_info(prestera_dev(sw), "using random base mac address\n");
+       }
++      of_node_put(base_mac_np);
+       return prestera_hw_switch_mac_set(sw, sw->base_mac);
+ }
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1392,7 +1392,6 @@ static int pxa168_eth_probe(struct platf
+       struct resource *res;
+       struct clk *clk;
+       struct device_node *np;
+-      const unsigned char *mac_addr = NULL;
+       int err;
+       printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+@@ -1435,12 +1434,8 @@ static int pxa168_eth_probe(struct platf
+       INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
+-      if (pdev->dev.of_node)
+-              mac_addr = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-      } else {
++      err = of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
++      if (err) {
+               /* try reading the mac address, if set by the bootloader */
+               pxa168_eth_get_mac_address(dev, dev->dev_addr);
+               if (!is_valid_ether_addr(dev->dev_addr)) {
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -4725,7 +4725,7 @@ static struct net_device *sky2_init_netd
+ {
+       struct sky2_port *sky2;
+       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+-      const void *iap;
++      int ret;
+       if (!dev)
+               return NULL;
+@@ -4795,10 +4795,8 @@ static struct net_device *sky2_init_netd
+        * 1) from device tree data
+        * 2) from internal registers set by bootloader
+        */
+-      iap = of_get_mac_address(hw->pdev->dev.of_node);
+-      if (!IS_ERR(iap))
+-              ether_addr_copy(dev->dev_addr, iap);
+-      else
++      ret = of_get_mac_address(hw->pdev->dev.of_node, dev->dev_addr);
++      if (ret)
+               memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8,
+                             ETH_ALEN);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2559,14 +2559,11 @@ static int __init mtk_init(struct net_de
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      const char *mac_addr;
++      int ret;
+-      mac_addr = of_get_mac_address(mac->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-
+-      /* If the mac address is invalid, use random mac address  */
+-      if (!is_valid_ether_addr(dev->dev_addr)) {
++      ret = of_get_mac_address(mac->of_node, dev->dev_addr);
++      if (ret) {
++              /* If the mac address is invalid, use random mac address */
+               eth_hw_addr_random(dev);
+               dev_err(eth->dev, "generated random MAC address %pM\n",
+                       dev->dev_addr);
+--- a/drivers/net/ethernet/micrel/ks8851_common.c
++++ b/drivers/net/ethernet/micrel/ks8851_common.c
+@@ -194,11 +194,10 @@ static void ks8851_read_mac_addr(struct
+ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np)
+ {
+       struct net_device *dev = ks->netdev;
+-      const u8 *mac_addr;
++      int ret;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      ret = of_get_mac_address(np, dev->dev_addr);
++      if (!ret) {
+               ks8851_write_mac_addr(dev);
+               return;
+       }
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -2815,7 +2815,6 @@ static int lan743x_pcidev_probe(struct p
+ {
+       struct lan743x_adapter *adapter = NULL;
+       struct net_device *netdev = NULL;
+-      const void *mac_addr;
+       int ret = -ENODEV;
+       netdev = devm_alloc_etherdev(&pdev->dev,
+@@ -2832,9 +2831,7 @@ static int lan743x_pcidev_probe(struct p
+                             NETIF_MSG_IFDOWN | NETIF_MSG_TX_QUEUED;
+       netdev->max_mtu = LAN743X_MAX_FRAME_SIZE;
+-      mac_addr = of_get_mac_address(pdev->dev.of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(adapter->mac_address, mac_addr);
++      of_get_mac_address(pdev->dev.of_node, adapter->mac_address);
+       ret = lan743x_pci_init(adapter, pdev);
+       if (ret)
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1348,9 +1348,7 @@ static int lpc_eth_drv_probe(struct plat
+       __lpc_get_mac(pldat, ndev->dev_addr);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+-              const char *macaddr = of_get_mac_address(np);
+-              if (!IS_ERR(macaddr))
+-                      ether_addr_copy(ndev->dev_addr, macaddr);
++              of_get_mac_address(np, ndev->dev_addr);
+       }
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -885,7 +885,7 @@ qca_spi_probe(struct spi_device *spi)
+       struct net_device *qcaspi_devs = NULL;
+       u8 legacy_mode = 0;
+       u16 signature;
+-      const char *mac;
++      int ret;
+       if (!spi->dev.of_node) {
+               dev_err(&spi->dev, "Missing device tree\n");
+@@ -962,12 +962,8 @@ qca_spi_probe(struct spi_device *spi)
+       spi_set_drvdata(spi, qcaspi_devs);
+-      mac = of_get_mac_address(spi->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(spi->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&spi->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/qualcomm/qca_uart.c
++++ b/drivers/net/ethernet/qualcomm/qca_uart.c
+@@ -323,7 +323,6 @@ static int qca_uart_probe(struct serdev_
+ {
+       struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+       struct qcauart *qca;
+-      const char *mac;
+       u32 speed = 115200;
+       int ret;
+@@ -348,12 +347,8 @@ static int qca_uart_probe(struct serdev_
+       of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+-      mac = of_get_mac_address(serdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(serdev->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -109,11 +109,13 @@ static void ravb_set_buffer_align(struct
+  * Ethernet AVB device doesn't have ROM for MAC address.
+  * This function gets the MAC address that was used by a bootloader.
+  */
+-static void ravb_read_mac_address(struct net_device *ndev, const u8 *mac)
++static void ravb_read_mac_address(struct device_node *np,
++                                struct net_device *ndev)
+ {
+-      if (!IS_ERR(mac)) {
+-              ether_addr_copy(ndev->dev_addr, mac);
+-      } else {
++      int ret;
++
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
+               u32 mahr = ravb_read(ndev, MAHR);
+               u32 malr = ravb_read(ndev, MALR);
+@@ -2189,7 +2191,7 @@ static int ravb_probe(struct platform_de
+       priv->msg_enable = RAVB_DEF_MSG_ENABLE;
+       /* Read and set MAC address */
+-      ravb_read_mac_address(ndev, of_get_mac_address(np));
++      ravb_read_mac_address(np, ndev);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+               dev_warn(&pdev->dev,
+                        "no valid MAC address supplied, using a random one\n");
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -3144,7 +3144,6 @@ static struct sh_eth_plat_data *sh_eth_p
+       struct device_node *np = dev->of_node;
+       struct sh_eth_plat_data *pdata;
+       phy_interface_t interface;
+-      const char *mac_addr;
+       int ret;
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+@@ -3156,9 +3155,7 @@ static struct sh_eth_plat_data *sh_eth_p
+               return NULL;
+       pdata->phy_interface = interface;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->mac_addr, mac_addr);
++      of_get_mac_address(np, pdata->mac_addr);
+       pdata->no_ether_link =
+               of_property_read_bool(np, "renesas,no-ether-link");
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
+@@ -25,8 +25,7 @@
+ #ifdef CONFIG_OF
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct sxgbe_dma_cfg *dma_cfg;
+@@ -35,7 +34,6 @@ static int sxgbe_probe_config_dt(struct
+       if (!np)
+               return -ENODEV;
+-      *mac = of_get_mac_address(np);
+       err = of_get_phy_mode(np, &plat->interface);
+       if (err && err != -ENODEV)
+               return err;
+@@ -63,8 +61,7 @@ static int sxgbe_probe_config_dt(struct
+ }
+ #else
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       return -ENOSYS;
+ }
+@@ -85,7 +82,6 @@ static int sxgbe_platform_probe(struct p
+       void __iomem *addr;
+       struct sxgbe_priv_data *priv = NULL;
+       struct sxgbe_plat_data *plat_dat = NULL;
+-      const char *mac = NULL;
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct device_node *node = dev->of_node;
+@@ -101,7 +97,7 @@ static int sxgbe_platform_probe(struct p
+               if (!plat_dat)
+                       return  -ENOMEM;
+-              ret = sxgbe_probe_config_dt(pdev, plat_dat, &mac);
++              ret = sxgbe_probe_config_dt(pdev, plat_dat);
+               if (ret) {
+                       pr_err("%s: main dt probe failed\n", __func__);
+                       return ret;
+@@ -122,8 +118,7 @@ static int sxgbe_platform_probe(struct p
+       }
+       /* Get MAC address if available (DT) */
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(priv->dev->dev_addr, mac);
++      of_get_mac_address(node, priv->dev->dev_addr);
+       /* Get the TX/RX IRQ numbers */
+       for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
+--- a/drivers/net/ethernet/socionext/sni_ave.c
++++ b/drivers/net/ethernet/socionext/sni_ave.c
+@@ -1559,7 +1559,6 @@ static int ave_probe(struct platform_dev
+       struct ave_private *priv;
+       struct net_device *ndev;
+       struct device_node *np;
+-      const void *mac_addr;
+       void __iomem *base;
+       const char *name;
+       int i, irq, ret;
+@@ -1600,12 +1599,9 @@ static int ave_probe(struct platform_dev
+       ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* if the mac address is invalid, use random mac address */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the mac address is invalid, use random mac address */
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "Using random MAC address: %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+@@ -115,7 +115,7 @@ static int anarion_dwmac_probe(struct pl
+       if (IS_ERR(gmac))
+               return PTR_ERR(gmac);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+@@ -444,7 +444,7 @@ static int dwc_eth_dwmac_probe(struct pl
+       if (IS_ERR(stmmac_res.addr))
+               return PTR_ERR(stmmac_res.addr);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct pl
+               return ret;
+       if (pdev->dev.of_node) {
+-              plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++              plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+               if (IS_ERR(plat_dat)) {
+                       dev_err(&pdev->dev, "dt configuration failed\n");
+                       return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
+@@ -226,7 +226,7 @@ static int imx_dwmac_probe(struct platfo
+       if (!dwmac)
+               return -ENOMEM;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+@@ -88,7 +88,7 @@ static int intel_eth_plat_probe(struct p
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -255,7 +255,7 @@ static int ipq806x_gmac_probe(struct pla
+       if (val)
+               return val;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -407,7 +407,7 @@ static int mediatek_dwmac_probe(struct p
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct pla
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+@@ -372,7 +372,7 @@ static int meson8b_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+@@ -118,7 +118,7 @@ static int oxnas_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+@@ -461,7 +461,7 @@ static int qcom_ethqos_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -1396,7 +1396,7 @@ static int rk_gmac_probe(struct platform
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -398,7 +398,7 @@ static int socfpga_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+@@ -325,7 +325,7 @@ static int sti_dwmac_probe(struct platfo
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+@@ -371,7 +371,7 @@ static int stm32_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+@@ -1202,7 +1202,7 @@ static int sun8i_dwmac_probe(struct plat
+       if (ret)
+               return -EINVAL;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platf
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -25,7 +25,7 @@
+ struct stmmac_resources {
+       void __iomem *addr;
+-      const char *mac;
++      u8 mac[ETH_ALEN];
+       int wol_irq;
+       int lpi_irq;
+       int irq;
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4911,7 +4911,7 @@ int stmmac_dvr_probe(struct device *devi
+       priv->wol_irq = res->wol_irq;
+       priv->lpi_irq = res->lpi_irq;
+-      if (!IS_ERR_OR_NULL(res->mac))
++      if (!is_zero_ether_addr(res->mac))
+               memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
+       dev_set_drvdata(device, priv->dev);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -394,7 +394,7 @@ static int stmmac_of_get_mac_mode(struct
+  * set some private fields that will be used by the main at runtime.
+  */
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct plat_stmmacenet_data *plat;
+@@ -405,12 +405,12 @@ stmmac_probe_config_dt(struct platform_d
+       if (!plat)
+               return ERR_PTR(-ENOMEM);
+-      *mac = of_get_mac_address(np);
+-      if (IS_ERR(*mac)) {
+-              if (PTR_ERR(*mac) == -EPROBE_DEFER)
+-                      return ERR_CAST(*mac);
++      rc = of_get_mac_address(np, mac);
++      if (rc) {
++              if (rc == -EPROBE_DEFER)
++                      return ERR_PTR(rc);
+-              *mac = NULL;
++              eth_zero_addr(mac);
+       }
+       plat->phy_interface = device_get_phy_mode(&pdev->dev);
+@@ -631,7 +631,7 @@ void stmmac_remove_config_dt(struct plat
+ }
+ #else
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       return ERR_PTR(-EINVAL);
+ }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+@@ -12,7 +12,7 @@
+ #include "stmmac.h"
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+ void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat);
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1741,7 +1741,6 @@ static int am65_cpsw_nuss_init_slave_por
+       for_each_child_of_node(node, port_np) {
+               struct am65_cpsw_port *port;
+-              const void *mac_addr;
+               u32 port_id;
+               /* it is not a slave port node, continue */
+@@ -1820,15 +1819,15 @@ static int am65_cpsw_nuss_init_slave_por
+                       return ret;
+               }
+-              mac_addr = of_get_mac_address(port_np);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(port->slave.mac_addr, mac_addr);
+-              } else if (am65_cpsw_am654_get_efuse_macid(port_np,
+-                                                         port->port_id,
+-                                                         port->slave.mac_addr) ||
+-                         !is_valid_ether_addr(port->slave.mac_addr)) {
+-                      random_ether_addr(port->slave.mac_addr);
+-                      dev_err(dev, "Use random MAC address\n");
++              ret = of_get_mac_address(port_np, port->slave.mac_addr);
++              if (ret) {
++                      am65_cpsw_am654_get_efuse_macid(port_np,
++                                                      port->port_id,
++                                                      port->slave.mac_addr);
++                      if (!is_valid_ether_addr(port->slave.mac_addr)) {
++                              random_ether_addr(port->slave.mac_addr);
++                              dev_err(dev, "Use random MAC address\n");
++                      }
+               }
+       }
+       of_node_put(node);
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -1306,7 +1306,6 @@ static int cpsw_probe_dt(struct cpsw_pla
+       for_each_available_child_of_node(node, slave_node) {
+               struct cpsw_slave_data *slave_data = data->slave_data + i;
+-              const void *mac_addr = NULL;
+               int lenp;
+               const __be32 *parp;
+@@ -1378,10 +1377,8 @@ static int cpsw_probe_dt(struct cpsw_pla
+               }
+ no_phy_slave:
+-              mac_addr = of_get_mac_address(slave_node);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(slave_data->mac_addr, mac_addr);
+-              } else {
++              ret = of_get_mac_address(slave_node, slave_data->mac_addr);
++              if (ret) {
+                       ret = ti_cm_get_macid(&pdev->dev, i,
+                                             slave_data->mac_addr);
+                       if (ret)
+--- a/drivers/net/ethernet/ti/cpsw_new.c
++++ b/drivers/net/ethernet/ti/cpsw_new.c
+@@ -1267,7 +1267,6 @@ static int cpsw_probe_dt(struct cpsw_com
+       for_each_child_of_node(tmp_node, port_np) {
+               struct cpsw_slave_data *slave_data;
+-              const void *mac_addr;
+               u32 port_id;
+               ret = of_property_read_u32(port_np, "reg", &port_id);
+@@ -1326,10 +1325,8 @@ static int cpsw_probe_dt(struct cpsw_com
+                       goto err_node_put;
+               }
+-              mac_addr = of_get_mac_address(port_np);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(slave_data->mac_addr, mac_addr);
+-              } else {
++              ret = of_get_mac_address(port_np, slave_data->mac_addr);
++              if (ret) {
+                       ret = ti_cm_get_macid(dev, port_id - 1,
+                                             slave_data->mac_addr);
+                       if (ret)
+--- a/drivers/net/ethernet/ti/davinci_emac.c
++++ b/drivers/net/ethernet/ti/davinci_emac.c
+@@ -1687,7 +1687,6 @@ davinci_emac_of_get_pdata(struct platfor
+       const struct of_device_id *match;
+       const struct emac_platform_data *auxdata;
+       struct emac_platform_data *pdata = NULL;
+-      const u8 *mac_addr;
+       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+               return dev_get_platdata(&pdev->dev);
+@@ -1699,11 +1698,8 @@ davinci_emac_of_get_pdata(struct platfor
+       np = pdev->dev.of_node;
+       pdata->version = EMAC_VERSION_2;
+-      if (!is_valid_ether_addr(pdata->mac_addr)) {
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(pdata->mac_addr, mac_addr);
+-      }
++      if (!is_valid_ether_addr(pdata->mac_addr))
++              of_get_mac_address(np, pdata->mac_addr);
+       of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
+                            &pdata->ctrl_reg_offset);
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1966,7 +1966,6 @@ static int netcp_create_interface(struct
+       struct resource res;
+       void __iomem *efuse = NULL;
+       u32 efuse_mac = 0;
+-      const void *mac_addr;
+       u8 efuse_mac_addr[6];
+       u32 temp[2];
+       int ret = 0;
+@@ -2036,10 +2035,8 @@ static int netcp_create_interface(struct
+               devm_iounmap(dev, efuse);
+               devm_release_mem_region(dev, res.start, size);
+       } else {
+-              mac_addr = of_get_mac_address(node_interface);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(ndev->dev_addr, mac_addr);
+-              else
++              ret = of_get_mac_address(node_interface, ndev->dev_addr);
++              if (ret)
+                       eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/wiznet/w5100-spi.c
++++ b/drivers/net/ethernet/wiznet/w5100-spi.c
+@@ -423,8 +423,14 @@ static int w5100_spi_probe(struct spi_de
+       const struct of_device_id *of_id;
+       const struct w5100_ops *ops;
+       kernel_ulong_t driver_data;
++      const void *mac = NULL;
++      u8 tmpmac[ETH_ALEN];
+       int priv_size;
+-      const void *mac = of_get_mac_address(spi->dev.of_node);
++      int ret;
++
++      ret = of_get_mac_address(spi->dev.of_node, tmpmac);
++      if (!ret)
++              mac = tmpmac;
+       if (spi->dev.of_node) {
+               of_id = of_match_device(w5100_of_match, &spi->dev);
+--- a/drivers/net/ethernet/wiznet/w5100.c
++++ b/drivers/net/ethernet/wiznet/w5100.c
+@@ -1157,7 +1157,7 @@ int w5100_probe(struct device *dev, cons
+       INIT_WORK(&priv->setrx_work, w5100_setrx_work);
+       INIT_WORK(&priv->restart_work, w5100_restart_work);
+-      if (!IS_ERR_OR_NULL(mac_addr))
++      if (mac_addr)
+               memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+       else
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
+@@ -438,7 +438,7 @@ static void temac_do_set_mac_address(str
+ static int temac_init_mac_address(struct net_device *ndev, const void *address)
+ {
+-      ether_addr_copy(ndev->dev_addr, address);
++      memcpy(ndev->dev_addr, address, ETH_ALEN);
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+       temac_do_set_mac_address(ndev);
+@@ -1351,7 +1351,7 @@ static int temac_probe(struct platform_d
+       struct device_node *temac_np = dev_of_node(&pdev->dev), *dma_np;
+       struct temac_local *lp;
+       struct net_device *ndev;
+-      const void *addr;
++      u8 addr[ETH_ALEN];
+       __be32 *p;
+       bool little_endian;
+       int rc = 0;
+@@ -1542,8 +1542,8 @@ static int temac_probe(struct platform_d
+       if (temac_np) {
+               /* Retrieve the MAC address */
+-              addr = of_get_mac_address(temac_np);
+-              if (IS_ERR(addr)) {
++              rc = of_get_mac_address(temac_np, addr);
++              if (rc) {
+                       dev_err(&pdev->dev, "could not find MAC address\n");
+                       return -ENODEV;
+               }
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1803,8 +1803,8 @@ static int axienet_probe(struct platform
+       struct device_node *np;
+       struct axienet_local *lp;
+       struct net_device *ndev;
+-      const void *mac_addr;
+       struct resource *ethres;
++      u8 mac_addr[ETH_ALEN];
+       int addr_width = 32;
+       u32 value;
+@@ -2004,13 +2004,14 @@ static int axienet_probe(struct platform
+               dev_info(&pdev->dev, "Ethernet core IRQ not defined\n");
+       /* Retrieve the MAC address */
+-      mac_addr = of_get_mac_address(pdev->dev.of_node);
+-      if (IS_ERR(mac_addr)) {
+-              dev_warn(&pdev->dev, "could not find MAC address property: %ld\n",
+-                       PTR_ERR(mac_addr));
+-              mac_addr = NULL;
++      ret = of_get_mac_address(pdev->dev.of_node, mac_addr);
++      if (!ret) {
++              axienet_set_mac_address(ndev, mac_addr);
++      } else {
++              dev_warn(&pdev->dev, "could not find MAC address property: %d\n",
++                       ret);
++              axienet_set_mac_address(ndev, NULL);
+       }
+-      axienet_set_mac_address(ndev, mac_addr);
+       lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
+       lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1113,7 +1113,6 @@ static int xemaclite_of_probe(struct pla
+       struct net_device *ndev = NULL;
+       struct net_local *lp = NULL;
+       struct device *dev = &ofdev->dev;
+-      const void *mac_address;
+       int rc = 0;
+@@ -1155,12 +1154,9 @@ static int xemaclite_of_probe(struct pla
+       lp->next_rx_buf_to_use = 0x0;
+       lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong");
+       lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong");
+-      mac_address = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_address)) {
+-              /* Set the MAC address. */
+-              ether_addr_copy(ndev->dev_addr, mac_address);
+-      } else {
++      rc = of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
++      if (rc) {
+               dev_warn(dev, "No MAC address found, using random\n");
+               eth_hw_addr_random(ndev);
+       }
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -618,7 +618,6 @@ static int ath9k_of_init(struct ath_soft
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
+-      const char *mac;
+       char eeprom_name[100];
+       int ret;
+@@ -641,9 +640,7 @@ static int ath9k_of_init(struct ath_soft
+               ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(common->macaddr, mac);
++      of_get_mac_address(np, common->macaddr);
+       return 0;
+ }
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -90,15 +90,9 @@ out_put_node:
+ void
+ mt76_eeprom_override(struct mt76_dev *dev)
+ {
+-#ifdef CONFIG_OF
+       struct device_node *np = dev->dev->of_node;
+-      const u8 *mac = NULL;
+-      if (np)
+-              mac = of_get_mac_address(np);
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->macaddr, mac);
+-#endif
++      of_get_mac_address(np, dev->macaddr);
+       if (!is_valid_ether_addr(dev->macaddr)) {
+               eth_random_addr(dev->macaddr);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -990,11 +990,7 @@ static void rt2x00lib_rate(struct ieee80
+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+ {
+-      const char *mac_addr;
+-
+-      mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(eeprom_mac_addr, mac_addr);
++      of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+       if (!is_valid_ether_addr(eeprom_mac_addr)) {
+               eth_random_addr(eeprom_mac_addr);
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -45,37 +45,29 @@ int of_get_phy_mode(struct device_node *
+ }
+ EXPORT_SYMBOL_GPL(of_get_phy_mode);
+-static const void *of_get_mac_addr(struct device_node *np, const char *name)
++static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
+ {
+       struct property *pp = of_find_property(np, name, NULL);
+-      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value))
+-              return pp->value;
+-      return NULL;
++      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)) {
++              memcpy(addr, pp->value, ETH_ALEN);
++              return 0;
++      }
++      return -ENODEV;
+ }
+-static const void *of_get_mac_addr_nvmem(struct device_node *np)
++static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
+ {
+-      int ret;
+-      const void *mac;
+-      u8 nvmem_mac[ETH_ALEN];
+       struct platform_device *pdev = of_find_device_by_node(np);
++      int ret;
+       if (!pdev)
+-              return ERR_PTR(-ENODEV);
++              return -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);
++      ret = nvmem_get_mac_address(&pdev->dev, addr);
+       put_device(&pdev->dev);
+-      if (!mac)
+-              return ERR_PTR(-ENOMEM);
+-      return mac;
++      return ret;
+ }
+ /**
+@@ -98,24 +90,27 @@ static const void *of_get_mac_addr_nvmem
+  * 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.
++ * Return: 0 on success and errno in case of error.
+ */
+-const void *of_get_mac_address(struct device_node *np)
++int of_get_mac_address(struct device_node *np, u8 *addr)
+ {
+-      const void *addr;
+-
+-      addr = of_get_mac_addr(np, "mac-address");
+-      if (addr)
+-              return addr;
++      int ret;
+-      addr = of_get_mac_addr(np, "local-mac-address");
+-      if (addr)
+-              return addr;
++      if (!np)
++              return -ENODEV;
+-      addr = of_get_mac_addr(np, "address");
+-      if (addr)
+-              return addr;
++      ret = of_get_mac_addr(np, "mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "local-mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "address", addr);
++      if (!ret)
++              return 0;
+-      return of_get_mac_addr_nvmem(np);
++      return of_get_mac_addr_nvmem(np, addr);
+ }
+ EXPORT_SYMBOL(of_get_mac_address);
+--- a/drivers/staging/octeon/ethernet.c
++++ b/drivers/staging/octeon/ethernet.c
+@@ -407,14 +407,10 @@ static int cvm_oct_common_set_mac_addres
+ int cvm_oct_common_init(struct net_device *dev)
+ {
+       struct octeon_ethernet *priv = netdev_priv(dev);
+-      const u8 *mac = NULL;
++      int ret;
+-      if (priv->of_node)
+-              mac = of_get_mac_address(priv->of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->dev_addr, mac);
+-      else
++      ret = of_get_mac_address(priv->of_node, dev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(dev);
+       /*
+--- a/drivers/staging/wfx/main.c
++++ b/drivers/staging/wfx/main.c
+@@ -334,7 +334,6 @@ int wfx_probe(struct wfx_dev *wdev)
+ {
+       int i;
+       int err;
+-      const void *macaddr;
+       struct gpio_desc *gpio_saved;
+       // During first part of boot, gpio_wakeup cannot yet been used. So
+@@ -423,9 +422,9 @@ int wfx_probe(struct wfx_dev *wdev)
+       for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) {
+               eth_zero_addr(wdev->addresses[i].addr);
+-              macaddr = of_get_mac_address(wdev->dev->of_node);
+-              if (!IS_ERR_OR_NULL(macaddr)) {
+-                      ether_addr_copy(wdev->addresses[i].addr, macaddr);
++              err = of_get_mac_address(wdev->dev->of_node,
++                                       wdev->addresses[i].addr);
++              if (!err) {
+                       wdev->addresses[i].addr[ETH_ALEN - 1] += i;
+               } else {
+                       ether_addr_copy(wdev->addresses[i].addr,
+--- a/include/linux/of_net.h
++++ b/include/linux/of_net.h
+@@ -13,7 +13,7 @@
+ struct net_device;
+ extern int of_get_phy_mode(struct device_node *np, phy_interface_t *interface);
+-extern const void *of_get_mac_address(struct device_node *np);
++extern int of_get_mac_address(struct device_node *np, u8 *mac);
+ extern struct net_device *of_find_net_device_by_node(struct device_node *np);
+ #else
+ static inline int of_get_phy_mode(struct device_node *np,
+@@ -22,9 +22,9 @@ static inline int of_get_phy_mode(struct
+       return -ENODEV;
+ }
+-static inline const void *of_get_mac_address(struct device_node *np)
++static inline int of_get_mac_address(struct device_node *np, u8 *mac)
+ {
+-      return ERR_PTR(-ENODEV);
++      return -ENODEV;
+ }
+ static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -208,7 +208,7 @@ struct dsa_port {
+       unsigned int            index;
+       const char              *name;
+       struct dsa_port         *cpu_dp;
+-      const char              *mac;
++      u8                      mac[ETH_ALEN];
+       struct device_node      *dn;
+       unsigned int            ageing_time;
+       bool                    vlan_filtering;
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -288,7 +288,7 @@ static int dsa_port_setup(struct dsa_por
+               break;
+       case DSA_PORT_TYPE_USER:
+-              dp->mac = of_get_mac_address(dp->dn);
++              of_get_mac_address(dp->dn, dp->mac);
+               err = dsa_slave_create(dp);
+               if (err)
+                       break;
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1852,7 +1852,7 @@ int dsa_slave_create(struct dsa_port *po
+       slave_dev->hw_features |= NETIF_F_HW_TC;
+       slave_dev->features |= NETIF_F_LLTX;
+       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
+-      if (!IS_ERR_OR_NULL(port->mac))
++      if (!is_zero_ether_addr(port->mac))
+               ether_addr_copy(slave_dev->dev_addr, port->mac);
+       else
+               eth_hw_addr_inherit(slave_dev, master);
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -506,13 +506,14 @@ unsigned char * __weak arch_get_platform
+ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+ {
+-      const unsigned char *addr = NULL;
++      unsigned char *addr;
++      int ret;
+-      if (dev->of_node)
+-              addr = of_get_mac_address(dev->of_node);
+-      if (IS_ERR_OR_NULL(addr))
+-              addr = arch_get_platform_mac_address();
++      ret = of_get_mac_address(dev->of_node, mac_addr);
++      if (!ret)
++              return 0;
++      addr = arch_get_platform_mac_address();
+       if (!addr)
+               return -ENODEV;
diff --git a/target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch b/target/linux/generic/backport-5.10/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch
new file mode 100644 (file)
index 0000000..245c5f3
--- /dev/null
@@ -0,0 +1,77 @@
+From f10843e04a075202dbb39dfcee047e3a2fdf5a8d Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:18 +0200
+Subject: of: net: fix of_get_mac_addr_nvmem() for non-platform devices
+
+of_get_mac_address() already supports fetching the MAC address by an
+nvmem provider. But until now, it was just working for platform devices.
+Esp. it was not working for DSA ports and PCI devices. It gets more
+common that PCI devices have a device tree binding since SoCs contain
+integrated root complexes.
+
+Use the nvmem of_* binding to fetch the nvmem cells by a struct
+device_node. We still have to try to read the cell by device first
+because there might be a nvmem_cell_lookup associated with that device.
+
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/of/of_net.c | 35 ++++++++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -11,6 +11,7 @@
+ #include <linux/phy.h>
+ #include <linux/export.h>
+ #include <linux/device.h>
++#include <linux/nvmem-consumer.h>
+ /**
+  * of_get_phy_mode - Get phy mode for given device_node
+@@ -59,15 +60,39 @@ static int of_get_mac_addr(struct device
+ 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;
++      size_t len;
+       int ret;
+-      if (!pdev)
+-              return -ENODEV;
++      /* Try lookup by device first, there might be a nvmem_cell_lookup
++       * associated with a given device.
++       */
++      if (pdev) {
++              ret = nvmem_get_mac_address(&pdev->dev, addr);
++              put_device(&pdev->dev);
++              return ret;
++      }
++
++      cell = of_nvmem_cell_get(np, "mac-address");
++      if (IS_ERR(cell))
++              return PTR_ERR(cell);
++
++      mac = 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;
++      }
+-      ret = nvmem_get_mac_address(&pdev->dev, addr);
+-      put_device(&pdev->dev);
++      memcpy(addr, mac, ETH_ALEN);
++      kfree(mac);
+-      return ret;
++      return 0;
+ }
+ /**
diff --git a/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/target/linux/generic/backport-5.4/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
new file mode 100644 (file)
index 0000000..e743e1e
--- /dev/null
@@ -0,0 +1,1759 @@
+From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:17 +0200
+Subject: of: net: pass the dst buffer to of_get_mac_address()
+
+of_get_mac_address() returns a "const void*" pointer to a MAC address.
+Lately, support to fetch the MAC address by an NVMEM provider was added.
+But this will only work with platform devices. It will not work with
+PCI devices (e.g. of an integrated root complex) and esp. not with DSA
+ports.
+
+There is an of_* variant of the nvmem binding which works without
+devices. The returned data of a nvmem_cell_read() has to be freed after
+use. On the other hand the return of_get_mac_address() points to some
+static data without a lifetime. The trick for now, was to allocate a
+device resource managed buffer which is then returned. This will only
+work if we have an actual device.
+
+Change it, so that the caller of of_get_mac_address() has to supply a
+buffer where the MAC address is written to. Unfortunately, this will
+touch all drivers which use the of_get_mac_address().
+
+Usually the code looks like:
+
+  const char *addr;
+  addr = of_get_mac_address(np);
+  if (!IS_ERR(addr))
+    ether_addr_copy(ndev->dev_addr, addr);
+
+This can then be simply rewritten as:
+
+  of_get_mac_address(np, ndev->dev_addr);
+
+Sometimes is_valid_ether_addr() is used to test the MAC address.
+of_get_mac_address() already makes sure, it just returns a valid MAC
+address. Thus we can just test its return code. But we have to be
+careful if there are still other sources for the MAC address before the
+of_get_mac_address(). In this case we have to keep the
+is_valid_ether_addr() call.
+
+The following coccinelle patch was used to convert common cases to the
+new style. Afterwards, I've manually gone over the drivers and fixed the
+return code variable: either used a new one or if one was already
+available use that. Mansour Moufid, thanks for that coccinelle patch!
+
+<spml>
+@a@
+identifier x;
+expression y, z;
+@@
+- x = of_get_mac_address(y);
++ x = of_get_mac_address(y, z);
+  <...
+- ether_addr_copy(z, x);
+  ...>
+
+@@
+identifier a.x;
+@@
+- if (<+... x ...+>) {}
+
+@@
+identifier a.x;
+@@
+  if (<+... x ...+>) {
+      ...
+  }
+- else {}
+
+@@
+identifier a.x;
+expression e;
+@@
+- if (<+... x ...+>@e)
+-     {}
+- else
++ if (!(e))
+      {...}
+
+@@
+expression x, y, z;
+@@
+- x = of_get_mac_address(y, z);
++ of_get_mac_address(y, z);
+  ... when != x
+</spml>
+
+All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
+compile-time tested.
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm/mach-mvebu/kirkwood.c                     |  3 +-
+ arch/powerpc/sysdev/tsi108_dev.c                   |  5 +-
+ drivers/net/ethernet/aeroflex/greth.c              |  6 +--
+ drivers/net/ethernet/allwinner/sun4i-emac.c        | 10 ++--
+ drivers/net/ethernet/altera/altera_tse_main.c      |  7 +--
+ drivers/net/ethernet/arc/emac_main.c               |  8 +--
+ drivers/net/ethernet/atheros/ag71xx.c              |  7 +--
+ drivers/net/ethernet/broadcom/bcm4908_enet.c       |  7 +--
+ drivers/net/ethernet/broadcom/bcmsysport.c         |  7 +--
+ drivers/net/ethernet/broadcom/bgmac-bcma.c         | 10 ++--
+ drivers/net/ethernet/broadcom/bgmac-platform.c     | 11 ++--
+ drivers/net/ethernet/cadence/macb_main.c           | 11 ++--
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c   |  8 +--
+ drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  5 +-
+ drivers/net/ethernet/davicom/dm9000.c              | 10 ++--
+ drivers/net/ethernet/ethoc.c                       |  6 +--
+ drivers/net/ethernet/ezchip/nps_enet.c             |  7 +--
+ drivers/net/ethernet/freescale/fec_main.c          |  7 +--
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |  7 +--
+ drivers/net/ethernet/freescale/fman/mac.c          |  9 ++--
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |  5 +-
+ drivers/net/ethernet/freescale/gianfar.c           |  8 +--
+ drivers/net/ethernet/freescale/ucc_geth.c          |  5 +-
+ drivers/net/ethernet/hisilicon/hisi_femac.c        |  7 +--
+ drivers/net/ethernet/hisilicon/hix5hd2_gmac.c      |  7 +--
+ drivers/net/ethernet/lantiq_xrx200.c               |  7 +--
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |  5 +-
+ drivers/net/ethernet/marvell/mvneta.c              |  6 +--
+ .../net/ethernet/marvell/prestera/prestera_main.c  | 11 ++--
+ drivers/net/ethernet/marvell/pxa168_eth.c          |  9 +---
+ drivers/net/ethernet/marvell/sky2.c                |  8 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c        | 11 ++--
+ drivers/net/ethernet/micrel/ks8851_common.c        |  7 ++-
+ drivers/net/ethernet/microchip/lan743x_main.c      |  5 +-
+ drivers/net/ethernet/nxp/lpc_eth.c                 |  4 +-
+ drivers/net/ethernet/qualcomm/qca_spi.c            | 10 ++--
+ drivers/net/ethernet/qualcomm/qca_uart.c           |  9 +---
+ drivers/net/ethernet/renesas/ravb_main.c           | 12 +++--
+ drivers/net/ethernet/renesas/sh_eth.c              |  5 +-
+ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c    | 13 ++---
+ drivers/net/ethernet/socionext/sni_ave.c           | 10 ++--
+ .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-generic.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c    |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-mediatek.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c  |  2 +-
+ .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-visconti.c   |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  2 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 14 ++---
+ .../net/ethernet/stmicro/stmmac/stmmac_platform.h  |  2 +-
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c           | 19 ++++---
+ drivers/net/ethernet/ti/cpsw.c                     |  7 +--
+ drivers/net/ethernet/ti/cpsw_new.c                 |  7 +--
+ drivers/net/ethernet/ti/davinci_emac.c             |  8 +--
+ drivers/net/ethernet/ti/netcp_core.c               |  7 +--
+ drivers/net/ethernet/wiznet/w5100-spi.c            |  8 ++-
+ drivers/net/ethernet/wiznet/w5100.c                |  2 +-
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |  8 +--
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 15 +++---
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |  8 +--
+ drivers/net/wireless/ath/ath9k/init.c              |  5 +-
+ drivers/net/wireless/mediatek/mt76/eeprom.c        |  9 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |  6 +--
+ drivers/of/of_net.c                                | 60 ++++++++++------------
+ drivers/staging/octeon/ethernet.c                  | 10 ++--
+ drivers/staging/wfx/main.c                         |  7 ++-
+ include/linux/of_net.h                             |  6 +--
+ include/net/dsa.h                                  |  2 +-
+ net/dsa/dsa2.c                                     |  2 +-
+ net/dsa/slave.c                                    |  2 +-
+ net/ethernet/eth.c                                 | 11 ++--
+ 85 files changed, 218 insertions(+), 364 deletions(-)
+
+--- a/arch/arm/mach-mvebu/kirkwood.c
++++ b/arch/arm/mach-mvebu/kirkwood.c
+@@ -84,6 +84,7 @@ static void __init kirkwood_dt_eth_fixup
+               struct device_node *pnp = of_get_parent(np);
+               struct clk *clk;
+               struct property *pmac;
++              u8 tmpmac[ETH_ALEN];
+               void __iomem *io;
+               u8 *macaddr;
+               u32 reg;
+@@ -93,7 +94,7 @@ static void __init kirkwood_dt_eth_fixup
+               /* skip disabled nodes or nodes with valid MAC address*/
+               if (!of_device_is_available(pnp) ||
+-                  !IS_ERR(of_get_mac_address(np)))
++                  !of_get_mac_address(np, tmpmac))
+                       goto eth_fixup_skip;
+               clk = of_clk_get(pnp, 0);
+--- a/arch/powerpc/sysdev/tsi108_dev.c
++++ b/arch/powerpc/sysdev/tsi108_dev.c
+@@ -73,7 +73,6 @@ static int __init tsi108_eth_of_init(voi
+               struct device_node *phy, *mdio;
+               hw_info tsi_eth_data;
+               const unsigned int *phy_id;
+-              const void *mac_addr;
+               const phandle *ph;
+               memset(r, 0, sizeof(r));
+@@ -101,9 +100,7 @@ static int __init tsi108_eth_of_init(voi
+                       goto err;
+               }
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(tsi_eth_data.mac_addr, mac_addr);
++              of_get_mac_address(np, tsi_eth_data.mac_addr);
+               ph = of_get_property(np, "mdio-handle", NULL);
+               mdio = of_find_node_by_phandle(*ph);
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -1451,10 +1451,10 @@ static int greth_of_probe(struct platfor
+                       break;
+       }
+       if (i == 6) {
+-              const u8 *addr;
++              u8 addr[ETH_ALEN];
+-              addr = of_get_mac_address(ofdev->dev.of_node);
+-              if (!IS_ERR(addr)) {
++              err = of_get_mac_address(ofdev->dev.of_node, addr);
++              if (!err) {
+                       for (i = 0; i < 6; i++)
+                               macaddr[i] = (unsigned int) addr[i];
+               } else {
+--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
++++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
+@@ -807,7 +807,6 @@ static int emac_probe(struct platform_de
+       struct emac_board_info *db;
+       struct net_device *ndev;
+       int ret = 0;
+-      const char *mac_addr;
+       ndev = alloc_etherdev(sizeof(struct emac_board_info));
+       if (!ndev) {
+@@ -870,12 +869,9 @@ static int emac_probe(struct platform_de
+       }
+       /* Read MAC-address from DT */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* Check if the MAC address is valid, if not get a random one */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the MAC address is invalid get a random one */
+               eth_hw_addr_random(ndev);
+               dev_warn(&pdev->dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/altera/altera_tse_main.c
++++ b/drivers/net/ethernet/altera/altera_tse_main.c
+@@ -1351,7 +1351,6 @@ static int altera_tse_probe(struct platf
+       struct resource *control_port;
+       struct resource *dma_res;
+       struct altera_tse_private *priv;
+-      const unsigned char *macaddr;
+       void __iomem *descmap;
+       const struct of_device_id *of_id = NULL;
+@@ -1525,10 +1524,8 @@ static int altera_tse_probe(struct platf
+       priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;
+       /* get default MAC address from device tree */
+-      macaddr = of_get_mac_address(pdev->dev.of_node);
+-      if (!IS_ERR(macaddr))
+-              ether_addr_copy(ndev->dev_addr, macaddr);
+-      else
++      ret = of_get_mac_address(pdev->dev.of_node, ndev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(ndev);
+       /* get phy addr and create mdio */
+--- a/drivers/net/ethernet/arc/emac_main.c
++++ b/drivers/net/ethernet/arc/emac_main.c
+@@ -870,7 +870,6 @@ int arc_emac_probe(struct net_device *nd
+       struct device_node *phy_node;
+       struct phy_device *phydev = NULL;
+       struct arc_emac_priv *priv;
+-      const char *mac_addr;
+       unsigned int id, clock_frequency, irq;
+       int err;
+@@ -955,11 +954,8 @@ int arc_emac_probe(struct net_device *nd
+       }
+       /* Get MAC address from device tree */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       arc_emac_set_address_internal(ndev);
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1634,7 +1634,6 @@ static int ag71xx_probe(struct platform_
+       const struct ag71xx_dcfg *dcfg;
+       struct net_device *ndev;
+       struct resource *res;
+-      const void *mac_addr;
+       int tx_size, err, i;
+       struct ag71xx *ag;
+@@ -1735,10 +1734,8 @@ static int ag71xx_probe(struct platform_
+       ag->stop_desc->ctrl = 0;
+       ag->stop_desc->next = (u32)ag->stop_desc_dma;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+-      if (IS_ERR(mac_addr) || !is_valid_ether_addr(ndev->dev_addr)) {
++      err = of_get_mac_address(np, ndev->dev_addr);
++      if (err) {
+               netif_err(ag, probe, ndev, "invalid MAC address, using random address\n");
+               eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -2420,7 +2420,6 @@ static int bcm_sysport_probe(struct plat
+       struct bcm_sysport_priv *priv;
+       struct device_node *dn;
+       struct net_device *dev;
+-      const void *macaddr;
+       u32 txq, rxq;
+       int ret;
+@@ -2502,12 +2501,10 @@ static int bcm_sysport_probe(struct plat
+       }
+       /* Initialize netdevice members */
+-      macaddr = of_get_mac_address(dn);
+-      if (IS_ERR(macaddr)) {
++      ret = of_get_mac_address(dn, dev->dev_addr);
++      if (ret) {
+               dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+               eth_hw_addr_random(dev);
+-      } else {
+-              ether_addr_copy(dev->dev_addr, macaddr);
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -115,7 +115,7 @@ static int bgmac_probe(struct bcma_devic
+       struct ssb_sprom *sprom = &core->bus->sprom;
+       struct mii_bus *mii_bus;
+       struct bgmac *bgmac;
+-      const u8 *mac = NULL;
++      const u8 *mac;
+       int err;
+       bgmac = bgmac_alloc(&core->dev);
+@@ -128,11 +128,10 @@ static int bgmac_probe(struct bcma_devic
+       bcma_set_drvdata(core, bgmac);
+-      if (bgmac->dev->of_node)
+-              mac = of_get_mac_address(bgmac->dev->of_node);
++      err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr);
+       /* If no MAC address assigned via device tree, check SPROM */
+-      if (IS_ERR_OR_NULL(mac)) {
++      if (err) {
+               switch (core->core_unit) {
+               case 0:
+                       mac = sprom->et0mac;
+@@ -149,10 +148,9 @@ static int bgmac_probe(struct bcma_devic
+                       err = -ENOTSUPP;
+                       goto err;
+               }
++              ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+       }
+-      ether_addr_copy(bgmac->net_dev->dev_addr, mac);
+-
+       /* On BCM4706 we need common core to access PHY */
+       if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
+           !core->bus->drv_gmac_cmn.core) {
+--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
+@@ -173,7 +173,7 @@ static int bgmac_probe(struct platform_d
+       struct device_node *np = pdev->dev.of_node;
+       struct bgmac *bgmac;
+       struct resource *regs;
+-      const u8 *mac_addr;
++      int ret;
+       bgmac = bgmac_alloc(&pdev->dev);
+       if (!bgmac)
+@@ -192,11 +192,10 @@ static int bgmac_probe(struct platform_d
+       bgmac->dev = &pdev->dev;
+       bgmac->dma_dev = &pdev->dev;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(bgmac->net_dev->dev_addr, mac_addr);
+-      else
+-              dev_warn(&pdev->dev, "MAC address not present in device tree\n");
++      ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
++      if (ret)
++              dev_warn(&pdev->dev,
++                       "MAC address not present in device tree\n");
+       bgmac->irq = platform_get_irq(pdev, 0);
+       if (bgmac->irq < 0)
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -4203,7 +4203,6 @@ static int macb_probe(struct platform_de
+       struct net_device *dev;
+       struct resource *regs;
+       void __iomem *mem;
+-      const char *mac;
+       struct macb *bp;
+       int err, val;
+@@ -4316,15 +4315,11 @@ static int macb_probe(struct platform_de
+       if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
+               bp->rx_intr_mask |= MACB_BIT(RXUBR);
+-      mac = of_get_mac_address(np);
+-      if (PTR_ERR(mac) == -EPROBE_DEFER) {
+-              err = -EPROBE_DEFER;
++      err = of_get_mac_address(np, bp->dev->dev_addr);
++      if (err == -EPROBE_DEFER)
+               goto err_out_free_netdev;
+-      } else if (!IS_ERR_OR_NULL(mac)) {
+-              ether_addr_copy(bp->dev->dev_addr, mac);
+-      } else {
++      else if (err)
+               macb_get_hwaddr(bp);
+-      }
+       err = of_get_phy_mode(np);
+       if (err < 0)
+--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
++++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+@@ -1391,7 +1391,6 @@ static int octeon_mgmt_probe(struct plat
+       struct net_device *netdev;
+       struct octeon_mgmt *p;
+       const __be32 *data;
+-      const u8 *mac;
+       struct resource *res_mix;
+       struct resource *res_agl;
+       struct resource *res_agl_prt_ctl;
+@@ -1508,11 +1507,8 @@ static int octeon_mgmt_probe(struct plat
+       netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
+       netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;
+-      mac = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(netdev->dev_addr, mac);
+-      else
++      result = of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
++      if (result)
+               eth_hw_addr_random(netdev);
+       p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1474,7 +1474,6 @@ static int bgx_init_of_phy(struct bgx *b
+       device_for_each_child_node(&bgx->pdev->dev, fwn) {
+               struct phy_device *pd;
+               struct device_node *phy_np;
+-              const char *mac;
+               /* Should always be an OF node.  But if it is not, we
+                * cannot handle it, so exit the loop.
+@@ -1483,9 +1482,7 @@ static int bgx_init_of_phy(struct bgx *b
+               if (!node)
+                       break;
+-              mac = of_get_mac_address(node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(bgx->lmac[lmac].mac, mac);
++              of_get_mac_address(node, bgx->lmac[lmac].mac);
+               SET_NETDEV_DEV(&bgx->lmac[lmac].netdev, &bgx->pdev->dev);
+               bgx->lmac[lmac].lmacid = lmac;
+--- a/drivers/net/ethernet/davicom/dm9000.c
++++ b/drivers/net/ethernet/davicom/dm9000.c
+@@ -1390,7 +1390,7 @@ static struct dm9000_plat_data *dm9000_p
+ {
+       struct dm9000_plat_data *pdata;
+       struct device_node *np = dev->of_node;
+-      const void *mac_addr;
++      int ret;
+       if (!IS_ENABLED(CONFIG_OF) || !np)
+               return ERR_PTR(-ENXIO);
+@@ -1404,11 +1404,9 @@ static struct dm9000_plat_data *dm9000_p
+       if (of_find_property(np, "davicom,no-eeprom", NULL))
+               pdata->flags |= DM9000_PLATF_NO_EEPROM;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->dev_addr, mac_addr);
+-      else if (PTR_ERR(mac_addr) == -EPROBE_DEFER)
+-              return ERR_CAST(mac_addr);
++      ret = of_get_mac_address(np, pdata->dev_addr);
++      if (ret == -EPROBE_DEFER)
++              return ERR_PTR(ret);
+       return pdata;
+ }
+--- a/drivers/net/ethernet/ethoc.c
++++ b/drivers/net/ethernet/ethoc.c
+@@ -1147,11 +1147,7 @@ static int ethoc_probe(struct platform_d
+               ether_addr_copy(netdev->dev_addr, pdata->hwaddr);
+               priv->phy_id = pdata->phy_id;
+       } else {
+-              const void *mac;
+-
+-              mac = of_get_mac_address(pdev->dev.of_node);
+-              if (!IS_ERR(mac))
+-                      ether_addr_copy(netdev->dev_addr, mac);
++              of_get_mac_address(pdev->dev.of_node, netdev->dev_addr);
+               priv->phy_id = -1;
+       }
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -575,7 +575,6 @@ static s32 nps_enet_probe(struct platfor
+       struct net_device *ndev;
+       struct nps_enet_priv *priv;
+       s32 err = 0;
+-      const char *mac_addr;
+       if (!dev->of_node)
+               return -ENODEV;
+@@ -602,10 +601,8 @@ static s32 nps_enet_probe(struct platfor
+       dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base);
+       /* set kernel MAC address to dev */
+-      mac_addr = of_get_mac_address(dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      else
++      err = of_get_mac_address(dev->of_node, ndev->dev_addr);
++      if (err)
+               eth_hw_addr_random(ndev);
+       /* Get IRQ number */
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1695,6 +1695,7 @@ static void fec_get_mac(struct net_devic
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
+       unsigned char *iap, tmpaddr[ETH_ALEN];
++      int ret;
+       /*
+        * try to get mac address in following order:
+@@ -1710,9 +1711,9 @@ static void fec_get_mac(struct net_devic
+       if (!is_valid_ether_addr(iap)) {
+               struct device_node *np = fep->pdev->dev.of_node;
+               if (np) {
+-                      const char *mac = of_get_mac_address(np);
+-                      if (!IS_ERR(mac))
+-                              iap = (unsigned char *) mac;
++                      ret = of_get_mac_address(np, tmpaddr);
++                      if (!ret)
++                              iap = tmpaddr;
+               }
+       }
+--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
++++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
+@@ -823,7 +823,6 @@ static int mpc52xx_fec_probe(struct plat
+       const u32 *prop;
+       int prop_size;
+       struct device_node *np = op->dev.of_node;
+-      const char *mac_addr;
+       phys_addr_t rx_fifo;
+       phys_addr_t tx_fifo;
+@@ -901,10 +900,8 @@ static int mpc52xx_fec_probe(struct plat
+        *
+        * First try to read MAC address from DT
+        */
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr)) {
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      } else {
++      rv = of_get_mac_address(np, ndev->dev_addr);
++      if (rv) {
+               struct mpc52xx_fec __iomem *fec = priv->fec;
+               /*
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -605,7 +605,6 @@ static int mac_probe(struct platform_dev
+       struct platform_device  *of_dev;
+       struct resource          res;
+       struct mac_priv_s       *priv;
+-      const u8                *mac_addr;
+       u32                      val;
+       u8                      fman_id;
+       int                     phy_if;
+@@ -723,13 +722,12 @@ static int mac_probe(struct platform_dev
+       priv->cell_index = (u8)val;
+       /* Get the MAC address */
+-      mac_addr = of_get_mac_address(mac_node);
+-      if (IS_ERR(mac_addr)) {
++      err = of_get_mac_address(mac_node, mac_dev->addr);
++      if (err) {
+               dev_err(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
+               err = -EINVAL;
+               goto _return_of_get_parent;
+       }
+-      ether_addr_copy(mac_dev->addr, mac_addr);
+       /* Get the port handles */
+       nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
+--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+@@ -925,7 +925,6 @@ static int fs_enet_probe(struct platform
+       const u32 *data;
+       struct clk *clk;
+       int err;
+-      const u8 *mac_addr;
+       const char *phy_connection_type;
+       int privsize, len, ret = -ENODEV;
+@@ -1013,9 +1012,7 @@ static int fs_enet_probe(struct platform
+       spin_lock_init(&fep->lock);
+       spin_lock_init(&fep->tx_lock);
+-      mac_addr = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
++      of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
+       ret = fep->ops->allocate_bd(ndev);
+       if (ret)
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -643,7 +643,6 @@ static phy_interface_t gfar_get_interfac
+ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+ {
+       const char *model;
+-      const void *mac_addr;
+       int err = 0, i;
+       struct net_device *dev = NULL;
+       struct gfar_private *priv = NULL;
+@@ -784,10 +783,7 @@ static int gfar_of_init(struct platform_
+       if (stash_len || stash_idx)
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+-      mac_addr = of_get_mac_address(np);
+-
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      err = of_get_mac_address(np, dev->dev_addr);
+       if (model && !strcasecmp(model, "TSEC"))
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
+--- a/drivers/net/ethernet/freescale/ucc_geth.c
++++ b/drivers/net/ethernet/freescale/ucc_geth.c
+@@ -3697,7 +3697,6 @@ static int ucc_geth_probe(struct platfor
+       int err, ucc_num, max_speed = 0;
+       const unsigned int *prop;
+       const char *sprop;
+-      const void *mac_addr;
+       phy_interface_t phy_interface;
+       static const int enet_to_speed[] = {
+               SPEED_10, SPEED_10, SPEED_10,
+@@ -3907,9 +3906,7 @@ static int ucc_geth_probe(struct platfor
+               goto err_free_netdev;
+       }
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
++      of_get_mac_address(np, dev->dev_addr);
+       ugeth->ug_info = ug_info;
+       ugeth->dev = device;
+--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
++++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
+@@ -784,7 +784,6 @@ static int hisi_femac_drv_probe(struct p
+       struct net_device *ndev;
+       struct hisi_femac_priv *priv;
+       struct phy_device *phy;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(*priv));
+@@ -854,10 +853,8 @@ static int hisi_femac_drv_probe(struct p
+                          (unsigned long)phy->phy_id,
+                          phy_modes(phy->interface));
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "using random MAC address %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
++++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+@@ -1098,7 +1098,6 @@ static int hix5hd2_dev_probe(struct plat
+       struct net_device *ndev;
+       struct hix5hd2_priv *priv;
+       struct mii_bus *bus;
+-      const char *mac_addr;
+       int ret;
+       ndev = alloc_etherdev(sizeof(struct hix5hd2_priv));
+@@ -1221,10 +1220,8 @@ static int hix5hd2_dev_probe(struct plat
+               goto out_phy_node;
+       }
+-      mac_addr = of_get_mac_address(node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(node, ndev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(ndev);
+               netdev_warn(ndev, "using random MAC address %pM\n",
+                           ndev->dev_addr);
+--- a/drivers/net/ethernet/lantiq_xrx200.c
++++ b/drivers/net/ethernet/lantiq_xrx200.c
+@@ -434,7 +434,6 @@ static int xrx200_probe(struct platform_
+       struct resource *res;
+       struct xrx200_priv *priv;
+       struct net_device *net_dev;
+-      const u8 *mac;
+       int err;
+       /* alloc the network device */
+@@ -478,10 +477,8 @@ static int xrx200_probe(struct platform_
+               return PTR_ERR(priv->clk);
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(net_dev->dev_addr, mac);
+-      else
++      err = of_get_mac_address(np, net_dev->dev_addr);
++      if (err)
+               eth_hw_addr_random(net_dev);
+       /* bring up the dma engine and IP core */
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2705,7 +2705,6 @@ static int mv643xx_eth_shared_of_add_por
+       struct platform_device *ppdev;
+       struct mv643xx_eth_platform_data ppd;
+       struct resource res;
+-      const char *mac_addr;
+       int ret;
+       int dev_num = 0;
+@@ -2736,9 +2735,7 @@ static int mv643xx_eth_shared_of_add_por
+               return -EINVAL;
+       }
+-      mac_addr = of_get_mac_address(pnp);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ppd.mac_addr, mac_addr);
++      of_get_mac_address(pnp, ppd.mac_addr);
+       mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
+       mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4526,7 +4526,6 @@ static int mvneta_probe(struct platform_
+       struct net_device *dev;
+       struct phylink *phylink;
+       struct phy *comphy;
+-      const char *dt_mac_addr;
+       char hw_mac_addr[ETH_ALEN];
+       const char *mac_from;
+       int tx_csum_limit;
+@@ -4623,10 +4622,9 @@ static int mvneta_probe(struct platform_
+               goto err_free_ports;
+       }
+-      dt_mac_addr = of_get_mac_address(dn);
+-      if (!IS_ERR(dt_mac_addr)) {
++      err = of_get_mac_address(dn, dev->dev_addr);
++      if (!err) {
+               mac_from = "device tree";
+-              ether_addr_copy(dev->dev_addr, dt_mac_addr);
+       } else {
+               mvneta_get_mac_addr(pp, hw_mac_addr);
+               if (is_valid_ether_addr(hw_mac_addr)) {
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1402,7 +1402,6 @@ static int pxa168_eth_probe(struct platf
+       struct resource *res;
+       struct clk *clk;
+       struct device_node *np;
+-      const unsigned char *mac_addr = NULL;
+       int err;
+       printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+@@ -1445,12 +1444,8 @@ static int pxa168_eth_probe(struct platf
+       INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
+-      if (pdev->dev.of_node)
+-              mac_addr = of_get_mac_address(pdev->dev.of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac_addr)) {
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-      } else {
++      err = of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
++      if (err) {
+               /* try reading the mac address, if set by the bootloader */
+               pxa168_eth_get_mac_address(dev, dev->dev_addr);
+               if (!is_valid_ether_addr(dev->dev_addr)) {
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -4721,7 +4721,7 @@ static struct net_device *sky2_init_netd
+ {
+       struct sky2_port *sky2;
+       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+-      const void *iap;
++      int ret;
+       if (!dev)
+               return NULL;
+@@ -4791,10 +4791,8 @@ static struct net_device *sky2_init_netd
+        * 1) from device tree data
+        * 2) from internal registers set by bootloader
+        */
+-      iap = of_get_mac_address(hw->pdev->dev.of_node);
+-      if (!IS_ERR(iap))
+-              ether_addr_copy(dev->dev_addr, iap);
+-      else
++      ret = of_get_mac_address(hw->pdev->dev.of_node, dev->dev_addr);
++      if (ret)
+               memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8,
+                             ETH_ALEN);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2469,14 +2469,11 @@ static int __init mtk_init(struct net_de
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      const char *mac_addr;
++      int ret;
+-      mac_addr = of_get_mac_address(mac->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(dev->dev_addr, mac_addr);
+-
+-      /* If the mac address is invalid, use random mac address  */
+-      if (!is_valid_ether_addr(dev->dev_addr)) {
++      ret = of_get_mac_address(mac->of_node, dev->dev_addr);
++      if (ret) {
++              /* If the mac address is invalid, use random mac address */
+               eth_hw_addr_random(dev);
+               dev_err(eth->dev, "generated random MAC address %pM\n",
+                       dev->dev_addr);
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1350,9 +1350,7 @@ static int lpc_eth_drv_probe(struct plat
+       __lpc_get_mac(pldat, ndev->dev_addr);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+-              const char *macaddr = of_get_mac_address(np);
+-              if (!IS_ERR(macaddr))
+-                      ether_addr_copy(ndev->dev_addr, macaddr);
++              of_get_mac_address(np, ndev->dev_addr);
+       }
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -885,7 +885,7 @@ qca_spi_probe(struct spi_device *spi)
+       struct net_device *qcaspi_devs = NULL;
+       u8 legacy_mode = 0;
+       u16 signature;
+-      const char *mac;
++      int ret;
+       if (!spi->dev.of_node) {
+               dev_err(&spi->dev, "Missing device tree\n");
+@@ -962,12 +962,8 @@ qca_spi_probe(struct spi_device *spi)
+       spi_set_drvdata(spi, qcaspi_devs);
+-      mac = of_get_mac_address(spi->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(spi->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&spi->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/qualcomm/qca_uart.c
++++ b/drivers/net/ethernet/qualcomm/qca_uart.c
+@@ -323,7 +323,6 @@ static int qca_uart_probe(struct serdev_
+ {
+       struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
+       struct qcauart *qca;
+-      const char *mac;
+       u32 speed = 115200;
+       int ret;
+@@ -348,12 +347,8 @@ static int qca_uart_probe(struct serdev_
+       of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
+-      mac = of_get_mac_address(serdev->dev.of_node);
+-
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(qca->net_dev->dev_addr, mac);
+-
+-      if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
++      ret = of_get_mac_address(serdev->dev.of_node, qca->net_dev->dev_addr);
++      if (ret) {
+               eth_hw_addr_random(qca->net_dev);
+               dev_info(&serdev->dev, "Using random MAC address: %pM\n",
+                        qca->net_dev->dev_addr);
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -109,11 +109,13 @@ static void ravb_set_buffer_align(struct
+  * Ethernet AVB device doesn't have ROM for MAC address.
+  * This function gets the MAC address that was used by a bootloader.
+  */
+-static void ravb_read_mac_address(struct net_device *ndev, const u8 *mac)
++static void ravb_read_mac_address(struct device_node *np,
++                                struct net_device *ndev)
+ {
+-      if (!IS_ERR(mac)) {
+-              ether_addr_copy(ndev->dev_addr, mac);
+-      } else {
++      int ret;
++
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
+               u32 mahr = ravb_read(ndev, MAHR);
+               u32 malr = ravb_read(ndev, MALR);
+@@ -2163,7 +2165,7 @@ static int ravb_probe(struct platform_de
+       priv->msg_enable = RAVB_DEF_MSG_ENABLE;
+       /* Read and set MAC address */
+-      ravb_read_mac_address(ndev, of_get_mac_address(np));
++      ravb_read_mac_address(np, ndev);
+       if (!is_valid_ether_addr(ndev->dev_addr)) {
+               dev_warn(&pdev->dev,
+                        "no valid MAC address supplied, using a random one\n");
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -3194,7 +3194,6 @@ static struct sh_eth_plat_data *sh_eth_p
+ {
+       struct device_node *np = dev->of_node;
+       struct sh_eth_plat_data *pdata;
+-      const char *mac_addr;
+       int ret;
+       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+@@ -3206,9 +3205,7 @@ static struct sh_eth_plat_data *sh_eth_p
+               return NULL;
+       pdata->phy_interface = ret;
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(pdata->mac_addr, mac_addr);
++      of_get_mac_address(np, pdata->mac_addr);
+       pdata->no_ether_link =
+               of_property_read_bool(np, "renesas,no-ether-link");
+--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
++++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c
+@@ -25,8 +25,7 @@
+ #ifdef CONFIG_OF
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct sxgbe_dma_cfg *dma_cfg;
+@@ -34,7 +33,6 @@ static int sxgbe_probe_config_dt(struct
+       if (!np)
+               return -ENODEV;
+-      *mac = of_get_mac_address(np);
+       plat->interface = of_get_phy_mode(np);
+       plat->bus_id = of_alias_get_id(np, "ethernet");
+@@ -60,8 +58,7 @@ static int sxgbe_probe_config_dt(struct
+ }
+ #else
+ static int sxgbe_probe_config_dt(struct platform_device *pdev,
+-                               struct sxgbe_plat_data *plat,
+-                               const char **mac)
++                               struct sxgbe_plat_data *plat)
+ {
+       return -ENOSYS;
+ }
+@@ -82,7 +79,6 @@ static int sxgbe_platform_probe(struct p
+       void __iomem *addr;
+       struct sxgbe_priv_data *priv = NULL;
+       struct sxgbe_plat_data *plat_dat = NULL;
+-      const char *mac = NULL;
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct device_node *node = dev->of_node;
+@@ -98,7 +94,7 @@ static int sxgbe_platform_probe(struct p
+               if (!plat_dat)
+                       return  -ENOMEM;
+-              ret = sxgbe_probe_config_dt(pdev, plat_dat, &mac);
++              ret = sxgbe_probe_config_dt(pdev, plat_dat);
+               if (ret) {
+                       pr_err("%s: main dt probe failed\n", __func__);
+                       return ret;
+@@ -119,8 +115,7 @@ static int sxgbe_platform_probe(struct p
+       }
+       /* Get MAC address if available (DT) */
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(priv->dev->dev_addr, mac);
++      of_get_mac_address(node, priv->dev->dev_addr);
+       /* Get the TX/RX IRQ numbers */
+       for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) {
+--- a/drivers/net/ethernet/socionext/sni_ave.c
++++ b/drivers/net/ethernet/socionext/sni_ave.c
+@@ -1559,7 +1559,6 @@ static int ave_probe(struct platform_dev
+       struct ave_private *priv;
+       struct net_device *ndev;
+       struct device_node *np;
+-      const void *mac_addr;
+       void __iomem *base;
+       const char *name;
+       int i, irq, ret;
+@@ -1600,12 +1599,9 @@ static int ave_probe(struct platform_dev
+       ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
+-      mac_addr = of_get_mac_address(np);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(ndev->dev_addr, mac_addr);
+-
+-      /* if the mac address is invalid, use random mac address */
+-      if (!is_valid_ether_addr(ndev->dev_addr)) {
++      ret = of_get_mac_address(np, ndev->dev_addr);
++      if (ret) {
++              /* if the mac address is invalid, use random mac address */
+               eth_hw_addr_random(ndev);
+               dev_warn(dev, "Using random MAC address: %pM\n",
+                        ndev->dev_addr);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+@@ -110,7 +110,7 @@ static int anarion_dwmac_probe(struct pl
+       if (IS_ERR(gmac))
+               return PTR_ERR(gmac);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+@@ -438,7 +438,7 @@ static int dwc_eth_dwmac_probe(struct pl
+       if (IS_ERR(stmmac_res.addr))
+               return PTR_ERR(stmmac_res.addr);
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+@@ -27,7 +27,7 @@ static int dwmac_generic_probe(struct pl
+               return ret;
+       if (pdev->dev.of_node) {
+-              plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++              plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+               if (IS_ERR(plat_dat)) {
+                       dev_err(&pdev->dev, "dt configuration failed\n");
+                       return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -254,7 +254,7 @@ static int ipq806x_gmac_probe(struct pla
+       if (val)
+               return val;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+@@ -37,7 +37,7 @@ static int lpc18xx_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -348,7 +348,7 @@ static int mediatek_dwmac_probe(struct p
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
+@@ -52,7 +52,7 @@ static int meson6_dwmac_probe(struct pla
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+@@ -324,7 +324,7 @@ static int meson8b_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+@@ -118,7 +118,7 @@ static int oxnas_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+@@ -461,7 +461,7 @@ static int qcom_ethqos_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat)) {
+               dev_err(&pdev->dev, "dt configuration failed\n");
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -1396,7 +1396,7 @@ static int rk_gmac_probe(struct platform
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -398,7 +398,7 @@ static int socfpga_dwmac_probe(struct pl
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+@@ -320,7 +320,7 @@ static int sti_dwmac_probe(struct platfo
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+@@ -364,7 +364,7 @@ static int stm32_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+@@ -1127,7 +1127,7 @@ static int sun8i_dwmac_probe(struct plat
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -108,7 +108,7 @@ static int sun7i_gmac_probe(struct platf
+       if (ret)
+               return ret;
+-      plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
++      plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+       if (IS_ERR(plat_dat))
+               return PTR_ERR(plat_dat);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -25,7 +25,7 @@
+ struct stmmac_resources {
+       void __iomem *addr;
+-      const char *mac;
++      u8 mac[ETH_ALEN];
+       int wol_irq;
+       int lpi_irq;
+       int irq;
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4479,7 +4479,7 @@ int stmmac_dvr_probe(struct device *devi
+       priv->wol_irq = res->wol_irq;
+       priv->lpi_irq = res->lpi_irq;
+-      if (!IS_ERR_OR_NULL(res->mac))
++      if (!is_zero_ether_addr(res->mac))
+               memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
+       dev_set_drvdata(device, priv->dev);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -393,7 +393,7 @@ static int stmmac_of_get_mac_mode(struct
+  * set some private fields that will be used by the main at runtime.
+  */
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       struct device_node *np = pdev->dev.of_node;
+       struct plat_stmmacenet_data *plat;
+@@ -404,12 +404,12 @@ stmmac_probe_config_dt(struct platform_d
+       if (!plat)
+               return ERR_PTR(-ENOMEM);
+-      *mac = of_get_mac_address(np);
+-      if (IS_ERR(*mac)) {
+-              if (PTR_ERR(*mac) == -EPROBE_DEFER)
+-                      return ERR_CAST(*mac);
++      rc = of_get_mac_address(np, mac);
++      if (rc) {
++              if (rc == -EPROBE_DEFER)
++                      return ERR_PTR(rc);
+-              *mac = NULL;
++              eth_zero_addr(mac);
+       }
+       plat->phy_interface = of_get_phy_mode(np);
+@@ -629,7 +629,7 @@ void stmmac_remove_config_dt(struct plat
+ }
+ #else
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ {
+       return ERR_PTR(-EINVAL);
+ }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
+@@ -12,7 +12,7 @@
+ #include "stmmac.h"
+ struct plat_stmmacenet_data *
+-stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
++stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac);
+ void stmmac_remove_config_dt(struct platform_device *pdev,
+                            struct plat_stmmacenet_data *plat);
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -2555,7 +2555,6 @@ static int cpsw_probe_dt(struct cpsw_pla
+       for_each_available_child_of_node(node, slave_node) {
+               struct cpsw_slave_data *slave_data = data->slave_data + i;
+-              const void *mac_addr = NULL;
+               int lenp;
+               const __be32 *parp;
+@@ -2628,10 +2627,8 @@ static int cpsw_probe_dt(struct cpsw_pla
+               }
+ no_phy_slave:
+-              mac_addr = of_get_mac_address(slave_node);
+-              if (!IS_ERR(mac_addr)) {
+-                      ether_addr_copy(slave_data->mac_addr, mac_addr);
+-              } else {
++              ret = of_get_mac_address(slave_node, slave_data->mac_addr);
++              if (ret) {
+                       ret = ti_cm_get_macid(&pdev->dev, i,
+                                             slave_data->mac_addr);
+                       if (ret)
+--- a/drivers/net/ethernet/ti/davinci_emac.c
++++ b/drivers/net/ethernet/ti/davinci_emac.c
+@@ -1686,7 +1686,6 @@ davinci_emac_of_get_pdata(struct platfor
+       const struct of_device_id *match;
+       const struct emac_platform_data *auxdata;
+       struct emac_platform_data *pdata = NULL;
+-      const u8 *mac_addr;
+       if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+               return dev_get_platdata(&pdev->dev);
+@@ -1698,11 +1697,8 @@ davinci_emac_of_get_pdata(struct platfor
+       np = pdev->dev.of_node;
+       pdata->version = EMAC_VERSION_2;
+-      if (!is_valid_ether_addr(pdata->mac_addr)) {
+-              mac_addr = of_get_mac_address(np);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(pdata->mac_addr, mac_addr);
+-      }
++      if (!is_valid_ether_addr(pdata->mac_addr))
++              of_get_mac_address(np, pdata->mac_addr);
+       of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
+                            &pdata->ctrl_reg_offset);
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1966,7 +1966,6 @@ static int netcp_create_interface(struct
+       struct resource res;
+       void __iomem *efuse = NULL;
+       u32 efuse_mac = 0;
+-      const void *mac_addr;
+       u8 efuse_mac_addr[6];
+       u32 temp[2];
+       int ret = 0;
+@@ -2036,10 +2035,8 @@ static int netcp_create_interface(struct
+               devm_iounmap(dev, efuse);
+               devm_release_mem_region(dev, res.start, size);
+       } else {
+-              mac_addr = of_get_mac_address(node_interface);
+-              if (!IS_ERR(mac_addr))
+-                      ether_addr_copy(ndev->dev_addr, mac_addr);
+-              else
++              ret = of_get_mac_address(node_interface, ndev->dev_addr);
++              if (ret)
+                       eth_random_addr(ndev->dev_addr);
+       }
+--- a/drivers/net/ethernet/wiznet/w5100-spi.c
++++ b/drivers/net/ethernet/wiznet/w5100-spi.c
+@@ -423,8 +423,14 @@ static int w5100_spi_probe(struct spi_de
+       const struct of_device_id *of_id;
+       const struct w5100_ops *ops;
+       kernel_ulong_t driver_data;
++      const void *mac = NULL;
++      u8 tmpmac[ETH_ALEN];
+       int priv_size;
+-      const void *mac = of_get_mac_address(spi->dev.of_node);
++      int ret;
++
++      ret = of_get_mac_address(spi->dev.of_node, tmpmac);
++      if (!ret)
++              mac = tmpmac;
+       if (spi->dev.of_node) {
+               of_id = of_match_device(w5100_of_match, &spi->dev);
+--- a/drivers/net/ethernet/wiznet/w5100.c
++++ b/drivers/net/ethernet/wiznet/w5100.c
+@@ -1157,7 +1157,7 @@ int w5100_probe(struct device *dev, cons
+       INIT_WORK(&priv->setrx_work, w5100_setrx_work);
+       INIT_WORK(&priv->restart_work, w5100_restart_work);
+-      if (!IS_ERR_OR_NULL(mac_addr))
++      if (mac_addr)
+               memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+       else
+               eth_hw_addr_random(ndev);
+--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
+@@ -434,7 +434,7 @@ static void temac_do_set_mac_address(str
+ static int temac_init_mac_address(struct net_device *ndev, const void *address)
+ {
+-      ether_addr_copy(ndev->dev_addr, address);
++      memcpy(ndev->dev_addr, address, ETH_ALEN);
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               eth_hw_addr_random(ndev);
+       temac_do_set_mac_address(ndev);
+@@ -1277,7 +1277,7 @@ static int temac_probe(struct platform_d
+       struct temac_local *lp;
+       struct net_device *ndev;
+       struct resource *res;
+-      const void *addr;
++      u8 addr[ETH_ALEN];
+       __be32 *p;
+       bool little_endian;
+       int rc = 0;
+@@ -1473,8 +1473,8 @@ static int temac_probe(struct platform_d
+       if (temac_np) {
+               /* Retrieve the MAC address */
+-              addr = of_get_mac_address(temac_np);
+-              if (IS_ERR(addr)) {
++              rc = of_get_mac_address(temac_np, addr);
++              if (rc) {
+                       dev_err(&pdev->dev, "could not find MAC address\n");
+                       return -ENODEV;
+               }
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -1663,7 +1663,7 @@ static int axienet_probe(struct platform
+       struct device_node *np;
+       struct axienet_local *lp;
+       struct net_device *ndev;
+-      const void *mac_addr;
++      u8 mac_addr[ETH_ALEN];
+       struct resource *ethres;
+       u32 value;
+@@ -1835,13 +1835,14 @@ static int axienet_probe(struct platform
+               dev_info(&pdev->dev, "Ethernet core IRQ not defined\n");
+       /* Retrieve the MAC address */
+-      mac_addr = of_get_mac_address(pdev->dev.of_node);
+-      if (IS_ERR(mac_addr)) {
+-              dev_warn(&pdev->dev, "could not find MAC address property: %ld\n",
+-                       PTR_ERR(mac_addr));
+-              mac_addr = NULL;
++      ret = of_get_mac_address(pdev->dev.of_node, mac_addr);
++      if (!ret) {
++              axienet_set_mac_address(ndev, mac_addr);
++      } else {
++              dev_warn(&pdev->dev, "could not find MAC address property: %d\n",
++                       ret);
++              axienet_set_mac_address(ndev, NULL);
+       }
+-      axienet_set_mac_address(ndev, mac_addr);
+       lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
+       lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1113,7 +1113,6 @@ static int xemaclite_of_probe(struct pla
+       struct net_device *ndev = NULL;
+       struct net_local *lp = NULL;
+       struct device *dev = &ofdev->dev;
+-      const void *mac_address;
+       int rc = 0;
+@@ -1155,12 +1154,9 @@ static int xemaclite_of_probe(struct pla
+       lp->next_rx_buf_to_use = 0x0;
+       lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong");
+       lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong");
+-      mac_address = of_get_mac_address(ofdev->dev.of_node);
+-      if (!IS_ERR(mac_address)) {
+-              /* Set the MAC address. */
+-              ether_addr_copy(ndev->dev_addr, mac_address);
+-      } else {
++      rc = of_get_mac_address(ofdev->dev.of_node, ndev->dev_addr);
++      if (rc) {
+               dev_warn(dev, "No MAC address found, using random\n");
+               eth_hw_addr_random(ndev);
+       }
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -618,7 +618,6 @@ static int ath9k_of_init(struct ath_soft
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
+-      const char *mac;
+       char eeprom_name[100];
+       int ret;
+@@ -641,9 +640,7 @@ static int ath9k_of_init(struct ath_soft
+               ah->ah_flags |= AH_NO_EEP_SWAP;
+       }
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(common->macaddr, mac);
++      of_get_mac_address(np, common->macaddr);
+       return 0;
+ }
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -75,17 +75,9 @@ out_put_node:
+ void
+ mt76_eeprom_override(struct mt76_dev *dev)
+ {
+-#ifdef CONFIG_OF
+       struct device_node *np = dev->dev->of_node;
+-      const u8 *mac;
+-      if (!np)
+-              return;
+-
+-      mac = of_get_mac_address(np);
+-      if (!IS_ERR(mac))
+-              ether_addr_copy(dev->macaddr, mac);
+-#endif
++      of_get_mac_address(np, dev->macaddr);
+       if (!is_valid_ether_addr(dev->macaddr)) {
+               eth_random_addr(dev->macaddr);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -990,11 +990,7 @@ static void rt2x00lib_rate(struct ieee80
+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+ {
+-      const char *mac_addr;
+-
+-      mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
+-      if (!IS_ERR(mac_addr))
+-              ether_addr_copy(eeprom_mac_addr, mac_addr);
++      of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
+       if (!is_valid_ether_addr(eeprom_mac_addr)) {
+               eth_random_addr(eeprom_mac_addr);
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -39,37 +39,29 @@ int of_get_phy_mode(struct device_node *
+ }
+ EXPORT_SYMBOL_GPL(of_get_phy_mode);
+-static const void *of_get_mac_addr(struct device_node *np, const char *name)
++static int of_get_mac_addr(struct device_node *np, const char *name, u8 *addr)
+ {
+       struct property *pp = of_find_property(np, name, NULL);
+-      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value))
+-              return pp->value;
+-      return NULL;
++      if (pp && pp->length == ETH_ALEN && is_valid_ether_addr(pp->value)) {
++              memcpy(addr, pp->value, ETH_ALEN);
++              return 0;
++      }
++      return -ENODEV;
+ }
+-static const void *of_get_mac_addr_nvmem(struct device_node *np)
++static int of_get_mac_addr_nvmem(struct device_node *np, u8 *addr)
+ {
+-      int ret;
+-      const void *mac;
+-      u8 nvmem_mac[ETH_ALEN];
+       struct platform_device *pdev = of_find_device_by_node(np);
++      int ret;
+       if (!pdev)
+-              return ERR_PTR(-ENODEV);
++              return -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);
++      ret = nvmem_get_mac_address(&pdev->dev, addr);
+       put_device(&pdev->dev);
+-      if (!mac)
+-              return ERR_PTR(-ENOMEM);
+-      return mac;
++      return ret;
+ }
+ /**
+@@ -92,24 +84,27 @@ static const void *of_get_mac_addr_nvmem
+  * 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.
++ * Return: 0 on success and errno in case of error.
+ */
+-const void *of_get_mac_address(struct device_node *np)
++int of_get_mac_address(struct device_node *np, u8 *addr)
+ {
+-      const void *addr;
+-
+-      addr = of_get_mac_addr(np, "mac-address");
+-      if (addr)
+-              return addr;
++      int ret;
+-      addr = of_get_mac_addr(np, "local-mac-address");
+-      if (addr)
+-              return addr;
++      if (!np)
++              return -ENODEV;
+-      addr = of_get_mac_addr(np, "address");
+-      if (addr)
+-              return addr;
++      ret = of_get_mac_addr(np, "mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "local-mac-address", addr);
++      if (!ret)
++              return 0;
++
++      ret = of_get_mac_addr(np, "address", addr);
++      if (!ret)
++              return 0;
+-      return of_get_mac_addr_nvmem(np);
++      return of_get_mac_addr_nvmem(np, addr);
+ }
+ EXPORT_SYMBOL(of_get_mac_address);
+--- a/drivers/staging/octeon/ethernet.c
++++ b/drivers/staging/octeon/ethernet.c
+@@ -407,14 +407,10 @@ static int cvm_oct_common_set_mac_addres
+ int cvm_oct_common_init(struct net_device *dev)
+ {
+       struct octeon_ethernet *priv = netdev_priv(dev);
+-      const u8 *mac = NULL;
++      int ret;
+-      if (priv->of_node)
+-              mac = of_get_mac_address(priv->of_node);
+-
+-      if (!IS_ERR_OR_NULL(mac))
+-              ether_addr_copy(dev->dev_addr, mac);
+-      else
++      ret = of_get_mac_address(priv->of_node, dev->dev_addr);
++      if (ret)
+               eth_hw_addr_random(dev);
+       /*
+--- a/include/linux/of_net.h
++++ b/include/linux/of_net.h
+@@ -11,7 +11,7 @@
+ struct net_device;
+ extern int of_get_phy_mode(struct device_node *np);
+-extern const void *of_get_mac_address(struct device_node *np);
++extern int of_get_mac_address(struct device_node *np, u8 *mac);
+ extern struct net_device *of_find_net_device_by_node(struct device_node *np);
+ #else
+ static inline int of_get_phy_mode(struct device_node *np)
+@@ -19,9 +19,9 @@ static inline int of_get_phy_mode(struct
+       return -ENODEV;
+ }
+-static inline const void *of_get_mac_address(struct device_node *np)
++static inline int of_get_mac_address(struct device_node *np, u8 *mac)
+ {
+-      return ERR_PTR(-ENODEV);
++      return -ENODEV;
+ }
+ static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -186,7 +186,7 @@ struct dsa_port {
+       unsigned int            index;
+       const char              *name;
+       struct dsa_port         *cpu_dp;
+-      const char              *mac;
++      u8                      mac[ETH_ALEN];
+       struct device_node      *dn;
+       unsigned int            ageing_time;
+       bool                    vlan_filtering;
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -318,7 +318,7 @@ static int dsa_port_setup(struct dsa_por
+                       break;
+               devlink_port_registered = true;
+-              dp->mac = of_get_mac_address(dp->dn);
++              of_get_mac_address(dp->dn, dp->mac);
+               err = dsa_slave_create(dp);
+               if (err)
+                       break;
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1411,7 +1411,7 @@ int dsa_slave_create(struct dsa_port *po
+       slave_dev->hw_features |= NETIF_F_HW_TC;
+       slave_dev->features |= NETIF_F_LLTX;
+       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
+-      if (!IS_ERR_OR_NULL(port->mac))
++      if (!is_zero_ether_addr(port->mac))
+               ether_addr_copy(slave_dev->dev_addr, port->mac);
+       else
+               eth_hw_addr_inherit(slave_dev, master);
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -550,13 +550,14 @@ unsigned char * __weak arch_get_platform
+ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
+ {
+-      const unsigned char *addr = NULL;
++      unsigned char *addr;
++      int ret;
+-      if (dev->of_node)
+-              addr = of_get_mac_address(dev->of_node);
+-      if (IS_ERR_OR_NULL(addr))
+-              addr = arch_get_platform_mac_address();
++      ret = of_get_mac_address(dev->of_node, mac_addr);
++      if (!ret)
++              return 0;
++      addr = arch_get_platform_mac_address();
+       if (!addr)
+               return -ENODEV;
diff --git a/target/linux/generic/backport-5.4/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch b/target/linux/generic/backport-5.4/782-net-next-2-of-net-fix-of_get_mac_addr_nvmem-for-non-platform-devices.patch
new file mode 100644 (file)
index 0000000..c365ac0
--- /dev/null
@@ -0,0 +1,77 @@
+From f10843e04a075202dbb39dfcee047e3a2fdf5a8d Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Mon, 12 Apr 2021 19:47:18 +0200
+Subject: of: net: fix of_get_mac_addr_nvmem() for non-platform devices
+
+of_get_mac_address() already supports fetching the MAC address by an
+nvmem provider. But until now, it was just working for platform devices.
+Esp. it was not working for DSA ports and PCI devices. It gets more
+common that PCI devices have a device tree binding since SoCs contain
+integrated root complexes.
+
+Use the nvmem of_* binding to fetch the nvmem cells by a struct
+device_node. We still have to try to read the cell by device first
+because there might be a nvmem_cell_lookup associated with that device.
+
+Signed-off-by: Michael Walle <michael@walle.cc>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/of/of_net.c | 35 ++++++++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+--- a/drivers/of/of_net.c
++++ b/drivers/of/of_net.c
+@@ -11,6 +11,7 @@
+ #include <linux/phy.h>
+ #include <linux/export.h>
+ #include <linux/device.h>
++#include <linux/nvmem-consumer.h>
+ /**
+  * of_get_phy_mode - Get phy mode for given device_node
+@@ -53,15 +54,39 @@ static int of_get_mac_addr(struct device
+ 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;
++      size_t len;
+       int ret;
+-      if (!pdev)
+-              return -ENODEV;
++      /* Try lookup by device first, there might be a nvmem_cell_lookup
++       * associated with a given device.
++       */
++      if (pdev) {
++              ret = nvmem_get_mac_address(&pdev->dev, addr);
++              put_device(&pdev->dev);
++              return ret;
++      }
++
++      cell = of_nvmem_cell_get(np, "mac-address");
++      if (IS_ERR(cell))
++              return PTR_ERR(cell);
++
++      mac = 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;
++      }
+-      ret = nvmem_get_mac_address(&pdev->dev, addr);
+-      put_device(&pdev->dev);
++      memcpy(addr, mac, ETH_ALEN);
++      kfree(mac);
+-      return ret;
++      return 0;
+ }
+ /**
diff --git a/target/linux/generic/hack-5.10/780-drivers-net-mediatek-register-of_platform-for-every-.patch b/target/linux/generic/hack-5.10/780-drivers-net-mediatek-register-of_platform-for-every-.patch
deleted file mode 100644 (file)
index fa80b0e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From c94b2cfd25c282e2974accc1b07da98ae7139b47 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 23 Jul 2021 12:14:33 +0200
-Subject: [PATCH 1/2] drivers: net: mediatek: register of_platform for every
- port
-
-Currently the nvmem framework require the devicenode to be registred on
-the of_platform or of_get_mac_address fail to get the macaddress if
-defined using an nvmem cell. Fix this by registrering these special node
-so they can be found by of_find_device_by_node.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3005,6 +3005,8 @@ static int mtk_add_mac(struct mtk_eth *e
-       eth->netdev[id]->dev.of_node = np;
-       eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
-+      
-+      of_platform_device_create(np, NULL, NULL);
-       return 0;
diff --git a/target/linux/generic/hack-5.10/781-dsa-register-every-port-with-of_platform.patch b/target/linux/generic/hack-5.10/781-dsa-register-every-port-with-of_platform.patch
deleted file mode 100644 (file)
index 330d9f1..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 8bab551f44204fc5d43977063cd704112c17c750 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 23 Jul 2021 12:17:27 +0200
-Subject: [PATCH 2/2] dsa: register every port with of_platform
-
-The declaration of a different mac-addr using the nvmem framework is
-currently broken. The dsa code use the generic of_get_mac_address where
-the nvmem function require the device node to be registred in the
-of_platform to be found by of_find_device_by_node. Register every port
-in the of_platform so they can corrently found and a custom mac-addr can
-correctly be declared using a nvmem-cell declared in the dts.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- net/dsa/dsa2.c | 2 +
- 1 file changed, 2 insertion(+)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -14,6 +14,7 @@
- #include <linux/rtnetlink.h>
- #include <linux/of.h>
- #include <linux/of_net.h>
-+#include <linux/of_platform.h>
- #include <net/devlink.h>
- #include "dsa_priv.h"
-@@ -288,6 +289,7 @@ static int dsa_port_setup(struct dsa_por
-               break;
-       case DSA_PORT_TYPE_USER:
-+              of_platform_device_create(dp->dn, NULL, NULL);
-               dp->mac = of_get_mac_address(dp->dn);
-               err = dsa_slave_create(dp);
-               if (err)
diff --git a/target/linux/generic/hack-5.4/780-drivers-net-mediatek-register-of_platform-for-every-.patch b/target/linux/generic/hack-5.4/780-drivers-net-mediatek-register-of_platform-for-every-.patch
deleted file mode 100644 (file)
index 09b413e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From c94b2cfd25c282e2974accc1b07da98ae7139b47 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 23 Jul 2021 12:14:33 +0200
-Subject: [PATCH 1/2] drivers: net: mediatek: register of_platform for every
- port
-
-Currently the nvmem framework require the devicenode to be registred on
-the of_platform or of_get_mac_address fail to get the macaddress if
-defined using an nvmem cell. Fix this by registrering these special node
-so they can be found by of_find_device_by_node.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3034,6 +3034,8 @@ static int mtk_add_mac(struct mtk_eth *e
-       eth->netdev[id]->dev.of_node = np;
-       eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
-+      
-+      of_platform_device_create(np, NULL, NULL);
-       return 0;
diff --git a/target/linux/generic/hack-5.4/781-dsa-register-every-port-with-of_platform.patch b/target/linux/generic/hack-5.4/781-dsa-register-every-port-with-of_platform.patch
deleted file mode 100644 (file)
index bd7e190..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 8bab551f44204fc5d43977063cd704112c17c750 Mon Sep 17 00:00:00 2001
-From: Ansuel Smith <ansuelsmth@gmail.com>
-Date: Fri, 23 Jul 2021 12:17:27 +0200
-Subject: [PATCH 2/2] dsa: register every port with of_platform
-
-The declaration of a different mac-addr using the nvmem framework is
-currently broken. The dsa code use the generic of_get_mac_address where
-the nvmem function require the device node to be registred in the
-of_platform to be found by of_find_device_by_node. Register every port
-in the of_platform so they can corrently found and a custom mac-addr can
-correctly be declared using a nvmem-cell declared in the dts.
-
-Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
----
- net/dsa/dsa2.c | 2 +
- 1 file changed, 2 insertion(+)
-
---- a/net/dsa/dsa2.c
-+++ b/net/dsa/dsa2.c
-@@ -14,6 +14,7 @@
- #include <linux/rtnetlink.h>
- #include <linux/of.h>
- #include <linux/of_net.h>
-+#include <linux/of_platform.h>
- #include <net/devlink.h>
- #include "dsa_priv.h"
-@@ -318,6 +319,7 @@ static int dsa_port_setup(struct dsa_por
-                       break;
-               devlink_port_registered = true;
-+              of_platform_device_create(dp->dn, NULL, NULL);
-               dp->mac = of_get_mac_address(dp->dn);
-               err = dsa_slave_create(dp);
-               if (err)
index 71d794e83bd790cdc827d86afafde3085733f605..463fc270c6bd153ecb581ea10a07dcc0bcf6a4a1 100644 (file)
@@ -17,28 +17,19 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -11,6 +11,7 @@
- #include <linux/phy.h>
+@@ -12,6 +12,7 @@
  #include <linux/export.h>
  #include <linux/device.h>
+ #include <linux/nvmem-consumer.h>
 +#include <linux/mtd/mtd.h>
  
  /**
   * of_get_phy_mode - Get phy mode for given device_node
-@@ -45,7 +46,7 @@ int of_get_phy_mode(struct device_node *
+@@ -95,6 +96,52 @@ static int of_get_mac_addr_nvmem(struct
+       return 0;
  }
- EXPORT_SYMBOL_GPL(of_get_phy_mode);
  
--static const void *of_get_mac_addr(struct device_node *np, const char *name)
-+static void *of_get_mac_addr(struct device_node *np, const char *name)
- {
-       struct property *pp = of_find_property(np, name, NULL);
-@@ -78,6 +79,55 @@ static const void *of_get_mac_addr_nvmem
-       return mac;
- }
-+static const void *of_get_mac_address_mtd(struct device_node *np)
++static int of_get_mac_address_mtd(struct device_node *np, u8 *addr)
 +{
 +#ifdef CONFIG_MTD
 +      struct platform_device *pdev = of_find_device_by_node(np);
@@ -50,18 +41,17 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 +      const __be32 *list;
 +      phandle phandle;
 +      u8 mac[ETH_ALEN];
-+      void *addr;
 +
 +      list = of_get_property(np, "mtd-mac-address", &size);
 +      if (!list || (size != (2 * sizeof(*list))))
-+              return NULL;
++              return -ENODEV;
 +
 +      phandle = be32_to_cpup(list++);
 +      if (phandle)
 +              mtd_np = of_find_node_by_phandle(phandle);
 +
 +      if (!mtd_np)
-+              return NULL;
++              return -ENODEV;
 +
 +      part = of_get_property(mtd_np, "label", NULL);
 +      if (!part)
@@ -69,28 +59,26 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 +
 +      mtd = get_mtd_device_nm(part);
 +      if (IS_ERR(mtd))
-+              return NULL;
++              return -ENODEV;
 +
 +      ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
 +      put_mtd_device(mtd);
 +
 +      if (!is_valid_ether_addr(mac))
-+              return NULL;
++              return -EINVAL;
 +
-+      addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL);
-+      if (!addr)
-+              return ERR_PTR(-ENOMEM);
++      memcpy(addr, mac, ETH_ALEN);
 +
-+      return addr;
++      return 0;
 +#endif
-+      return NULL;
++      return -EINVAL;
 +}
 +
 +
  /**
   * 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
-@@ -98,6 +148,10 @@ static const void *of_get_mac_addr_nvmem
+@@ -115,6 +161,10 @@ static int of_get_mac_addr_nvmem(struct
   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
   * but is all zeros.
   *
@@ -98,17 +86,17 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 + * If a mtd-mac-address property exists, try to fetch the MAC address from the
 + * specified mtd device.
 + *
-  * Return: Will be a valid pointer on success and ERR_PTR in case of error.
+  * Return: 0 on success and errno in case of error.
  */
const void *of_get_mac_address(struct device_node *np)
-@@ -116,6 +170,10 @@ const void *of_get_mac_address(struct de
-       if (addr)
-               return addr;
int of_get_mac_address(struct device_node *np, u8 *addr)
+@@ -136,6 +186,10 @@ int of_get_mac_address(struct device_nod
+       if (!ret)
+               return 0;
  
-+      addr = of_get_mac_address_mtd(np);
-+      if (addr)
-+              return addr;
++      ret = of_get_mac_address_mtd(np, addr);
++      if (!ret)
++              return 0;
 +
-       return of_get_mac_addr_nvmem(np);
+       return of_get_mac_addr_nvmem(np, addr);
  }
  EXPORT_SYMBOL(of_get_mac_address);
index 9032b9186c51a493fb8b7578233c49318f3319bb..ce5211a21b83957bef67fbcd002ea35df3f77146 100644 (file)
@@ -20,52 +20,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -55,31 +55,36 @@ static void *of_get_mac_addr(struct devi
-       return NULL;
- }
--static const void *of_get_mac_addr_nvmem(struct device_node *np)
-+static void *of_get_mac_addr_nvmem(struct device_node *np, int *err)
- {
-       int ret;
--      const void *mac;
-+      void *mac;
-       u8 nvmem_mac[ETH_ALEN];
-       struct platform_device *pdev = of_find_device_by_node(np);
--      if (!pdev)
--              return ERR_PTR(-ENODEV);
-+      if (!pdev) {
-+              *err = -ENODEV;
-+              return NULL;
-+      }
-       ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac);
-       if (ret) {
-               put_device(&pdev->dev);
--              return ERR_PTR(ret);
-+              *err = ret;
-+              return NULL;
-       }
-       mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL);
-       put_device(&pdev->dev);
--      if (!mac)
--              return ERR_PTR(-ENOMEM);
-+      if (!mac) {
-+              *err = -ENOMEM;
-+              return NULL;
-+      }
-       return mac;
- }
--static const void *of_get_mac_address_mtd(struct device_node *np)
-+static void *of_get_mac_address_mtd(struct device_node *np)
- {
- #ifdef CONFIG_MTD
-       struct platform_device *pdev = of_find_device_by_node(np);
-@@ -152,28 +157,54 @@ static const void *of_get_mac_address_mt
+@@ -165,31 +165,56 @@ static int of_get_mac_address_mtd(struct
   * If a mtd-mac-address property exists, try to fetch the MAC address from the
   * specified mtd device.
   *
@@ -77,52 +32,53 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 + *   not overflow to other bytes if the increment is over 255.
 + *   (example 00:01:02:03:04:ff + 1 == 00:01:02:03:04:00)
 + *
-  * Return: Will be a valid pointer on success and ERR_PTR in case of error.
+  * Return: 0 on success and errno in case of error.
  */
const void *of_get_mac_address(struct device_node *np)
int of_get_mac_address(struct device_node *np, u8 *addr)
  {
--      const void *addr;
 +      u32 inc_idx, mac_inc;
-+      int ret = 0;
-+      u8 *addr;
-+
+       int ret;
 +      /* Check first if the increment byte is present and valid.
 +       * If not set assume to increment the last byte if found.
 +       */
 +      if (of_property_read_u32(np, "mac-address-increment-byte", &inc_idx))
 +              inc_idx = 5;
 +      if (inc_idx < 3 || inc_idx > 5)
-+              return ERR_PTR(-EINVAL);
++              return -EINVAL;
++
+       if (!np)
+               return -ENODEV;
  
-       addr = of_get_mac_addr(np, "mac-address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "mac-address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_addr(np, "local-mac-address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "local-mac-address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_addr(np, "address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_address_mtd(np);
-       if (addr)
--              return addr;
+       ret = of_get_mac_address_mtd(np, addr);
+       if (!ret)
+-              return 0;
 +              goto found;
 +
-+      addr = of_get_mac_addr_nvmem(np, &ret);
++      ret = of_get_mac_addr_nvmem(np, addr);
 +      if (ret)
-+              return ERR_PTR(ret);
++              return ret;
 +
 +found:
 +      if (!of_property_read_u32(np, "mac-address-increment", &mac_inc))
 +              addr[inc_idx] += mac_inc;
  
--      return of_get_mac_addr_nvmem(np);
-+      return addr;
+-      return of_get_mac_addr_nvmem(np, addr);
++      return ret;
  }
  EXPORT_SYMBOL(of_get_mac_address);
index eac793388412747832c54c11385019bcf478fdc6..377f16e7c922167a5034a87715e65b53bc0f0840 100644 (file)
@@ -1,19 +1,16 @@
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -132,6 +132,33 @@ static void *of_get_mac_address_mtd(stru
-       return NULL;
+@@ -132,6 +132,30 @@ static void *of_get_mac_address_mtd(stru
+       return -EINVAL;
  }
  
 +static int of_add_mac_address(struct device_node *np, u8* addr)
 +{
 +      struct property *prop;
-+      u8 *np_addr;
 +
-+      np_addr = of_get_mac_addr(np, "mac-address");
-+      if (np_addr) {
-+              memcpy(np_addr, addr, ETH_ALEN);
-+              return 0;
-+      }
++      prop = of_find_property(np, "mac-address", NULL);
++      if (prop)
++              kfree(prop);
 +
 +      prop = kzalloc(sizeof(*prop), GFP_KERNEL);
 +      if (!prop)
@@ -39,6 +36,6 @@
                addr[inc_idx] += mac_inc;
  
 +      of_add_mac_address(np, addr);
-       return addr;
+       return ret;
  }
  EXPORT_SYMBOL(of_get_mac_address);
index 3dc33c2fcaecdf0199ccaa371e15404bea16eefe..463fc270c6bd153ecb581ea10a07dcc0bcf6a4a1 100644 (file)
@@ -17,28 +17,19 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -11,6 +11,7 @@
- #include <linux/phy.h>
+@@ -12,6 +12,7 @@
  #include <linux/export.h>
  #include <linux/device.h>
+ #include <linux/nvmem-consumer.h>
 +#include <linux/mtd/mtd.h>
  
  /**
   * of_get_phy_mode - Get phy mode for given device_node
-@@ -39,7 +40,7 @@ int of_get_phy_mode(struct device_node *
+@@ -95,6 +96,52 @@ static int of_get_mac_addr_nvmem(struct
+       return 0;
  }
- EXPORT_SYMBOL_GPL(of_get_phy_mode);
  
--static const void *of_get_mac_addr(struct device_node *np, const char *name)
-+static void *of_get_mac_addr(struct device_node *np, const char *name)
- {
-       struct property *pp = of_find_property(np, name, NULL);
-@@ -72,6 +73,55 @@ static const void *of_get_mac_addr_nvmem
-       return mac;
- }
-+static const void *of_get_mac_address_mtd(struct device_node *np)
++static int of_get_mac_address_mtd(struct device_node *np, u8 *addr)
 +{
 +#ifdef CONFIG_MTD
 +      struct platform_device *pdev = of_find_device_by_node(np);
@@ -50,18 +41,17 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 +      const __be32 *list;
 +      phandle phandle;
 +      u8 mac[ETH_ALEN];
-+      void *addr;
 +
 +      list = of_get_property(np, "mtd-mac-address", &size);
 +      if (!list || (size != (2 * sizeof(*list))))
-+              return NULL;
++              return -ENODEV;
 +
 +      phandle = be32_to_cpup(list++);
 +      if (phandle)
 +              mtd_np = of_find_node_by_phandle(phandle);
 +
 +      if (!mtd_np)
-+              return NULL;
++              return -ENODEV;
 +
 +      part = of_get_property(mtd_np, "label", NULL);
 +      if (!part)
@@ -69,28 +59,26 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 +
 +      mtd = get_mtd_device_nm(part);
 +      if (IS_ERR(mtd))
-+              return NULL;
++              return -ENODEV;
 +
 +      ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
 +      put_mtd_device(mtd);
 +
 +      if (!is_valid_ether_addr(mac))
-+              return NULL;
++              return -EINVAL;
 +
-+      addr = devm_kmemdup(&pdev->dev, mac, ETH_ALEN, GFP_KERNEL);
-+      if (!addr)
-+              return ERR_PTR(-ENOMEM);
++      memcpy(addr, mac, ETH_ALEN);
 +
-+      return addr;
++      return 0;
 +#endif
-+      return NULL;
++      return -EINVAL;
 +}
 +
 +
  /**
   * 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
-@@ -92,6 +142,10 @@ static const void *of_get_mac_addr_nvmem
+@@ -115,6 +161,10 @@ static int of_get_mac_addr_nvmem(struct
   * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
   * but is all zeros.
   *
@@ -98,17 +86,17 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 + * If a mtd-mac-address property exists, try to fetch the MAC address from the
 + * specified mtd device.
 + *
-  * Return: Will be a valid pointer on success and ERR_PTR in case of error.
+  * Return: 0 on success and errno in case of error.
  */
const void *of_get_mac_address(struct device_node *np)
-@@ -110,6 +164,10 @@ const void *of_get_mac_address(struct de
-       if (addr)
-               return addr;
int of_get_mac_address(struct device_node *np, u8 *addr)
+@@ -136,6 +186,10 @@ int of_get_mac_address(struct device_nod
+       if (!ret)
+               return 0;
  
-+      addr = of_get_mac_address_mtd(np);
-+      if (addr)
-+              return addr;
++      ret = of_get_mac_address_mtd(np, addr);
++      if (!ret)
++              return 0;
 +
-       return of_get_mac_addr_nvmem(np);
+       return of_get_mac_addr_nvmem(np, addr);
  }
  EXPORT_SYMBOL(of_get_mac_address);
index 120ef52ff83744e95b4d0da020f4d02071e99c2d..ce5211a21b83957bef67fbcd002ea35df3f77146 100644 (file)
@@ -20,52 +20,7 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -49,31 +49,36 @@ static void *of_get_mac_addr(struct devi
-       return NULL;
- }
--static const void *of_get_mac_addr_nvmem(struct device_node *np)
-+static void *of_get_mac_addr_nvmem(struct device_node *np, int *err)
- {
-       int ret;
--      const void *mac;
-+      void *mac;
-       u8 nvmem_mac[ETH_ALEN];
-       struct platform_device *pdev = of_find_device_by_node(np);
--      if (!pdev)
--              return ERR_PTR(-ENODEV);
-+      if (!pdev) {
-+              *err = -ENODEV;
-+              return NULL;
-+      }
-       ret = nvmem_get_mac_address(&pdev->dev, &nvmem_mac);
-       if (ret) {
-               put_device(&pdev->dev);
--              return ERR_PTR(ret);
-+              *err = ret;
-+              return NULL;
-       }
-       mac = devm_kmemdup(&pdev->dev, nvmem_mac, ETH_ALEN, GFP_KERNEL);
-       put_device(&pdev->dev);
--      if (!mac)
--              return ERR_PTR(-ENOMEM);
-+      if (!mac) {
-+              *err = -ENOMEM;
-+              return NULL;
-+      }
-       return mac;
- }
--static const void *of_get_mac_address_mtd(struct device_node *np)
-+static void *of_get_mac_address_mtd(struct device_node *np)
- {
- #ifdef CONFIG_MTD
-       struct platform_device *pdev = of_find_device_by_node(np);
-@@ -146,28 +151,54 @@ static const void *of_get_mac_address_mt
+@@ -165,31 +165,56 @@ static int of_get_mac_address_mtd(struct
   * If a mtd-mac-address property exists, try to fetch the MAC address from the
   * specified mtd device.
   *
@@ -77,52 +32,53 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 + *   not overflow to other bytes if the increment is over 255.
 + *   (example 00:01:02:03:04:ff + 1 == 00:01:02:03:04:00)
 + *
-  * Return: Will be a valid pointer on success and ERR_PTR in case of error.
+  * Return: 0 on success and errno in case of error.
  */
const void *of_get_mac_address(struct device_node *np)
int of_get_mac_address(struct device_node *np, u8 *addr)
  {
--      const void *addr;
 +      u32 inc_idx, mac_inc;
-+      int ret = 0;
-+      u8 *addr;
-+
+       int ret;
 +      /* Check first if the increment byte is present and valid.
 +       * If not set assume to increment the last byte if found.
 +       */
 +      if (of_property_read_u32(np, "mac-address-increment-byte", &inc_idx))
 +              inc_idx = 5;
 +      if (inc_idx < 3 || inc_idx > 5)
-+              return ERR_PTR(-EINVAL);
++              return -EINVAL;
++
+       if (!np)
+               return -ENODEV;
  
-       addr = of_get_mac_addr(np, "mac-address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "mac-address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_addr(np, "local-mac-address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "local-mac-address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_addr(np, "address");
-       if (addr)
--              return addr;
+       ret = of_get_mac_addr(np, "address", addr);
+       if (!ret)
+-              return 0;
 +              goto found;
  
-       addr = of_get_mac_address_mtd(np);
-       if (addr)
--              return addr;
+       ret = of_get_mac_address_mtd(np, addr);
+       if (!ret)
+-              return 0;
 +              goto found;
 +
-+      addr = of_get_mac_addr_nvmem(np, &ret);
++      ret = of_get_mac_addr_nvmem(np, addr);
 +      if (ret)
-+              return ERR_PTR(ret);
++              return ret;
 +
 +found:
 +      if (!of_property_read_u32(np, "mac-address-increment", &mac_inc))
 +              addr[inc_idx] += mac_inc;
  
--      return of_get_mac_addr_nvmem(np);
-+      return addr;
+-      return of_get_mac_addr_nvmem(np, addr);
++      return ret;
  }
  EXPORT_SYMBOL(of_get_mac_address);
index cabfba8b969b8c194f15ec7ab0ce5c7cb70fae37..377f16e7c922167a5034a87715e65b53bc0f0840 100644 (file)
@@ -1,19 +1,16 @@
 --- a/drivers/of/of_net.c
 +++ b/drivers/of/of_net.c
-@@ -126,6 +126,33 @@ static void *of_get_mac_address_mtd(stru
-       return NULL;
+@@ -132,6 +132,30 @@ static void *of_get_mac_address_mtd(stru
+       return -EINVAL;
  }
  
 +static int of_add_mac_address(struct device_node *np, u8* addr)
 +{
 +      struct property *prop;
-+      u8 *np_addr;
 +
-+      np_addr = of_get_mac_addr(np, "mac-address");
-+      if (np_addr) {
-+              memcpy(np_addr, addr, ETH_ALEN);
-+              return 0;
-+      }
++      prop = of_find_property(np, "mac-address", NULL);
++      if (prop)
++              kfree(prop);
 +
 +      prop = kzalloc(sizeof(*prop), GFP_KERNEL);
 +      if (!prop)
  
  /**
   * Search the device tree for the best MAC address to use.  'mac-address' is
-@@ -199,6 +226,7 @@ found:
+@@ -205,6 +232,7 @@ found:
        if (!of_property_read_u32(np, "mac-address-increment", &mac_inc))
                addr[inc_idx] += mac_inc;
  
 +      of_add_mac_address(np, addr);
-       return addr;
+       return ret;
  }
  EXPORT_SYMBOL(of_get_mac_address);
index af55ee4dd551113b695238aa6832777fbe6be939..b5ca99598d1f480f86c4413d9b2001fe5a43c1f6 100644 (file)
@@ -905,8 +905,6 @@ static int edma_axi_probe(struct platform_device *pdev)
        }
 
        for_each_available_child_of_node(np, pnp) {
-               const char *mac_addr;
-
                /* this check is needed if parent and daughter dts have
                 * different number of gmac nodes
                 */
@@ -915,9 +913,7 @@ static int edma_axi_probe(struct platform_device *pdev)
                        break;
                }
 
-               mac_addr = of_get_mac_address(pnp);
-               if (!IS_ERR(mac_addr))
-                       memcpy(edma_netdev[idx_mac]->dev_addr, mac_addr, ETH_ALEN);
+               of_get_mac_address(pnp, edma_netdev[idx_mac]->dev_addr);
 
                idx_mac++;
        }
index 441aaed05b22f37d06382cf7e5cc67f476654c84..0a42fd59e4663f0539afc6bd16aedea621fe6a36 100644 (file)
@@ -721,7 +721,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
        netif_trans_update(dev);
        netif_wake_queue(dev);
        return;
-@@ -618,14 +822,19 @@ static const struct net_device_ops ltq_e
+@@ -618,14 +822,18 @@ static const struct net_device_ops ltq_e
        .ndo_tx_timeout = ltq_etop_tx_timeout,
  };
  
@@ -733,7 +733,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
        struct ltq_etop_priv *priv;
 -      struct resource *res;
 +      struct resource *res, *gbit_res, irqres[2];
-+      const u8 *mac;
        int err;
 -      int i;
 +
@@ -745,7 +744,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
  
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-@@ -651,31 +860,64 @@ ltq_etop_probe(struct platform_device *p
+@@ -651,31 +860,62 @@ ltq_etop_probe(struct platform_device *p
                goto err_out;
        }
  
@@ -785,9 +784,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      if (err)
 +              pr_err("Can't find phy-mode for port\n");
 +
-+      mac = of_get_mac_address(pdev->dev.of_node);
-+      if (mac)
-+              memcpy(priv->mac, mac, ETH_ALEN);
++      of_get_mac_address(pdev->dev.of_node, priv->mac);
 +
 +      priv->clk_ppe = clk_get(&pdev->dev, NULL);
 +      if (IS_ERR(priv->clk_ppe))
index 094496a16de4c94efd25e81289db17ab509b62f4..12a71fdad1137135cf48d0253c9cb25e921d1c15 100644 (file)
@@ -721,7 +721,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
        netif_trans_update(dev);
        netif_wake_queue(dev);
        return;
-@@ -625,14 +829,19 @@ static const struct net_device_ops ltq_e
+@@ -625,14 +829,18 @@ static const struct net_device_ops ltq_e
        .ndo_tx_timeout = ltq_etop_tx_timeout,
  };
  
@@ -733,7 +733,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
        struct ltq_etop_priv *priv;
 -      struct resource *res;
 +      struct resource *res, *gbit_res, irqres[2];
-+      const u8 *mac;
        int err;
 -      int i;
 +
@@ -745,7 +744,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
  
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-@@ -658,31 +867,62 @@ ltq_etop_probe(struct platform_device *p
+@@ -658,31 +867,60 @@ ltq_etop_probe(struct platform_device *p
                goto err_out;
        }
  
@@ -783,9 +782,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      priv->rx_irq = irqres[1].start;
 +      priv->mii_mode = of_get_phy_mode(pdev->dev.of_node);
 +
-+      mac = of_get_mac_address(pdev->dev.of_node);
-+      if (mac)
-+              memcpy(priv->mac, mac, ETH_ALEN);
++      of_get_mac_address(pdev->dev.of_node, priv->mac);
 +
 +      priv->clk_ppe = clk_get(&pdev->dev, NULL);
 +      if (IS_ERR(priv->clk_ppe))
index 29b52d2238b52f4f0c823bda5f3c35a23a5a0163..215569e406a27117a425c039b549fdb1b3af02fd 100644 (file)
@@ -10514,7 +10514,7 @@ Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
 +module_exit(dpa_ptp_unload);
 --- /dev/null
 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
-@@ -0,0 +1,909 @@
+@@ -0,0 +1,907 @@
 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
@@ -11582,7 +11582,6 @@ Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
 +      struct mac_device       *mac_dev;
 +      struct platform_device  *of_dev;
 +      struct resource          res;
-+      const uint8_t           *mac_addr;
 +      const char              *char_prop;
 +      int                     nph;
 +      u32                     cell_index;
@@ -11701,14 +11700,13 @@ Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
 +              mac_dev->cell_index -= 8;
 +
 +      /* Get the MAC address */
-+      mac_addr = of_get_mac_address(mac_node);
-+      if (unlikely(mac_addr == NULL)) {
++      of_get_mac_address(mac_node, mac_dev->addr);
++      if (unlikely(!is_valid_ether_addr(mac_dev->addr))) {
 +              dev_err(dev, "of_get_mac_address(%s) failed\n",
 +                              mac_node->full_name);
 +              _errno = -EINVAL;
 +              goto _return_dev_set_drvdata;
 +      }
-+      memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
 +
 +      /* Verify the number of port handles */
 +      nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
index 230238f9a03648e1c815089a9671d4087901d351..13fd4f90d1faebdaf90fc8ec576832a8eddee2f4 100644 (file)
@@ -6638,7 +6638,7 @@ Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
 +}
 --- /dev/null
 +++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
-@@ -0,0 +1,394 @@
+@@ -0,0 +1,388 @@
 +/*
 + * Copyright 2015-2016 Freescale Semiconductor, Inc.
 + * Copyright 2017 NXP
@@ -6680,7 +6680,6 @@ Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
 +      int size;
 +      int ii = 0, phy_id = 0;
 +      const u32 *addr;
-+      const void *mac_addr;
 +
 +      for (ii = 0; ii < if_cnt; ii++) {
 +              gem = of_get_next_child(parent, gem);
@@ -6699,12 +6698,7 @@ Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
 +
 +      pdata->ls1012a_eth_pdata[port].gem_id = port;
 +
-+      mac_addr = of_get_mac_address(gem);
-+
-+      if (mac_addr) {
-+              memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
-+                     ETH_ALEN);
-+      }
++      of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr);
 +
 +      pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem);
 +
index 7e4c6ae6aa1b40e92217acbb919b8245fa7c9ea6..7d59676781ce3268e9d93ad31e23effc5ce2aae2 100644 (file)
@@ -33,15 +33,9 @@ Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
        int size;
        int ii = 0, phy_id = 0;
        const u32 *addr;
-@@ -49,18 +49,11 @@ static int pfe_get_gemac_if_proprties(st
-       pdata->ls1012a_eth_pdata[port].gem_id = port;
+@@ -49,12 +49,6 @@ static int pfe_get_gemac_if_proprties(st
  
-       mac_addr = of_get_mac_address(gem);
--
-       if (mac_addr) {
-               memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
-                      ETH_ALEN);
-       }
+       of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr);
  
 -      pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem);
 -
index a42e9aa354a69b5cb9613af0735381fcaafa76a0..2613628d02cd6bc2f17c18eda5de2e9d3a2f29e4 100644 (file)
@@ -30,9 +30,3 @@ Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
  
        pdata->ls1012a_eth_pdata[port].gem_id = port;
  
-       mac_addr = of_get_mac_address(gem);
--      if (mac_addr) {
-+      if (!IS_ERR_OR_NULL(mac_addr)) {
-               memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
-                      ETH_ALEN);
-       }
index 3a9b2eb7cd032907067fabf060be4ef67aef5730..4ee6f8466099faaf29bf4a08158a3d870c9b50ac 100644 (file)
@@ -12,20 +12,18 @@ Tested-by: Johannes Kimmel <fff@bareminimum.eu>
 Signed-off-by: Roman Kuzmitskii <damex.pp@icloud.com>
 --- a/drivers/staging/octeon/ethernet.c
 +++ b/drivers/staging/octeon/ethernet.c
-@@ -408,9 +408,12 @@ int cvm_oct_common_init(struct net_devic
+@@ -408,7 +408,11 @@ int cvm_oct_common_init(struct net_devic
+ int cvm_oct_common_init(struct net_device *dev)
  {
        struct octeon_ethernet *priv = netdev_priv(dev);
-       const u8 *mac = NULL;
 +      const u8 *label = NULL;
--      if (priv->of_node)
-+      if (priv->of_node) {
-               mac = of_get_mac_address(priv->of_node);
+       int ret;
++
++      if (priv->of_node)
 +              label = of_get_property(priv->of_node, "label", NULL);
-+      }
  
-       if (!IS_ERR_OR_NULL(mac))
-               ether_addr_copy(dev->dev_addr, mac);
+       ret = of_get_mac_address(priv->of_node, dev->dev_addr);
+       if (ret)
 @@ -445,6 +448,9 @@ int cvm_oct_common_init(struct net_devic
        if (dev->netdev_ops->ndo_stop)
                dev->netdev_ops->ndo_stop(dev);
index 3a9b2eb7cd032907067fabf060be4ef67aef5730..4ee6f8466099faaf29bf4a08158a3d870c9b50ac 100644 (file)
@@ -12,20 +12,18 @@ Tested-by: Johannes Kimmel <fff@bareminimum.eu>
 Signed-off-by: Roman Kuzmitskii <damex.pp@icloud.com>
 --- a/drivers/staging/octeon/ethernet.c
 +++ b/drivers/staging/octeon/ethernet.c
-@@ -408,9 +408,12 @@ int cvm_oct_common_init(struct net_devic
+@@ -408,7 +408,11 @@ int cvm_oct_common_init(struct net_devic
+ int cvm_oct_common_init(struct net_device *dev)
  {
        struct octeon_ethernet *priv = netdev_priv(dev);
-       const u8 *mac = NULL;
 +      const u8 *label = NULL;
--      if (priv->of_node)
-+      if (priv->of_node) {
-               mac = of_get_mac_address(priv->of_node);
+       int ret;
++
++      if (priv->of_node)
 +              label = of_get_property(priv->of_node, "label", NULL);
-+      }
  
-       if (!IS_ERR_OR_NULL(mac))
-               ether_addr_copy(dev->dev_addr, mac);
+       ret = of_get_mac_address(priv->of_node, dev->dev_addr);
+       if (ret)
 @@ -445,6 +448,9 @@ int cvm_oct_common_init(struct net_devic
        if (dev->netdev_ops->ndo_stop)
                dev->netdev_ops->ndo_stop(dev);
index cf6d4806edabf277169178bd6182d5107869ac08..e07e5ed5a8f8924e8f4de62f26e4655d7d30e289 100644 (file)
@@ -1368,7 +1368,6 @@ static int __init fe_init(struct net_device *dev)
 {
        struct fe_priv *priv = netdev_priv(dev);
        struct device_node *port;
-       const char *mac_addr;
        int err;
 
        if (priv->soc->reset_fe)
@@ -1389,9 +1388,7 @@ static int __init fe_init(struct net_device *dev)
 
        fe_reset_phy(priv);
 
-       mac_addr = of_get_mac_address(priv->dev->of_node);
-       if (!IS_ERR_OR_NULL(mac_addr))
-               ether_addr_copy(dev->dev_addr, mac_addr);
+       of_get_mac_address(priv->dev->of_node, dev->dev_addr);
 
        /* If the mac address is invalid, use random mac address  */
        if (!is_valid_ether_addr(dev->dev_addr)) {
index de54868cadfea049abbea349c3b3f068082aff5c..f810f7eb581025aad0ae8a7b392b969056b00a32 100644 (file)
@@ -1968,7 +1968,6 @@ static int __init rtl838x_eth_probe(struct platform_device *pdev)
        struct device_node *dn = pdev->dev.of_node;
        struct rtl838x_eth_priv *priv;
        struct resource *res, *mem;
-       const void *mac;
        phy_interface_t phy_mode;
        struct phylink *phylink;
        int err = 0, i, rxrings, rxringlen;
@@ -2089,10 +2088,9 @@ static int __init rtl838x_eth_probe(struct platform_device *pdev)
         * 1) from device tree data
         * 2) from internal registers set by bootloader
         */
-       mac = of_get_mac_address(pdev->dev.of_node);
-       if (!IS_ERR(mac)) {
-               memcpy(dev->dev_addr, mac, ETH_ALEN);
-               rtl838x_set_mac_hw(dev, (u8 *)mac);
+       of_get_mac_address(pdev->dev.of_node, dev->dev_addr);
+       if (is_valid_ether_addr(dev->dev_addr))) {
+               rtl838x_set_mac_hw(dev, (u8 *)dev->dev_addr);
        } else {
                dev->dev_addr[0] = (sw_r32(priv->r->mac) >> 8) & 0xff;
                dev->dev_addr[1] = sw_r32(priv->r->mac) & 0xff;