2023-04-21 08:44:56

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 1/3] dt-bindings: nvmem: brcm,nvram: add #nvmem-cell-cells for MACs

From: Rafał Miłecki <[email protected]>

Broadcom's NVRAM contains MACs for Ethernet interfaces. Those MACs are
usually base addresses that are also used for calculating other MACs.

For example if a router vendor decided to use gmac0 it most likely
programmed NVRAM of each unit with a proper "et0macaddr" value. That is
a base.

Ethernet interface is usually connected to switch port. Switch usually
includes few LAN ports and a WAN port. MAC of WAN port gets calculated
as relative address to the interface one. Offset varies depending on
device model.

Wireless MACs may also need to be calculated using relevant offsets.

To support all those scenarios let MAC NVMEM cells be referenced with an
index specifying MAC offset. Disallow additionalProperties while at it.

Signed-off-by: Rafał Miłecki <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
V2: Add additionalProperties: false
---
.../devicetree/bindings/nvmem/brcm,nvram.yaml | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
index 36def7128fca..13412af7f046 100644
--- a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
+++ b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
@@ -36,14 +36,29 @@ properties:
et0macaddr:
type: object
description: First Ethernet interface's MAC address
+ properties:
+ "#nvmem-cell-cells":
+ description: The first argument is a MAC address offset.
+ const: 1
+ additionalProperties: false

et1macaddr:
type: object
description: Second Ethernet interface's MAC address
+ properties:
+ "#nvmem-cell-cells":
+ description: The first argument is a MAC address offset.
+ const: 1
+ additionalProperties: false

et2macaddr:
type: object
description: Third Ethernet interface's MAC address
+ properties:
+ "#nvmem-cell-cells":
+ description: The first argument is a MAC address offset.
+ const: 1
+ additionalProperties: false

unevaluatedProperties: false

--
2.34.1


2023-04-21 08:45:21

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 2/3] nvmem: brcm_nvram: add .read_post_process() for MACs

From: Rafał Miłecki <[email protected]>

1. Parse ASCII MAC format into byte based
2. Calculate relative addresses based on index argument

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/nvmem/Kconfig | 1 +
drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index b291b27048c7..688b70ba4826 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM
tristate "Broadcom's NVRAM support"
depends on ARCH_BCM_5301X || COMPILE_TEST
depends on HAS_IOMEM
+ select GENERIC_NET_UTILS
help
This driver provides support for Broadcom's NVRAM that can be accessed
using I/O mapping.
diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
index 39aa27942f28..4567c597c87f 100644
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -4,6 +4,8 @@
*/

#include <linux/bcm47xx_nvram.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context, unsigned int offset, void *val,
return 0;
}

+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index,
+ unsigned int offset, void *buf, size_t bytes)
+{
+ u8 mac[ETH_ALEN];
+
+ if (bytes != 3 * ETH_ALEN - 1)
+ return -EINVAL;
+
+ if (!mac_pton(buf, mac))
+ return -EINVAL;
+
+ if (index)
+ eth_addr_add(mac, index);
+
+ ether_addr_copy(buf, mac);
+
+ return 0;
+}
+
static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
size_t len)
{
@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
priv->cells[idx].offset = value - (char *)data;
priv->cells[idx].bytes = strlen(value);
priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
+ if (!strcmp(var, "et0macaddr") ||
+ !strcmp(var, "et1macaddr") ||
+ !strcmp(var, "et2macaddr")) {
+ priv->cells[idx].raw_len = strlen(value);
+ priv->cells[idx].bytes = ETH_ALEN;
+ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
+ }
}

return 0;
--
2.34.1

2023-04-21 08:45:34

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 3/3] ARM: dts: BCM5301X: Specify WAN port MAC address for Luxul XWR-3150

From: Rafał Miłecki <[email protected]>

It needs to be calculated based on the base Ethernet interface one.

Signed-off-by: Rafał Miłecki <[email protected]>
---
This PATCH is a proof of concept that can go separately through the ARM
DT tree. I'd actually suggest that. There are more .dts files I'll want
to update.
Srini: can you just take the first 2 patches from this series?
---
arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
index 60a2c441d5bd..2dd05f4dce92 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
@@ -27,6 +27,7 @@ nvram@1eff0000 {
reg = <0x1eff0000 0x10000>;

et0macaddr: et0macaddr {
+ #nvmem-cell-cells = <1>;
};
};

@@ -76,7 +77,7 @@ button-restart {
};

&gmac0 {
- nvmem-cells = <&et0macaddr>;
+ nvmem-cells = <&et0macaddr 0>;
nvmem-cell-names = "mac-address";
};

@@ -119,6 +120,8 @@ port@3 {
port@4 {
reg = <4>;
label = "wan";
+ nvmem-cells = <&et0macaddr 5>;
+ nvmem-cell-names = "mac-address";
};

port@5 {
--
2.34.1

2023-05-12 10:25:25

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [PATCH V2 1/3] dt-bindings: nvmem: brcm,nvram: add #nvmem-cell-cells for MACs



On 21/04/2023 09:43, Rafał Miłecki wrote:
> From: Rafał Miłecki <[email protected]>
>
> Broadcom's NVRAM contains MACs for Ethernet interfaces. Those MACs are
> usually base addresses that are also used for calculating other MACs.
>
> For example if a router vendor decided to use gmac0 it most likely
> programmed NVRAM of each unit with a proper "et0macaddr" value. That is
> a base.
>
> Ethernet interface is usually connected to switch port. Switch usually
> includes few LAN ports and a WAN port. MAC of WAN port gets calculated
> as relative address to the interface one. Offset varies depending on
> device model.
>
> Wireless MACs may also need to be calculated using relevant offsets.
>
> To support all those scenarios let MAC NVMEM cells be referenced with an
> index specifying MAC offset. Disallow additionalProperties while at it.
>
> Signed-off-by: Rafał Miłecki <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> ---

Applied thanks,

--srini
> V2: Add additionalProperties: false
> ---
> .../devicetree/bindings/nvmem/brcm,nvram.yaml | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
> index 36def7128fca..13412af7f046 100644
> --- a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
> +++ b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
> @@ -36,14 +36,29 @@ properties:
> et0macaddr:
> type: object
> description: First Ethernet interface's MAC address
> + properties:
> + "#nvmem-cell-cells":
> + description: The first argument is a MAC address offset.
> + const: 1
> + additionalProperties: false
>
> et1macaddr:
> type: object
> description: Second Ethernet interface's MAC address
> + properties:
> + "#nvmem-cell-cells":
> + description: The first argument is a MAC address offset.
> + const: 1
> + additionalProperties: false
>
> et2macaddr:
> type: object
> description: Third Ethernet interface's MAC address
> + properties:
> + "#nvmem-cell-cells":
> + description: The first argument is a MAC address offset.
> + const: 1
> + additionalProperties: false
>
> unevaluatedProperties: false
>

2023-05-12 10:28:34

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [PATCH V2 2/3] nvmem: brcm_nvram: add .read_post_process() for MACs



On 21/04/2023 09:43, Rafał Miłecki wrote:
> From: Rafał Miłecki <[email protected]>
>
> 1. Parse ASCII MAC format into byte based
> 2. Calculate relative addresses based on index argument
>
> Signed-off-by: Rafał Miłecki <[email protected]>
> ---

Applied thanks,

--srini
> drivers/nvmem/Kconfig | 1 +
> drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
> 2 files changed, 29 insertions(+)
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index b291b27048c7..688b70ba4826 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM
> tristate "Broadcom's NVRAM support"
> depends on ARCH_BCM_5301X || COMPILE_TEST
> depends on HAS_IOMEM
> + select GENERIC_NET_UTILS
> help
> This driver provides support for Broadcom's NVRAM that can be accessed
> using I/O mapping.
> diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
> index 39aa27942f28..4567c597c87f 100644
> --- a/drivers/nvmem/brcm_nvram.c
> +++ b/drivers/nvmem/brcm_nvram.c
> @@ -4,6 +4,8 @@
> */
>
> #include <linux/bcm47xx_nvram.h>
> +#include <linux/etherdevice.h>
> +#include <linux/if_ether.h>
> #include <linux/io.h>
> #include <linux/mod_devicetable.h>
> #include <linux/module.h>
> @@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context, unsigned int offset, void *val,
> return 0;
> }
>
> +static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index,
> + unsigned int offset, void *buf, size_t bytes)
> +{
> + u8 mac[ETH_ALEN];
> +
> + if (bytes != 3 * ETH_ALEN - 1)
> + return -EINVAL;
> +
> + if (!mac_pton(buf, mac))
> + return -EINVAL;
> +
> + if (index)
> + eth_addr_add(mac, index);
> +
> + ether_addr_copy(buf, mac);
> +
> + return 0;
> +}
> +
> static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
> size_t len)
> {
> @@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
> priv->cells[idx].offset = value - (char *)data;
> priv->cells[idx].bytes = strlen(value);
> priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
> + if (!strcmp(var, "et0macaddr") ||
> + !strcmp(var, "et1macaddr") ||
> + !strcmp(var, "et2macaddr")) {
> + priv->cells[idx].raw_len = strlen(value);
> + priv->cells[idx].bytes = ETH_ALEN;
> + priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
> + }
> }
>
> return 0;