diff mbox series

[v3,3/4] of_net: add mac-address-increment support

Message ID 20200920095724.8251-4-ansuelsmth@gmail.com
State Not Applicable
Delegated to: David Miller
Headers show
Series Actually implement nvmem support for mtd | expand

Commit Message

Christian Marangi Sept. 20, 2020, 9:57 a.m. UTC
Lots of embedded devices use the mac-address of other interface
extracted from nvmem cells and increments it by one or two. Add two
bindings to integrate this and directly use the right mac-address for
the interface. Some example are some routers that use the gmac
mac-address stored in the art partition and increments it by one for the
wifi. mac-address-increment-byte bindings is used to tell what byte of
the mac-address has to be increased (if not defined the last byte is
increased) and mac-address-increment tells how much the byte decided
early has to be increased.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
 drivers/of/of_net.c | 57 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 44 insertions(+), 13 deletions(-)

Comments

Rob Herring Sept. 25, 2020, 6:24 p.m. UTC | #1
On Sun, Sep 20, 2020 at 3:57 AM Ansuel Smith <ansuelsmth@gmail.com> wrote:
>
> Lots of embedded devices use the mac-address of other interface
> extracted from nvmem cells and increments it by one or two. Add two
> bindings to integrate this and directly use the right mac-address for
> the interface. Some example are some routers that use the gmac
> mac-address stored in the art partition and increments it by one for the
> wifi. mac-address-increment-byte bindings is used to tell what byte of
> the mac-address has to be increased (if not defined the last byte is
> increased) and mac-address-increment tells how much the byte decided
> early has to be increased.

I'm inclined to say if there's a platform specific way to transform
MAC addresses, then there should be platform specific code to do that
which then stuffs the DT using standard properties. Otherwise, we have
a never ending stream of 'generic' properties to try to handle
different platforms' cases.

Rob
Christian Marangi Sept. 25, 2020, 6:39 p.m. UTC | #2
> -----Original Message-----
> From: Rob Herring <robh+dt@kernel.org>
> Sent: Friday, September 25, 2020 8:24 PM
> To: Ansuel Smith <ansuelsmth@gmail.com>
> Cc: Miquel Raynal <miquel.raynal@bootlin.com>; Richard Weinberger
> <richard@nod.at>; Vignesh Raghavendra <vigneshr@ti.com>; David S.
> Miller <davem@davemloft.net>; Jakub Kicinski <kuba@kernel.org>;
> Andrew Lunn <andrew@lunn.ch>; Heiner Kallweit
> <hkallweit1@gmail.com>; Russell King <linux@armlinux.org.uk>; Frank
> Rowand <frowand.list@gmail.com>; Boris Brezillon
> <bbrezillon@kernel.org>; MTD Maling List <linux-mtd@lists.infradead.org>;
> devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; netdev
> <netdev@vger.kernel.org>
> Subject: Re: [PATCH v3 3/4] of_net: add mac-address-increment support
> 
> On Sun, Sep 20, 2020 at 3:57 AM Ansuel Smith <ansuelsmth@gmail.com>
> wrote:
> >
> > Lots of embedded devices use the mac-address of other interface
> > extracted from nvmem cells and increments it by one or two. Add two
> > bindings to integrate this and directly use the right mac-address for
> > the interface. Some example are some routers that use the gmac
> > mac-address stored in the art partition and increments it by one for the
> > wifi. mac-address-increment-byte bindings is used to tell what byte of
> > the mac-address has to be increased (if not defined the last byte is
> > increased) and mac-address-increment tells how much the byte decided
> > early has to be increased.
> 
> I'm inclined to say if there's a platform specific way to transform
> MAC addresses, then there should be platform specific code to do that
> which then stuffs the DT using standard properties. Otherwise, we have
> a never ending stream of 'generic' properties to try to handle
> different platforms' cases.
> 
> Rob

I agree about the 'never ending stream'... But I think the increment feature
is not that platform specific. I will quote some number by another patch
that tried to implement the same feature in a different way, [1]

* mtd-mac-address                used 497 times in 357 device tree files
* mtd-mac-address-increment      used  74 times in  58 device tree files
* mtd-mac-address-increment-byte used   1 time  in   1 device tree file

The mtd-mac-address is what this patchset is trying to fix with the nvmem
support. The increment is much more than 74 times since it doesn't count
SoC that have wifi integrated (it's common practice for SoC with integrated
wifi to take the switch mac and use it to set the wifi mac)
Actually what is really specific is the increment-byte that can be dropped
if we really want to.
I still think the increment feature would be very useful to add full support
for mac-address extracted from nvmem cell.

[1] https://patchwork.ozlabs.org/project/netdev/patch/1555445100-30936-1-git-send-email-ynezz@true.cz/
diff mbox series

Patch

diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
index 6e411821583e..bafbc833e659 100644
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -45,7 +45,7 @@  int of_get_phy_mode(struct device_node *np, phy_interface_t *interface)
 }
 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);
 
@@ -54,26 +54,31 @@  static const void *of_get_mac_addr(struct device_node *np, const char *name)
 	return NULL;
 }
 
-static const void *of_get_mac_addr_nvmem(struct device_node *np)
+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;
 }
@@ -98,24 +103,50 @@  static const void *of_get_mac_addr_nvmem(struct device_node *np)
  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
  * but is all zeros.
  *
+ * DT can tell the system to increment the mac-address after is extracted by
+ * using:
+ * - mac-address-increment-byte to decide what byte to increase
+ *   (if not defined is increased the last byte)
+ * - mac-address-increment to decide how much to increase. The value will
+ *   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.
 */
 const void *of_get_mac_address(struct device_node *np)
 {
-	const void *addr;
+	u32 inc_idx, mac_inc;
+	int ret = 0;
+	u8 *addr;
+
+	/* 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);
 
 	addr = of_get_mac_addr(np, "mac-address");
 	if (addr)
-		return addr;
+		goto found;
 
 	addr = of_get_mac_addr(np, "local-mac-address");
 	if (addr)
-		return addr;
+		goto found;
 
 	addr = of_get_mac_addr(np, "address");
 	if (addr)
-		return addr;
+		goto found;
+
+	addr = of_get_mac_addr_nvmem(np, &ret);
+	if (ret)
+		return ERR_PTR(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;
 }
 EXPORT_SYMBOL(of_get_mac_address);