[openwrt/openwrt] generic: 6.12: add pending b53 fixes for BCM5325

LEDE Commits lede-commits at lists.infradead.org
Tue Nov 25 04:24:52 PST 2025


noltari pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/b0e9371cb15216c64d10a0526a078bdb278156df

commit b0e9371cb15216c64d10a0526a078bdb278156df
Author: Álvaro Fernández Rojas <noltari at gmail.com>
AuthorDate: Tue Nov 25 10:53:20 2025 +0100

    generic: 6.12: add pending b53 fixes for BCM5325
    
    These patches fix the remaining issues with BCM5325 switches and allow
    dropping the default VLAN on Huawei HG556a.
    
    Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
 .../bcm6358/base-files/etc/board.d/02_network      |   1 -
 ...cm531x5-fix-cpu-rgmii-mode-interpretation.patch |   4 +-
 ...fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch |  31 ++++
 ...-extracting-VID-from-entry-for-BCM5325-65.patch |  28 ++++
 ...e-ARL-search-result-offset-for-BCM5325-65.patch |  71 +++++++++
 ...U-port-unicast-ARL-entries-for-BCM5325-65.patch |  48 ++++++
 ...BCM5325-65-ARL-entry-multicast-port-masks.patch | 117 ++++++++++++++
 ...net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch | 137 ++++++++++++++++
 ...07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch | 175 +++++++++++++++++++++
 9 files changed, 609 insertions(+), 3 deletions(-)

diff --git a/target/linux/bmips/bcm6358/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6358/base-files/etc/board.d/02_network
index 0f21e362ef..c3b5eff9ff 100644
--- a/target/linux/bmips/bcm6358/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/bcm6358/base-files/etc/board.d/02_network
@@ -9,7 +9,6 @@ huawei,hg553 |\
 huawei,hg556a-a |\
 huawei,hg556a-b |\
 huawei,hg556a-c)
-	ucidef_set_bridge_device switch
 	ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
 	;;
 esac
diff --git a/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch b/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch
index fc2a9caadf..abf19408a2 100644
--- a/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch
+++ b/target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch
@@ -58,7 +58,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
 +	  the phy interface, but actually requires internal delays enabled.
 --- a/drivers/net/dsa/b53/b53_common.c
 +++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1447,6 +1447,16 @@ static void b53_adjust_531x5_rgmii(struc
+@@ -1434,6 +1434,16 @@ static void b53_adjust_531x5_rgmii(struc
  	else
  		off = B53_RGMII_CTRL_P(port);
  
@@ -75,7 +75,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
  	/* Configure the port RGMII clock delay by DLL disabled and
  	 * tx_clk aligned timing (restoring to reset defaults)
  	 */
-@@ -1458,19 +1468,24 @@ static void b53_adjust_531x5_rgmii(struc
+@@ -1445,19 +1455,24 @@ static void b53_adjust_531x5_rgmii(struc
  	 * account for this internal delay that is inserted, otherwise
  	 * the switch won't be able to receive correctly.
  	 *
diff --git a/target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch
new file mode 100644
index 0000000000..6d5131d4b5
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-01-net-dsa-b53-fix-VLAN_ID_IDX-write-size-for-BCM5325-65.patch
@@ -0,0 +1,31 @@
+From 36ee43df98b0ac16bb73e62fa8cffcdf710c37e4 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:44 +0100
+Subject: [PATCH] net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65
+
+Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX
+register is only 8 bit wide, not 16 bit, so use an appropriate accessor.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1946,8 +1946,12 @@ static int b53_arl_op(struct b53_device
+ 
+ 	/* Perform a read for the given MAC and VID */
+ 	b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac);
+-	if (!is5325m(dev))
+-		b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
++	if (!is5325m(dev)) {
++		if (is5325(dev) || is5365(dev))
++			b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
++		else
++			b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
++	}
+ 
+ 	/* Issue a read operation for this MAC */
+ 	ret = b53_arl_rw_op(dev, 1);
diff --git a/target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch
new file mode 100644
index 0000000000..54db56df21
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-02-net-dsa-b53-fix-extracting-VID-from-entry-for-BCM5325-65.patch
@@ -0,0 +1,28 @@
+From 2bed2d0932c37d6cae9a745613c2e8f83649ed39 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:45 +0100
+Subject: [PATCH] net: dsa: b53: fix extracting VID from entry for BCM5325/65
+
+BCM5325/65's Entry register uses the highest three bits for
+VALID/STATIC/AGE, so shifting by 53 only will add these to
+b53_arl_entry::vid.
+
+So make sure to mask the vid value as well, to not get invalid VIDs.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_priv.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -350,7 +350,7 @@ static inline void b53_arl_to_entry_25(s
+ 	ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
+ 	ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
+ 	u64_to_ether_addr(mac_vid, ent->mac);
+-	ent->vid = mac_vid >> ARLTBL_VID_S_65;
++	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
+ }
+ 
+ static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
diff --git a/target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch
new file mode 100644
index 0000000000..8c4bb03cf0
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-03-net-dsa-b53-use-same-ARL-search-result-offset-for-BCM5325-65.patch
@@ -0,0 +1,71 @@
+From 8d2f3f0e87fe526686f7a2744bf965ce4e99ae41 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:46 +0100
+Subject: [PATCH] net: dsa: b53: use same ARL search result offset for BCM5325/65
+
+BCM5365's search result is at the same offset as BCM5325's search
+result, and they (mostly) share the same format, so switch BCM5365 to
+BCM5325's arl ops.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 18 +-----------------
+ drivers/net/dsa/b53/b53_regs.h   |  4 +---
+ 2 files changed, 2 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2105,16 +2105,6 @@ static void b53_arl_search_read_25(struc
+ 	b53_arl_to_entry_25(ent, mac_vid);
+ }
+ 
+-static void b53_arl_search_read_65(struct b53_device *dev, u8 idx,
+-				   struct b53_arl_entry *ent)
+-{
+-	u64 mac_vid;
+-
+-	b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
+-		   &mac_vid);
+-	b53_arl_to_entry_25(ent, mac_vid);
+-}
+-
+ static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
+ 				   struct b53_arl_entry *ent)
+ {
+@@ -2730,12 +2720,6 @@ static const struct b53_arl_ops b53_arl_
+ 	.arl_search_read = b53_arl_search_read_25,
+ };
+ 
+-static const struct b53_arl_ops b53_arl_ops_65 = {
+-	.arl_read_entry = b53_arl_read_entry_25,
+-	.arl_write_entry = b53_arl_write_entry_25,
+-	.arl_search_read = b53_arl_search_read_65,
+-};
+-
+ static const struct b53_arl_ops b53_arl_ops_89 = {
+ 	.arl_read_entry = b53_arl_read_entry_89,
+ 	.arl_write_entry = b53_arl_write_entry_89,
+@@ -2798,7 +2782,7 @@ static const struct b53_chip_data b53_sw
+ 		.arl_buckets = 1024,
+ 		.imp_port = 5,
+ 		.duplex_reg = B53_DUPLEX_STAT_FE,
+-		.arl_ops = &b53_arl_ops_65,
++		.arl_ops = &b53_arl_ops_25,
+ 	},
+ 	{
+ 		.chip_id = BCM5389_DEVICE_ID,
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -372,10 +372,8 @@
+ #define B53_ARL_SRCH_RSLT_MACVID_89	0x33
+ #define B53_ARL_SRCH_RSLT_MACVID_63XX	0x34
+ 
+-/* Single register search result on 5325 */
++/* Single register search result on 5325/5365 */
+ #define B53_ARL_SRCH_RSTL_0_MACVID_25	0x24
+-/* Single register search result on 5365 */
+-#define B53_ARL_SRCH_RSTL_0_MACVID_65	0x30
+ 
+ /* ARL Search Data Result (32 bit) */
+ #define B53_ARL_SRCH_RSTL_0		0x68
diff --git a/target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch
new file mode 100644
index 0000000000..47cfb01cc2
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-04-net-dsa-b53-fix-CPU-port-unicast-ARL-entries-for-BCM5325-65.patch
@@ -0,0 +1,48 @@
+From d0d7daf6e051f8795e4e1b759ff5055c80a85832 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:47 +0100
+Subject: [PATCH] net: dsa: b53: fix CPU port unicast ARL entries for BCM5325/65
+
+On BCM5325 and BCM5365, unicast ARL entries use 8 as the value for the
+CPU port, so we need to translate it to/from 5 as used for the CPU port
+at most other places.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_priv.h | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -344,12 +344,14 @@ static inline void b53_arl_to_entry_25(s
+ 				       u64 mac_vid)
+ {
+ 	memset(ent, 0, sizeof(*ent));
+-	ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
+-		     ARLTBL_DATA_PORT_ID_MASK_25;
+ 	ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
+ 	ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
+ 	ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
+ 	u64_to_ether_addr(mac_vid, ent->mac);
++	ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
++		     ARLTBL_DATA_PORT_ID_MASK_25;
++	if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
++		ent->port = B53_CPU_PORT_25;
+ 	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
+ }
+ 
+@@ -383,8 +385,11 @@ static inline void b53_arl_from_entry_25
+ 					 const struct b53_arl_entry *ent)
+ {
+ 	*mac_vid = ether_addr_to_u64(ent->mac);
+-	*mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
+-			  ARLTBL_DATA_PORT_ID_S_25;
++	if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25)
++		*mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25;
++	else
++		*mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
++				  ARLTBL_DATA_PORT_ID_S_25;
+ 	*mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
+ 			  ARLTBL_VID_S_65;
+ 	if (ent->is_valid)
diff --git a/target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch b/target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch
new file mode 100644
index 0000000000..59016c13f4
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-05-net-dsa-b53-fix-BCM5325-65-ARL-entry-multicast-port-masks.patch
@@ -0,0 +1,117 @@
+From 0a215e4d8da0c5e36ee29304879a111daff5b461 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:48 +0100
+Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks
+
+We currently use the mask 0xf for writing and reading b53_entry::port,
+but this is only correct for unicast ARL entries. Multicast ARL entries
+use a bitmask, and 0xf is not enough space for ports > 3, which includes
+the CPU port.
+
+So extend the mask accordingly to also fit port 4 (bit 4) and MII (bit
+5). According to the datasheet the multicast port mask is [60:48],
+making it 12 bit wide, but bits 60-55 are reserved anyway, and collide
+with the priority field at [60:59], so I am not sure if this is valid.
+Therefore leave it at the actual used range, [53:48].
+
+The ARL search result register differs a bit, and there the mask is only
+[52:48], so only spanning the user ports. The MII port bit is
+contained in the Search Result Extension register. So create a separate
+search result parse function that properly handles this.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c |  4 +++-
+ drivers/net/dsa/b53/b53_priv.h   | 25 +++++++++++++++++++++----
+ drivers/net/dsa/b53/b53_regs.h   |  8 +++++++-
+ 3 files changed, 31 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2099,10 +2099,12 @@ static void b53_arl_search_read_25(struc
+ 				   struct b53_arl_entry *ent)
+ {
+ 	u64 mac_vid;
++	u8 ext;
+ 
++	b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext);
+ 	b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
+ 		   &mac_vid);
+-	b53_arl_to_entry_25(ent, mac_vid);
++	b53_arl_search_to_entry_25(ent, mac_vid, ext);
+ }
+ 
+ static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -348,8 +348,8 @@ static inline void b53_arl_to_entry_25(s
+ 	ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
+ 	ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
+ 	u64_to_ether_addr(mac_vid, ent->mac);
+-	ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
+-		     ARLTBL_DATA_PORT_ID_MASK_25;
++	ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >>
++		     ARLTBL_DATA_PORT_ID_S_25;
+ 	if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
+ 		ent->port = B53_CPU_PORT_25;
+ 	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
+@@ -388,8 +388,8 @@ static inline void b53_arl_from_entry_25
+ 	if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25)
+ 		*mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25;
+ 	else
+-		*mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
+-				  ARLTBL_DATA_PORT_ID_S_25;
++		*mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) &
++			    ARLTBL_DATA_PORT_ID_MASK_25;
+ 	*mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
+ 			  ARLTBL_VID_S_65;
+ 	if (ent->is_valid)
+@@ -414,6 +414,23 @@ static inline void b53_arl_from_entry_89
+ 		*fwd_entry |= ARLTBL_AGE_89;
+ }
+ 
++static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent,
++					      u64 mac_vid, u8 ext)
++{
++	memset(ent, 0, sizeof(*ent));
++	ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
++	ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
++	ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
++	u64_to_ether_addr(mac_vid, ent->mac);
++	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
++	ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >>
++		    ARL_SRCH_RSLT_PORT_ID_S_25;
++	if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII))
++		ent->port |= BIT(B53_CPU_PORT_25);
++	else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
++		ent->port = B53_CPU_PORT_25;
++}
++
+ static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
+ 						u64 mac_vid, u16 fwd_entry)
+ {
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -328,7 +328,7 @@
+ #define   ARLTBL_VID_MASK_25		0xff
+ #define   ARLTBL_VID_MASK		0xfff
+ #define   ARLTBL_DATA_PORT_ID_S_25	48
+-#define   ARLTBL_DATA_PORT_ID_MASK_25	0xf
++#define   ARLTBL_DATA_PORT_ID_MASK_25	GENMASK_ULL(53, 48)
+ #define   ARLTBL_VID_S_65		53
+ #define   ARLTBL_AGE_25			BIT_ULL(61)
+ #define   ARLTBL_STATIC_25		BIT_ULL(62)
+@@ -374,6 +374,12 @@
+ 
+ /* Single register search result on 5325/5365 */
+ #define B53_ARL_SRCH_RSTL_0_MACVID_25	0x24
++#define   ARL_SRCH_RSLT_PORT_ID_S_25	48
++#define   ARL_SRCH_RSLT_PORT_ID_MASK_25	GENMASK_ULL(52, 48)
++
++/* BCM5325/5365 Search result extend register (8 bit) */
++#define B53_ARL_SRCH_RSLT_EXT_25	0x2c
++#define   ARL_SRCH_RSLT_EXT_MC_MII	BIT(2)
+ 
+ /* ARL Search Data Result (32 bit) */
+ #define B53_ARL_SRCH_RSTL_0		0x68
diff --git a/target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch b/target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch
new file mode 100644
index 0000000000..8e579afda7
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-06-net-dsa-b53-fix-BCM5325-65-ARL-entry-VIDs.patch
@@ -0,0 +1,137 @@
+From d41f2d5f1c9c6d492ccd3ffdd09e064e70ebc934 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:49 +0100
+Subject: [PATCH] net: dsa: b53: fix BCM5325/65 ARL entry VIDs
+
+BCM5325/65's ARL entry registers do not contain the VID, only the search
+result register does. ARL entries have a separate VID entry register for
+the index into the VLAN table.
+
+So make ARL entry accessors use the VID entry registers instead, and
+move the VLAN ID field definition to the search register definition.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c |  9 +++++++--
+ drivers/net/dsa/b53/b53_priv.h   | 12 ++++++------
+ drivers/net/dsa/b53/b53_regs.h   |  7 +++++--
+ 3 files changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1833,19 +1833,24 @@ static int b53_arl_rw_op(struct b53_devi
+ static void b53_arl_read_entry_25(struct b53_device *dev,
+ 				  struct b53_arl_entry *ent, u8 idx)
+ {
++	u8 vid_entry;
+ 	u64 mac_vid;
+ 
++	b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx),
++		  &vid_entry);
+ 	b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
+ 		   &mac_vid);
+-	b53_arl_to_entry_25(ent, mac_vid);
++	b53_arl_to_entry_25(ent, mac_vid, vid_entry);
+ }
+ 
+ static void b53_arl_write_entry_25(struct b53_device *dev,
+ 				   const struct b53_arl_entry *ent, u8 idx)
+ {
++	u8 vid_entry;
+ 	u64 mac_vid;
+ 
+-	b53_arl_from_entry_25(&mac_vid, ent);
++	b53_arl_from_entry_25(&mac_vid, &vid_entry, ent);
++	b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry);
+ 	b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
+ 		    mac_vid);
+ }
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -341,7 +341,7 @@ static inline void b53_arl_to_entry(stru
+ }
+ 
+ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent,
+-				       u64 mac_vid)
++				       u64 mac_vid, u8 vid_entry)
+ {
+ 	memset(ent, 0, sizeof(*ent));
+ 	ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
+@@ -352,7 +352,7 @@ static inline void b53_arl_to_entry_25(s
+ 		     ARLTBL_DATA_PORT_ID_S_25;
+ 	if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
+ 		ent->port = B53_CPU_PORT_25;
+-	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
++	ent->vid = vid_entry;
+ }
+ 
+ static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
+@@ -381,7 +381,7 @@ static inline void b53_arl_from_entry(u6
+ 		*fwd_entry |= ARLTBL_AGE;
+ }
+ 
+-static inline void b53_arl_from_entry_25(u64 *mac_vid,
++static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry,
+ 					 const struct b53_arl_entry *ent)
+ {
+ 	*mac_vid = ether_addr_to_u64(ent->mac);
+@@ -390,14 +390,13 @@ static inline void b53_arl_from_entry_25
+ 	else
+ 		*mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) &
+ 			    ARLTBL_DATA_PORT_ID_MASK_25;
+-	*mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
+-			  ARLTBL_VID_S_65;
+ 	if (ent->is_valid)
+ 		*mac_vid |= ARLTBL_VALID_25;
+ 	if (ent->is_static)
+ 		*mac_vid |= ARLTBL_STATIC_25;
+ 	if (ent->is_age)
+ 		*mac_vid |= ARLTBL_AGE_25;
++	*vid_entry = ent->vid;
+ }
+ 
+ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry,
+@@ -422,7 +421,8 @@ static inline void b53_arl_search_to_ent
+ 	ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
+ 	ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
+ 	u64_to_ether_addr(mac_vid, ent->mac);
+-	ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25;
++	ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >>
++		   ARL_SRCH_RSLT_VID_S_25;
+ 	ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >>
+ 		    ARL_SRCH_RSLT_PORT_ID_S_25;
+ 	if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII))
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -325,11 +325,9 @@
+ #define B53_ARLTBL_MAC_VID_ENTRY(n)	((0x10 * (n)) + 0x10)
+ #define   ARLTBL_MAC_MASK		0xffffffffffffULL
+ #define   ARLTBL_VID_S			48
+-#define   ARLTBL_VID_MASK_25		0xff
+ #define   ARLTBL_VID_MASK		0xfff
+ #define   ARLTBL_DATA_PORT_ID_S_25	48
+ #define   ARLTBL_DATA_PORT_ID_MASK_25	GENMASK_ULL(53, 48)
+-#define   ARLTBL_VID_S_65		53
+ #define   ARLTBL_AGE_25			BIT_ULL(61)
+ #define   ARLTBL_STATIC_25		BIT_ULL(62)
+ #define   ARLTBL_VALID_25		BIT_ULL(63)
+@@ -349,6 +347,9 @@
+ #define   ARLTBL_STATIC_89		BIT(14)
+ #define   ARLTBL_VALID_89		BIT(15)
+ 
++/* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */
++#define B53_ARLTBL_VID_ENTRY_25(n)	((0x2 * (n)) + 0x30)
++
+ /* Maximum number of bin entries in the ARL for all switches */
+ #define B53_ARLTBL_MAX_BIN_ENTRIES	4
+ 
+@@ -376,6 +377,8 @@
+ #define B53_ARL_SRCH_RSTL_0_MACVID_25	0x24
+ #define   ARL_SRCH_RSLT_PORT_ID_S_25	48
+ #define   ARL_SRCH_RSLT_PORT_ID_MASK_25	GENMASK_ULL(52, 48)
++#define   ARL_SRCH_RSLT_VID_S_25	53
++#define   ARL_SRCH_RSLT_VID_MASK_25	GENMASK_ULL(60, 53)
+ 
+ /* BCM5325/5365 Search result extend register (8 bit) */
+ #define B53_ARL_SRCH_RSLT_EXT_25	0x2c
diff --git a/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch b/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch
new file mode 100644
index 0000000000..9b255cc39f
--- /dev/null
+++ b/target/linux/generic/pending-6.12/750-07-net-dsa-b53-allow-VID-0-for-BCM5325-65.patch
@@ -0,0 +1,175 @@
+From b5a97c36457e4299afdb420603d39d1e30da843e Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Tue, 25 Nov 2025 08:51:50 +0100
+Subject: [PATCH] net: dsa: b53: allow VID 0 for BCM5325/65
+
+Now that writing ARL entries works properly, we can actually use VID 0
+as the default untagged VLAN for BCM5325 and BCM5365 as well, so use 0
+as default PVID always.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 49 +++++++++++---------------------
+ 1 file changed, 17 insertions(+), 32 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -850,14 +850,6 @@ static void b53_enable_stp(struct b53_de
+ 	b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
+ }
+ 
+-static u16 b53_default_pvid(struct b53_device *dev)
+-{
+-	if (is5325(dev) || is5365(dev))
+-		return 1;
+-	else
+-		return 0;
+-}
+-
+ static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
+ {
+ 	struct b53_device *dev = ds->priv;
+@@ -886,14 +878,12 @@ int b53_configure_vlan(struct dsa_switch
+ 	struct b53_device *dev = ds->priv;
+ 	struct b53_vlan vl = { 0 };
+ 	struct b53_vlan *v;
+-	int i, def_vid;
+ 	u16 vid;
+-
+-	def_vid = b53_default_pvid(dev);
++	int i;
+ 
+ 	/* clear all vlan entries */
+ 	if (is5325(dev) || is5365(dev)) {
+-		for (i = def_vid; i < dev->num_vlans; i++)
++		for (i = 0; i < dev->num_vlans; i++)
+ 			b53_set_vlan_entry(dev, i, &vl);
+ 	} else {
+ 		b53_do_vlan_op(dev, VTA_CMD_CLEAR);
+@@ -907,7 +897,7 @@ int b53_configure_vlan(struct dsa_switch
+ 	 * entry. Do this only when the tagging protocol is not
+ 	 * DSA_TAG_PROTO_NONE
+ 	 */
+-	v = &dev->vlans[def_vid];
++	v = &dev->vlans[0];
+ 	b53_for_each_port(dev, i) {
+ 		if (!b53_vlan_port_may_join_untagged(ds, i))
+ 			continue;
+@@ -915,16 +905,15 @@ int b53_configure_vlan(struct dsa_switch
+ 		vl.members |= BIT(i);
+ 		if (!b53_vlan_port_needs_forced_tagged(ds, i))
+ 			vl.untag = vl.members;
+-		b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i),
+-			    def_vid);
++		b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(i), 0);
+ 	}
+-	b53_set_vlan_entry(dev, def_vid, &vl);
++	b53_set_vlan_entry(dev, 0, &vl);
+ 
+ 	if (dev->vlan_filtering) {
+ 		/* Upon initial call we have not set-up any VLANs, but upon
+ 		 * system resume, we need to restore all VLAN entries.
+ 		 */
+-		for (vid = def_vid + 1; vid < dev->num_vlans; vid++) {
++		for (vid = 1; vid < dev->num_vlans; vid++) {
+ 			v = &dev->vlans[vid];
+ 
+ 			if (!v->members)
+@@ -1260,7 +1249,6 @@ static int b53_setup(struct dsa_switch *
+ 	struct b53_device *dev = ds->priv;
+ 	struct b53_vlan *vl;
+ 	unsigned int port;
+-	u16 pvid;
+ 	int ret;
+ 
+ 	/* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set
+@@ -1290,8 +1278,7 @@ static int b53_setup(struct dsa_switch *
+ 	}
+ 
+ 	/* setup default vlan for filtering mode */
+-	pvid = b53_default_pvid(dev);
+-	vl = &dev->vlans[pvid];
++	vl = &dev->vlans[0];
+ 	b53_for_each_port(dev, port) {
+ 		vl->members |= BIT(port);
+ 		if (!b53_vlan_port_needs_forced_tagged(ds, port))
+@@ -1720,7 +1707,7 @@ int b53_vlan_add(struct dsa_switch *ds,
+ 	if (pvid)
+ 		new_pvid = vlan->vid;
+ 	else if (!pvid && vlan->vid == old_pvid)
+-		new_pvid = b53_default_pvid(dev);
++		new_pvid = 0;
+ 	else
+ 		new_pvid = old_pvid;
+ 	dev->ports[port].pvid = new_pvid;
+@@ -1770,7 +1757,7 @@ int b53_vlan_del(struct dsa_switch *ds,
+ 	vl->members &= ~BIT(port);
+ 
+ 	if (pvid == vlan->vid)
+-		pvid = b53_default_pvid(dev);
++		pvid = 0;
+ 	dev->ports[port].pvid = pvid;
+ 
+ 	if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port))
+@@ -2249,7 +2236,7 @@ int b53_br_join(struct dsa_switch *ds, i
+ 	struct b53_device *dev = ds->priv;
+ 	struct b53_vlan *vl;
+ 	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+-	u16 pvlan, reg, pvid;
++	u16 pvlan, reg;
+ 	unsigned int i;
+ 
+ 	/* On 7278, port 7 which connects to the ASP should only receive
+@@ -2258,8 +2245,7 @@ int b53_br_join(struct dsa_switch *ds, i
+ 	if (dev->chip_id == BCM7278_DEVICE_ID && port == 7)
+ 		return -EINVAL;
+ 
+-	pvid = b53_default_pvid(dev);
+-	vl = &dev->vlans[pvid];
++	vl = &dev->vlans[0];
+ 
+ 	if (dev->vlan_filtering) {
+ 		/* Make this port leave the all VLANs join since we will have
+@@ -2275,9 +2261,9 @@ int b53_br_join(struct dsa_switch *ds, i
+ 				    reg);
+ 		}
+ 
+-		b53_get_vlan_entry(dev, pvid, vl);
++		b53_get_vlan_entry(dev, 0, vl);
+ 		vl->members &= ~BIT(port);
+-		b53_set_vlan_entry(dev, pvid, vl);
++		b53_set_vlan_entry(dev, 0, vl);
+ 	}
+ 
+ 	b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan);
+@@ -2316,7 +2302,7 @@ void b53_br_leave(struct dsa_switch *ds,
+ 	struct b53_vlan *vl;
+ 	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+ 	unsigned int i;
+-	u16 pvlan, reg, pvid;
++	u16 pvlan, reg;
+ 
+ 	b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan);
+ 
+@@ -2341,8 +2327,7 @@ void b53_br_leave(struct dsa_switch *ds,
+ 	b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
+ 	dev->ports[port].vlan_ctl_mask = pvlan;
+ 
+-	pvid = b53_default_pvid(dev);
+-	vl = &dev->vlans[pvid];
++	vl = &dev->vlans[0];
+ 
+ 	if (dev->vlan_filtering) {
+ 		/* Make this port join all VLANs without VLAN entries */
+@@ -2354,9 +2339,9 @@ void b53_br_leave(struct dsa_switch *ds,
+ 			b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
+ 		}
+ 
+-		b53_get_vlan_entry(dev, pvid, vl);
++		b53_get_vlan_entry(dev, 0, vl);
+ 		vl->members |= BIT(port);
+-		b53_set_vlan_entry(dev, pvid, vl);
++		b53_set_vlan_entry(dev, 0, vl);
+ 	}
+ }
+ EXPORT_SYMBOL(b53_br_leave);




More information about the lede-commits mailing list