Skip to contentSkip to conversation

davinci_emac: read the MAC address from nvmem

PATCH In review Bartosz Golaszewski 2 participants 6 messages Nov 30, 2018 – Dec 3, 2018

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

cover davinci_emac: read the MAC address from nvmem

From: Bartosz Golaszewski <[email protected]>

This series is part of a bigger series that aims at removing the platform data structure from the at24 EEPROM driver[1].

We provide a generalized version of of_get_nvmem_mac_address(), switch the only user of the of_ variant to using it, remove the previous implementation and use the new routine in the davinci_emac driver.

[1] https://lkml.org/lkml/2018/11/13/884

Bartosz Golaszewski (4):
net: ethernet: provide nvmem_get_mac_address()
net: cadence: switch to using nvmem_get_mac_address()
of: net: kill of_get_nvmem_mac_address()
net: davinci_emac: use nvmem_get_mac_address()

 drivers/net/ethernet/cadence/macb_main.c |  2 +-
 drivers/net/ethernet/ti/davinci_emac.c   | 14 ++++++---
 drivers/of/of_net.c                      | 39 ------------------------
 include/linux/etherdevice.h              |  1 +
 include/linux/of_net.h                   |  6 ----
 net/ethernet/eth.c                       | 38 +++++++++++++++++++++++
 6 files changed, 49 insertions(+), 51 deletions(-)
Signature · 1 line
2.19.1
#1 lore raw

PATCH 1/4 net: ethernet: provide nvmem_get_mac_address()

From: Bartosz Golaszewski <[email protected]>

We already have of_get_nvmem_mac_address() but some non-DT systems want to read the MAC address from NVMEM too. Implement a generalized routine that takes struct device as argument.

---
 include/linux/etherdevice.h |  1 +
 net/ethernet/eth.c          | 38 +++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
include/linux/etherdevice.h +1 -0
index 572e11bb8696..2c0af7b00715 100644
@@ -32,6 +32,7 @@
 struct device;
 int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr);
 unsigned char *arch_get_platform_mac_address(void);
+int nvmem_get_mac_address(struct device *dev, void *addrbuf);
 u32 eth_get_headlen(void *data, unsigned int max_len);
 __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern const struct header_ops eth_header_ops;
net/ethernet/eth.c +38 -0
index fd8faa0dfa61..df38593d1bb4 100644
@@ -47,6 +47,7 @@
 #include <linux/inet.h>
 #include <linux/ip.h>
 #include <linux/netdevice.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/errno.h>
@@ -548,3 +549,40 @@ int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr)
 	return 0;
 }
 EXPORT_SYMBOL(eth_platform_get_mac_address);
+
+/**
+ * Obtain the MAC address from an nvmem cell named 'mac-address' associated
+ * with given device.
+ *
+ * @dev:	Device with which the mac-address cell is associated.
+ * @addrbuf:	Buffer to which the MAC address will be copied on success.
+ *
+ * Returns 0 on success or a negative error number on failure.
+ */
+int nvmem_get_mac_address(struct device *dev, void *addrbuf)
+{
+	struct nvmem_cell *cell;
+	const void *mac;
+	size_t len;
+
+	cell = nvmem_cell_get(dev, "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;
+	}
+
+	ether_addr_copy(addrbuf, mac);
+	kfree(mac);
+
+	return 0;
+}
+EXPORT_SYMBOL(nvmem_get_mac_address);
Signature · 1 line
2.19.1
#2 lore raw

PATCH 2/4 net: cadence: switch to using nvmem_get_mac_address()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

We now have a generalized helper routine to read the MAC address from nvmem which takes struct device as argument. The nvmem subsystem will then try device tree first before all other potential providers.

---
 drivers/net/ethernet/cadence/macb_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/cadence/macb_main.c +1 -1
index 1d86b4d5645a..d9a208f7bb40 100644
@@ -4055,7 +4055,7 @@ static int macb_probe(struct platform_device *pdev)
 	if (mac) {
 		ether_addr_copy(bp->dev->dev_addr, mac);
 	} else {
-		err = of_get_nvmem_mac_address(np, bp->dev->dev_addr);
+		err = nvmem_get_mac_address(&pdev->dev, bp->dev->dev_addr);
 		if (err) {
 			if (err == -EPROBE_DEFER)
 				goto err_out_free_netdev;
Signature · 1 line
2.19.1
#3 lore raw

PATCH 3/4 of: net: kill of_get_nvmem_mac_address()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

We've switched all users to nvmem_get_mac_address(). Remove the now dead code.

---
 drivers/of/of_net.c    | 39 ---------------------------------------
 include/linux/of_net.h |  6 ------
 2 files changed, 45 deletions(-)
drivers/of/of_net.c +0 -39
index 53189d4022a6..810ab0fbcccb 100644
@@ -81,42 +81,3 @@ const void *of_get_mac_address(struct device_node *np)
 	return of_get_mac_addr(np, "address");
 }
 EXPORT_SYMBOL(of_get_mac_address);
-
-/**
- * Obtain the MAC address from an nvmem provider named 'mac-address' through
- * device tree.
- * On success, copies the new address into memory pointed to by addr and
- * returns 0. Returns a negative error code otherwise.
- * @np:		Device tree node containing the nvmem-cells phandle
- * @addr:	Pointer to receive the MAC address using ether_addr_copy()
- */
-int of_get_nvmem_mac_address(struct device_node *np, void *addr)
-{
-	struct nvmem_cell *cell;
-	const void *mac;
-	size_t len;
-	int 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)) {
-		ret = -EINVAL;
-	} else {
-		ether_addr_copy(addr, mac);
-		ret = 0;
-	}
-
-	kfree(mac);
-
-	return ret;
-}
-EXPORT_SYMBOL(of_get_nvmem_mac_address);
include/linux/of_net.h +0 -6
index 90d81ee9e6a0..9cd72aab76fe 100644
@@ -13,7 +13,6 @@
 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_nvmem_mac_address(struct device_node *np, void *addr);
 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)
@@ -26,11 +25,6 @@ static inline const void *of_get_mac_address(struct device_node *np)
 	return NULL;
 }
 
-static inline int of_get_nvmem_mac_address(struct device_node *np, void *addr)
-{
-	return -ENODEV;
-}
-
 static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
 {
 	return NULL;
Signature · 1 line
2.19.1
#4 lore raw

PATCH 4/4 net: davinci_emac: use nvmem_get_mac_address()

In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>

All DaVinci boards still supported in board files now define nvmem cells containing the MAC address. We want to stop using the setup callback from at24 so the MAC address for those users will no longer be provided over platform data. If we didn't get a valid MAC in pdata, try nvmem before resorting to a random MAC.

---
 drivers/net/ethernet/ti/davinci_emac.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/net/ethernet/ti/davinci_emac.c +9 -5
index 9153db120352..840820402cd0 100644
@@ -1912,11 +1912,15 @@ static int davinci_emac_probe(struct platform_device *pdev)
 		ether_addr_copy(ndev->dev_addr, priv->mac_addr);
 
 	if (!is_valid_ether_addr(priv->mac_addr)) {
-		/* Use random MAC if none passed */
-		eth_hw_addr_random(ndev);
-		memcpy(priv->mac_addr, ndev->dev_addr, ndev->addr_len);
-		dev_warn(&pdev->dev, "using random MAC addr: %pM\n",
-							priv->mac_addr);
+		/* Try nvmem if MAC wasn't passed over pdata or DT. */
+		rc = nvmem_get_mac_address(&pdev->dev, priv->mac_addr);
+		if (rc) {
+			/* Use random MAC if still none obtained. */
+			eth_hw_addr_random(ndev);
+			memcpy(priv->mac_addr, ndev->dev_addr, ndev->addr_len);
+			dev_warn(&pdev->dev, "using random MAC addr: %pM\n",
+				 priv->mac_addr);
+		}
 	}
 
 	ndev->netdev_ops = &emac_netdev_ops;
Signature · 1 line
2.19.1
maintainer
#5 lore raw
In reply to Bartosz Golaszewski

From: Bartosz Golaszewski <[email protected]>
Date: Fri, 30 Nov 2018 09:20:56 +0100

Quoted 10 lines

From: Bartosz Golaszewski <[email protected]>

This series is part of a bigger series that aims at removing the platform data structure from the at24 EEPROM driver[1].

We provide a generalized version of of_get_nvmem_mac_address(), switch the only user of the of_ variant to using it, remove the previous implementation and use the new routine in the davinci_emac driver.

[1] https://lkml.org/lkml/2018/11/13/884

This looks good, series applied.