[PATCH] kernel: of: add DT MAC address bitwise operation support

Shiji Yang yangshiji66 at outlook.com
Fri Nov 10 01:41:52 PST 2023


From: Shiji Yang <yangshiji66 at qq.com>

This patch allow user to perform basic bitwise clear/set operation on
OF DT MAC address. We use two new added dt-bindings to specific the
MAC address bits clear/set mask. "mac-address-bitwise-set" can be used
to set bit. And "mac-address-bitwise-clear" can be used to clear bit.

Signed-off-by: Shiji Yang <yangshiji66 at qq.com>
---

Hi!
This patch can benefit a lot of devices.

Git grep ref:

macaddr_setbit_la
https://git.openwrt.org/?p=openwrt%2Fopenwrt.git&a=search&h=HEAD&st=grep&s=macaddr_setbit_la&sr=1

macaddr_setbit
https://git.openwrt.org/?p=openwrt%2Fopenwrt.git&a=search&h=HEAD&st=grep&s=macaddr_setbit&sr=1

macaddr_unsetbit
https://git.openwrt.org/?p=openwrt%2Fopenwrt.git&a=search&h=HEAD&st=grep&s=macaddr_unsetbit&sr=1

If this hack/idea is unacceptable, please let me know. Thanks!

Regards,
Shiji Yang


 ...-cell-MAC-address-bitwise-operation-.patch | 101 ++++++++++++++++++
 ...-cell-MAC-address-bitwise-operation-.patch | 101 ++++++++++++++++++
 2 files changed, 202 insertions(+)
 create mode 100644 target/linux/generic/hack-5.15/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch
 create mode 100644 target/linux/generic/hack-6.1/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch

diff --git a/target/linux/generic/hack-5.15/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch b/target/linux/generic/hack-5.15/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch
new file mode 100644
index 0000000000..396eed8f4a
--- /dev/null
+++ b/target/linux/generic/hack-5.15/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch
@@ -0,0 +1,101 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Sun, 16 Jul 2023 21:00:15 +0800
+Subject: [PATCH] of: net: add DT MAC address bitwise operation support
+
+This patch allow user to perform basic bitwise clear/set operation on
+OF DT MAC address. We use two new added dt-bindings to specific the
+MAC address bits clear/set mask. "mac-address-bitwise-set" can be used
+to set bit. And "mac-address-bitwise-clear" can be used to clear bit.
+
+The "mac-address-bitwise-*" property consists of two 32-bit(4 Bytes)
+hexadecimal. The first hex number mask the Byte[1-2] and the second
+one mask the Byte[3-6]. Each MAC address bit corresponds to the unique
+mask bit. When setting mask bit to "1", OF driver will clear/set the
+corresponding MAC address bit.
+
+Sample MAC Address and Property Mask:
+AA: BB : CC : DD : EE : FF      -->  mask:  <0xAABB 0xCCDDEEFF>
+^         ^              ^
+Byte[1]   Byte[3]        Byte[6]
+
+Usage Example:
+Assuming the base MAC address is "00:11:22:33:44:55", and we have dts
+as follows. then the final MAC address should be "ff:11:22:33:44:66".
+
+0xff1122334466 = 0x001122334455 & (~0x0000000000ff) | 0xff0000000066
+
+&gmac0 {
+	nvmem-cells = <&macaddr_base>;
+	nvmem-cell-names = "mac-address";
+	mac-address-bitwise-clear = <0x0000 0x000000ff>;
+	mac-address-bitwise-set = <0xff00 0x00000066>;
+};
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ net/core/of_net.c | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/net/core/of_net.c
++++ b/net/core/of_net.c
+@@ -154,17 +154,10 @@ free:
+ */
+ int of_get_mac_address(struct device_node *np, u8 *addr)
+ {
+-	u32 inc_idx, mac_inc, mac_val;
++	u32 inc_idx, mac_inc;
++	u64 mac_val, mac_msk;
+ 	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 -EINVAL;
+-
+ 	if (!np)
+ 		return -ENODEV;
+ 
+@@ -185,16 +178,24 @@ int of_get_mac_address(struct device_nod
+ 		return ret;
+ 
+ found:
++	mac_val = ether_addr_to_u64(addr);
++
++	if (!of_property_read_u64(np, "mac-address-bitwise-clear", &mac_msk))
++		mac_val &= ~mac_msk;
++
++	if (!of_property_read_u64(np, "mac-address-bitwise-set", &mac_msk))
++		mac_val |= mac_msk;
++
+ 	if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) {
+-		/* Convert to a contiguous value */
+-		mac_val = (addr[3] << 16) + (addr[4] << 8) + addr[5];
++		/* 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 -EINVAL;
+ 		mac_val += mac_inc << 8 * (5-inc_idx);
+ 
+-		/* Apply the incremented value handling overflow case */
+-		addr[3] = (mac_val >> 16) & 0xff;
+-		addr[4] = (mac_val >> 8) & 0xff;
+-		addr[5] = (mac_val >> 0) & 0xff;
+-
+ 		/* Remove mac-address-increment and mac-address-increment-byte
+ 		 * DT property to make sure MAC address would not get incremented
+ 		 * more if this function is stared again. */
+@@ -202,6 +203,8 @@ found:
+ 		of_remove_property(np, of_find_property(np, "mac-address-increment-byte", NULL));
+ 	}
+ 
++	u64_to_ether_addr(mac_val, addr);
++
+ 	of_add_mac_address(np, addr);
+ 	return ret;
+ }
diff --git a/target/linux/generic/hack-6.1/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch b/target/linux/generic/hack-6.1/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch
new file mode 100644
index 0000000000..396eed8f4a
--- /dev/null
+++ b/target/linux/generic/hack-6.1/686-of-net-add-NVMEM-cell-MAC-address-bitwise-operation-.patch
@@ -0,0 +1,101 @@
+From: Shiji Yang <yangshiji66 at outlook.com>
+Date: Sun, 16 Jul 2023 21:00:15 +0800
+Subject: [PATCH] of: net: add DT MAC address bitwise operation support
+
+This patch allow user to perform basic bitwise clear/set operation on
+OF DT MAC address. We use two new added dt-bindings to specific the
+MAC address bits clear/set mask. "mac-address-bitwise-set" can be used
+to set bit. And "mac-address-bitwise-clear" can be used to clear bit.
+
+The "mac-address-bitwise-*" property consists of two 32-bit(4 Bytes)
+hexadecimal. The first hex number mask the Byte[1-2] and the second
+one mask the Byte[3-6]. Each MAC address bit corresponds to the unique
+mask bit. When setting mask bit to "1", OF driver will clear/set the
+corresponding MAC address bit.
+
+Sample MAC Address and Property Mask:
+AA: BB : CC : DD : EE : FF      -->  mask:  <0xAABB 0xCCDDEEFF>
+^         ^              ^
+Byte[1]   Byte[3]        Byte[6]
+
+Usage Example:
+Assuming the base MAC address is "00:11:22:33:44:55", and we have dts
+as follows. then the final MAC address should be "ff:11:22:33:44:66".
+
+0xff1122334466 = 0x001122334455 & (~0x0000000000ff) | 0xff0000000066
+
+&gmac0 {
+	nvmem-cells = <&macaddr_base>;
+	nvmem-cell-names = "mac-address";
+	mac-address-bitwise-clear = <0x0000 0x000000ff>;
+	mac-address-bitwise-set = <0xff00 0x00000066>;
+};
+
+Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
+---
+ net/core/of_net.c | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/net/core/of_net.c
++++ b/net/core/of_net.c
+@@ -154,17 +154,10 @@ free:
+ */
+ int of_get_mac_address(struct device_node *np, u8 *addr)
+ {
+-	u32 inc_idx, mac_inc, mac_val;
++	u32 inc_idx, mac_inc;
++	u64 mac_val, mac_msk;
+ 	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 -EINVAL;
+-
+ 	if (!np)
+ 		return -ENODEV;
+ 
+@@ -185,16 +178,24 @@ int of_get_mac_address(struct device_nod
+ 		return ret;
+ 
+ found:
++	mac_val = ether_addr_to_u64(addr);
++
++	if (!of_property_read_u64(np, "mac-address-bitwise-clear", &mac_msk))
++		mac_val &= ~mac_msk;
++
++	if (!of_property_read_u64(np, "mac-address-bitwise-set", &mac_msk))
++		mac_val |= mac_msk;
++
+ 	if (!of_property_read_u32(np, "mac-address-increment", &mac_inc)) {
+-		/* Convert to a contiguous value */
+-		mac_val = (addr[3] << 16) + (addr[4] << 8) + addr[5];
++		/* 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 -EINVAL;
+ 		mac_val += mac_inc << 8 * (5-inc_idx);
+ 
+-		/* Apply the incremented value handling overflow case */
+-		addr[3] = (mac_val >> 16) & 0xff;
+-		addr[4] = (mac_val >> 8) & 0xff;
+-		addr[5] = (mac_val >> 0) & 0xff;
+-
+ 		/* Remove mac-address-increment and mac-address-increment-byte
+ 		 * DT property to make sure MAC address would not get incremented
+ 		 * more if this function is stared again. */
+@@ -202,6 +203,8 @@ found:
+ 		of_remove_property(np, of_find_property(np, "mac-address-increment-byte", NULL));
+ 	}
+ 
++	u64_to_ether_addr(mac_val, addr);
++
+ 	of_add_mac_address(np, addr);
+ 	return ret;
+ }
-- 
2.39.2




More information about the openwrt-devel mailing list