[openwrt/openwrt] bmips: huawei,hg556a-b: enable external switch
LEDE Commits
lede-commits at lists.infradead.org
Sun Jun 1 11:50:30 PDT 2025
noltari pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/dbffeebea48791066d6512a626c0279e197db682
commit dbffeebea48791066d6512a626c0279e197db682
Author: Álvaro Fernández Rojas <noltari at gmail.com>
AuthorDate: Tue May 24 11:14:21 2022 +0200
bmips: huawei,hg556a-b: enable external switch
The external switch of the Huawei HG556a is a BCM5325E connected by MDIO.
All the DSA brcm legacy FCS tag and b53 patches have been submitted upstream
and will be backported when accepted.
There are still some sporadic FDB errors, but at least the switch is working
and stable on my device:
bcm53xx fffe4800.ethernet-mii:1e: port 0 failed to add 72:31:59:xx:xx:xx vid 1 to fdb: -28
bcm53xx fffe4800.ethernet-mii:1e: port 0 failed to add 5c:4c:a9:xx:xx:xx vid 0 to fdb: -28
bcm53xx fffe4800.ethernet-mii:1e: port 0 failed to add 5c:4c:a9:xx:xx:xx vid 1 to fdb: -28
bcm53xx fffe4800.ethernet-mii:1e: port 0 failed to delete 72:31:59:xx:xx:xx vid 1 from fdb: -2
Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
target/linux/bmips/bcm6318/config-6.12 | 1 +
target/linux/bmips/bcm63268/config-6.12 | 1 +
target/linux/bmips/bcm6328/config-6.12 | 1 +
.../bcm6358/base-files/etc/board.d/02_network | 3 +-
target/linux/bmips/bcm6358/config-6.12 | 1 +
target/linux/bmips/bcm6362/config-6.12 | 1 +
target/linux/bmips/bcm6368/config-6.12 | 1 +
target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts | 53 +++++
...-dsa-tag_brcm-legacy-reorganize-functions.patch | 96 ++++++++
...-tag_brcm-add-support-for-legacy-FCS-tags.patch | 173 +++++++++++++++
.../122-net-dsa-b53-support-legacy-FCS-tags.patch | 45 ++++
...-add-support-for-FDB-operations-on-5325-5.patch | 243 +++++++++++++++++++++
...sa-b53-prevent-FAST_AGE-access-on-BCM5325.patch | 49 +++++
...b53-prevent-SWITCH_CTRL-access-on-BCM5325.patch | 37 ++++
...-dsa-b53-fix-IP_MULTICAST_CTRL-on-BCM5325.patch | 50 +++++
...53-prevent-DIS_LEARNING-access-on-BCM5325.patch | 29 +++
...sa-b53-prevent-BRCM_HDR-access-on-BCM5325.patch | 30 +++
...-prevent-GMII_PORT_OVERRIDE_CTRL-access-o.patch | 75 +++++++
...-fix-unicast-multicast-flooding-on-BCM532.patch | 190 ++++++++++++++++
...sa-b53-fix-b53_imp_vlan_setup-for-BCM5325.patch | 30 +++
...t-dsa-b53-ensure-BCM5325-PHYs-are-enabled.patch | 28 +++
21 files changed, 1136 insertions(+), 1 deletion(-)
diff --git a/target/linux/bmips/bcm6318/config-6.12 b/target/linux/bmips/bcm6318/config-6.12
index 0851a2eb69..746ba1fc17 100644
--- a/target/linux/bmips/bcm6318/config-6.12
+++ b/target/linux/bmips/bcm6318/config-6.12
@@ -171,6 +171,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
diff --git a/target/linux/bmips/bcm63268/config-6.12 b/target/linux/bmips/bcm63268/config-6.12
index 2cc5a85d08..8d692322d8 100644
--- a/target/linux/bmips/bcm63268/config-6.12
+++ b/target/linux/bmips/bcm63268/config-6.12
@@ -185,6 +185,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
diff --git a/target/linux/bmips/bcm6328/config-6.12 b/target/linux/bmips/bcm6328/config-6.12
index 00582dd277..fd7a058381 100644
--- a/target/linux/bmips/bcm6328/config-6.12
+++ b/target/linux/bmips/bcm6328/config-6.12
@@ -184,6 +184,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
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 470d1b1bd0..4a539a2d9f 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
@@ -6,7 +6,8 @@ board_config_update
case "$(board_name)" in
huawei,hg556a-b)
- ucidef_set_interface_lan "eth0"
+ ucidef_set_bridge_device switch
+ ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
esac
diff --git a/target/linux/bmips/bcm6358/config-6.12 b/target/linux/bmips/bcm6358/config-6.12
index 9829ecad47..7f5da92396 100644
--- a/target/linux/bmips/bcm6358/config-6.12
+++ b/target/linux/bmips/bcm6358/config-6.12
@@ -170,6 +170,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
diff --git a/target/linux/bmips/bcm6362/config-6.12 b/target/linux/bmips/bcm6362/config-6.12
index a247ee77b6..2eef21a31a 100644
--- a/target/linux/bmips/bcm6362/config-6.12
+++ b/target/linux/bmips/bcm6362/config-6.12
@@ -185,6 +185,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
diff --git a/target/linux/bmips/bcm6368/config-6.12 b/target/linux/bmips/bcm6368/config-6.12
index ffe3317b50..9c7b27be44 100644
--- a/target/linux/bmips/bcm6368/config-6.12
+++ b/target/linux/bmips/bcm6368/config-6.12
@@ -186,6 +186,7 @@ CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_BRCM=y
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS=y
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_EGRESS=y
diff --git a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
index 999f162fe4..70f4de7494 100644
--- a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
+++ b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
@@ -151,6 +151,59 @@
status = "okay";
};
+&mdio1 {
+ switch at 1e {
+ compatible = "brcm,bcm5325";
+ reg = <30>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+ label = "lan1";
+
+ phy-mode = "mii";
+ };
+
+ port at 1 {
+ reg = <1>;
+ label = "lan2";
+
+ phy-mode = "mii";
+ };
+
+ port at 2 {
+ reg = <2>;
+ label = "lan3";
+
+ phy-mode = "mii";
+ };
+
+ port at 3 {
+ reg = <3>;
+ label = "lan4";
+
+ phy-mode = "mii";
+ };
+
+ port at 5 {
+ reg = <5>;
+ label = "cpu";
+
+ phy-mode = "internal";
+ ethernet = <ðernet1>;
+
+ fixed-link {
+ speed = <100>;
+ full-duplex;
+ };
+ };
+ };
+ };
+};
+
&ohci {
status = "okay";
};
diff --git a/target/linux/bmips/patches-6.12/120-net-dsa-tag_brcm-legacy-reorganize-functions.patch b/target/linux/bmips/patches-6.12/120-net-dsa-tag_brcm-legacy-reorganize-functions.patch
new file mode 100644
index 0000000000..fbc91219df
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/120-net-dsa-tag_brcm-legacy-reorganize-functions.patch
@@ -0,0 +1,96 @@
+From f4ed3dc77c598151a892b3c7622da4e8313bde2c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 17:10:11 +0200
+Subject: [PATCH] net: dsa: tag_brcm: legacy: reorganize functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move brcm_leg_tag_rcv() definition to top.
+This function is going to be shared between two different tags.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ net/dsa/tag_brcm.c | 64 +++++++++++++++++++++++-----------------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -213,6 +213,38 @@ MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROT
+ #endif
+
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
++static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ int len = BRCM_LEG_TAG_LEN;
++ int source_port;
++ u8 *brcm_tag;
++
++ if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN)))
++ return NULL;
++
++ brcm_tag = dsa_etype_header_pos_rx(skb);
++
++ source_port = brcm_tag[5] & BRCM_LEG_PORT_ID;
++
++ skb->dev = dsa_conduit_find_user(dev, 0, source_port);
++ if (!skb->dev)
++ return NULL;
++
++ /* VLAN tag is added by BCM63xx internal switch */
++ if (netdev_uses_dsa(skb->dev))
++ len += VLAN_HLEN;
++
++ /* Remove Broadcom tag and update checksum */
++ skb_pull_rcsum(skb, len);
++
++ dsa_default_offload_fwd_mark(skb);
++
++ dsa_strip_etype_header(skb, len);
++
++ return skb;
++}
++
+ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+ {
+@@ -249,38 +281,6 @@ static struct sk_buff *brcm_leg_tag_xmit
+
+ return skb;
+ }
+-
+-static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
+- struct net_device *dev)
+-{
+- int len = BRCM_LEG_TAG_LEN;
+- int source_port;
+- u8 *brcm_tag;
+-
+- if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN)))
+- return NULL;
+-
+- brcm_tag = dsa_etype_header_pos_rx(skb);
+-
+- source_port = brcm_tag[5] & BRCM_LEG_PORT_ID;
+-
+- skb->dev = dsa_conduit_find_user(dev, 0, source_port);
+- if (!skb->dev)
+- return NULL;
+-
+- /* VLAN tag is added by BCM63xx internal switch */
+- if (netdev_uses_dsa(skb->dev))
+- len += VLAN_HLEN;
+-
+- /* Remove Broadcom tag and update checksum */
+- skb_pull_rcsum(skb, len);
+-
+- dsa_default_offload_fwd_mark(skb);
+-
+- dsa_strip_etype_header(skb, len);
+-
+- return skb;
+-}
+
+ static const struct dsa_device_ops brcm_legacy_netdev_ops = {
+ .name = BRCM_LEGACY_NAME,
diff --git a/target/linux/bmips/patches-6.12/121-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch b/target/linux/bmips/patches-6.12/121-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch
new file mode 100644
index 0000000000..d8ff205c01
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/121-net-dsa-tag_brcm-add-support-for-legacy-FCS-tags.patch
@@ -0,0 +1,173 @@
+From fa4bb7220eb7b2f0d985dd9d1f60ba8bd84a8870 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Mon, 17 Apr 2023 18:38:05 +0200
+Subject: [PATCH] net: dsa: tag_brcm: add support for legacy FCS tags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for legacy Broadcom FCS tags, which are similar to
+DSA_TAG_PROTO_BRCM_LEGACY.
+BCM5325 and BCM5365 switches require including the original FCS value and
+length, as opposed to BCM63xx switches.
+Adding the original FCS value and length to DSA_TAG_PROTO_BRCM_LEGACY would
+impact performance of BCM63xx switches, so it's better to create a new tag.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ include/net/dsa.h | 2 ++
+ net/dsa/Kconfig | 8 ++++++
+ net/dsa/tag_brcm.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 80 insertions(+), 1 deletion(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -54,11 +54,13 @@ struct tc_action;
+ #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26
+ #define DSA_TAG_PROTO_LAN937X_VALUE 27
+ #define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE 28
++#define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE 29
+
+ enum dsa_tag_protocol {
+ DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
+ DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE,
+ DSA_TAG_PROTO_BRCM_LEGACY = DSA_TAG_PROTO_BRCM_LEGACY_VALUE,
++ DSA_TAG_PROTO_BRCM_LEGACY_FCS = DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE,
+ DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE,
+ DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE,
+ DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE,
+--- a/net/dsa/Kconfig
++++ b/net/dsa/Kconfig
+@@ -49,6 +49,14 @@ config NET_DSA_TAG_BRCM_LEGACY
+ Broadcom legacy switches which place the tag after the MAC source
+ address.
+
++config NET_DSA_TAG_BRCM_LEGACY_FCS
++ tristate "Tag driver for Broadcom legacy switches using in-frame headers, FCS and length"
++ select NET_DSA_TAG_BRCM_COMMON
++ help
++ Say Y if you want to enable support for tagging frames for the
++ Broadcom legacy switches which place the tag after the MAC source
++ address and require the original FCS and length.
++
+ config NET_DSA_TAG_BRCM_PREPEND
+ tristate "Tag driver for Broadcom switches using prepended headers"
+ select NET_DSA_TAG_BRCM_COMMON
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -15,6 +15,7 @@
+
+ #define BRCM_NAME "brcm"
+ #define BRCM_LEGACY_NAME "brcm-legacy"
++#define BRCM_LEGACY_FCS_NAME "brcm-legacy-fcs"
+ #define BRCM_PREPEND_NAME "brcm-prepend"
+
+ /* Legacy Broadcom tag (6 bytes) */
+@@ -32,6 +33,10 @@
+ #define BRCM_LEG_MULTICAST (1 << 5)
+ #define BRCM_LEG_EGRESS (2 << 5)
+ #define BRCM_LEG_INGRESS (3 << 5)
++#define BRCM_LEG_LEN_HI(x) (((x) >> 8) & 0x7)
++
++/* 4th byte in the tag */
++#define BRCM_LEG_LEN_LO(x) ((x) & 0xff)
+
+ /* 6th byte in the tag */
+ #define BRCM_LEG_PORT_ID (0xf)
+@@ -212,7 +217,8 @@ DSA_TAG_DRIVER(brcm_netdev_ops);
+ MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM, BRCM_NAME);
+ #endif
+
+-#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) || \
++ IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
+ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
+ struct net_device *dev)
+ {
+@@ -244,7 +250,9 @@ static struct sk_buff *brcm_leg_tag_rcv(
+
+ return skb;
+ }
++#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY || CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */
+
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
+ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+ {
+@@ -294,6 +302,66 @@ DSA_TAG_DRIVER(brcm_legacy_netdev_ops);
+ MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY, BRCM_LEGACY_NAME);
+ #endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */
+
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
++static struct sk_buff *brcm_leg_fcs_tag_xmit(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct dsa_port *dp = dsa_user_to_port(dev);
++ unsigned int fcs_len;
++ u32 fcs_val;
++ u8 *brcm_tag;
++
++ /* The Ethernet switch we are interfaced with needs packets to be at
++ * least 64 bytes (including FCS) otherwise they will be discarded when
++ * they enter the switch port logic. When Broadcom tags are enabled, we
++ * need to make sure that packets are at least 70 bytes
++ * (including FCS and tag) because the length verification is done after
++ * the Broadcom tag is stripped off the ingress packet.
++ *
++ * Let dsa_user_xmit() free the SKB
++ */
++ if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false))
++ return NULL;
++
++ fcs_len = skb->len;
++ fcs_val = swab32(crc32(~0, skb->data, fcs_len) ^ ~0);
++
++ skb_push(skb, BRCM_LEG_TAG_LEN);
++
++ dsa_alloc_etype_header(skb, BRCM_LEG_TAG_LEN);
++
++ brcm_tag = skb->data + 2 * ETH_ALEN;
++
++ /* Broadcom tag type */
++ brcm_tag[0] = BRCM_LEG_TYPE_HI;
++ brcm_tag[1] = BRCM_LEG_TYPE_LO;
++
++ /* Broadcom tag value */
++ brcm_tag[2] = BRCM_LEG_EGRESS | BRCM_LEG_LEN_HI(fcs_len);
++ brcm_tag[3] = BRCM_LEG_LEN_LO(fcs_len);
++ brcm_tag[4] = 0;
++ brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID;
++
++ /* Original FCS value */
++ if (__skb_pad(skb, ETH_FCS_LEN, false))
++ return NULL;
++ skb_put_data(skb, &fcs_val, ETH_FCS_LEN);
++
++ return skb;
++}
++
++static const struct dsa_device_ops brcm_legacy_fcs_netdev_ops = {
++ .name = BRCM_LEGACY_FCS_NAME,
++ .proto = DSA_TAG_PROTO_BRCM_LEGACY_FCS,
++ .xmit = brcm_leg_fcs_tag_xmit,
++ .rcv = brcm_leg_tag_rcv,
++ .needed_headroom = BRCM_LEG_TAG_LEN,
++};
++
++DSA_TAG_DRIVER(brcm_legacy_fcs_netdev_ops);
++MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY_FCS, BRCM_LEGACY_FCS_NAME);
++#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */
++
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
+ static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb,
+ struct net_device *dev)
+@@ -328,6 +396,9 @@ static struct dsa_tag_driver *dsa_tag_dr
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY)
+ &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops),
+ #endif
++#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS)
++ &DSA_TAG_DRIVER_NAME(brcm_legacy_fcs_netdev_ops),
++#endif
+ #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND)
+ &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops),
+ #endif
diff --git a/target/linux/bmips/patches-6.12/122-net-dsa-b53-support-legacy-FCS-tags.patch b/target/linux/bmips/patches-6.12/122-net-dsa-b53-support-legacy-FCS-tags.patch
new file mode 100644
index 0000000000..30319b6443
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/122-net-dsa-b53-support-legacy-FCS-tags.patch
@@ -0,0 +1,45 @@
+From acd751e9fe048cb51e9aee3c780f019c5e9732ec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 17:31:39 +0200
+Subject: [PATCH] net: dsa: b53: support legacy FCS tags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 46c5176c586c ("net: dsa: b53: support legacy tags") introduced support
+for legacy tags, but it turns out that BCM5325 and BCM5365 switches require
+the original FCS value and length, so they have to be treated differently.
+
+Fixes: 46c5176c586c ("net: dsa: b53: support legacy tags")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/Kconfig | 1 +
+ drivers/net/dsa/b53/b53_common.c | 7 +++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/b53/Kconfig
++++ b/drivers/net/dsa/b53/Kconfig
+@@ -5,6 +5,7 @@ menuconfig B53
+ select NET_DSA_TAG_NONE
+ select NET_DSA_TAG_BRCM
+ select NET_DSA_TAG_BRCM_LEGACY
++ select NET_DSA_TAG_BRCM_LEGACY_FCS
+ select NET_DSA_TAG_BRCM_PREPEND
+ help
+ This driver adds support for Broadcom managed switch chips. It supports
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2266,8 +2266,11 @@ enum dsa_tag_protocol b53_get_tag_protoc
+ goto out;
+ }
+
+- /* Older models require a different 6 byte tag */
+- if (is5325(dev) || is5365(dev) || is63xx(dev)) {
++ /* Older models require different 6 byte tags */
++ if (is5325(dev) || is5365(dev)) {
++ dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY_FCS;
++ goto out;
++ } else if (is63xx(dev)) {
+ dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY;
+ goto out;
+ }
diff --git a/target/linux/bmips/patches-6.12/130-net-dsa-b53-add-support-for-FDB-operations-on-5325-5.patch b/target/linux/bmips/patches-6.12/130-net-dsa-b53-add-support-for-FDB-operations-on-5325-5.patch
new file mode 100644
index 0000000000..e61f7cbd38
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/130-net-dsa-b53-add-support-for-FDB-operations-on-5325-5.patch
@@ -0,0 +1,243 @@
+From fec493475d7f0b17dc64f682a584faae5efe640e Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli at gmail.com>
+Date: Sat, 9 Sep 2017 16:41:26 -0700
+Subject: [PATCH] net: dsa: b53: add support for FDB operations on 5325/5365
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 and BCM5365 are part of a much older generation of switches which,
+due to their limited number of ports and VLAN entries (up to 256) allowed
+a single 64-bit register to hold a full ARL entry.
+This requires a little bit of massaging when reading, writing and
+converting ARL entries in both directions.
+
+Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 64 ++++++++++++++++++++------------
+ drivers/net/dsa/b53/b53_priv.h | 57 ++++++++++++++++++++--------
+ drivers/net/dsa/b53/b53_regs.h | 7 ++--
+ 3 files changed, 86 insertions(+), 42 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1760,13 +1760,15 @@ static int b53_arl_read(struct b53_devic
+ /* Read the bins */
+ for (i = 0; i < dev->num_arl_bins; i++) {
+ u64 mac_vid;
+- u32 fwd_entry;
++ u32 fwd_entry = 0;
+
+ b53_read64(dev, B53_ARLIO_PAGE,
+ B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid);
+- b53_read32(dev, B53_ARLIO_PAGE,
+- B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
+- b53_arl_to_entry(ent, mac_vid, fwd_entry);
++
++ if (!is5325(dev) && !is5365(dev))
++ b53_read32(dev, B53_ARLIO_PAGE,
++ B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
++ b53_arl_to_entry(dev, ent, mac_vid, fwd_entry);
+
+ if (!(fwd_entry & ARLTBL_VALID)) {
+ set_bit(i, free_bins);
+@@ -1799,7 +1801,8 @@ 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);
+- b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
++ if (!is5325(dev))
++ 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);
+@@ -1850,12 +1853,14 @@ static int b53_arl_op(struct b53_device
+ ent.is_static = true;
+ ent.is_age = false;
+ memcpy(ent.mac, addr, ETH_ALEN);
+- b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
++ b53_arl_from_entry(dev, &mac_vid, &fwd_entry, &ent);
+
+ b53_write64(dev, B53_ARLIO_PAGE,
+ B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
+- b53_write32(dev, B53_ARLIO_PAGE,
+- B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
++
++ if (!is5325(dev) && !is5365(dev))
++ b53_write32(dev, B53_ARLIO_PAGE,
++ B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
+
+ return b53_arl_rw_op(dev, 0);
+ }
+@@ -1867,12 +1872,6 @@ int b53_fdb_add(struct dsa_switch *ds, i
+ struct b53_device *priv = ds->priv;
+ int ret;
+
+- /* 5325 and 5365 require some more massaging, but could
+- * be supported eventually
+- */
+- if (is5325(priv) || is5365(priv))
+- return -EOPNOTSUPP;
+-
+ mutex_lock(&priv->arl_mutex);
+ ret = b53_arl_op(priv, 0, port, addr, vid, true);
+ mutex_unlock(&priv->arl_mutex);
+@@ -1899,10 +1898,15 @@ EXPORT_SYMBOL(b53_fdb_del);
+ static int b53_arl_search_wait(struct b53_device *dev)
+ {
+ unsigned int timeout = 1000;
+- u8 reg;
++ u8 reg, offset;
++
++ if (is5325(dev) || is5365(dev))
++ offset = B53_ARL_SRCH_CTL_25;
++ else
++ offset = B53_ARL_SRCH_CTL;
+
+ do {
+- b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, ®);
++ b53_read8(dev, B53_ARLIO_PAGE, offset, ®);
+ if (!(reg & ARL_SRCH_STDN))
+ return 0;
+
+@@ -1919,13 +1923,21 @@ static void b53_arl_search_rd(struct b53
+ struct b53_arl_entry *ent)
+ {
+ u64 mac_vid;
+- u32 fwd_entry;
++ u32 fwd_entry = 0;
+
+- b53_read64(dev, B53_ARLIO_PAGE,
+- B53_ARL_SRCH_RSTL_MACVID(idx), &mac_vid);
+- b53_read32(dev, B53_ARLIO_PAGE,
+- B53_ARL_SRCH_RSTL(idx), &fwd_entry);
+- b53_arl_to_entry(ent, mac_vid, fwd_entry);
++ if (is5325(dev)) {
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
++ &mac_vid);
++ } else if (is5365(dev)) {
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
++ &mac_vid);
++ } else {
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx),
++ &mac_vid);
++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx),
++ &fwd_entry);
++ }
++ b53_arl_to_entry(dev, ent, mac_vid, fwd_entry);
+ }
+
+ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
+@@ -1946,14 +1958,20 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ struct b53_device *priv = ds->priv;
+ struct b53_arl_entry results[2];
+ unsigned int count = 0;
++ u8 offset;
+ int ret;
+ u8 reg;
+
+ mutex_lock(&priv->arl_mutex);
+
++ if (is5325(priv) || is5365(priv))
++ offset = B53_ARL_SRCH_CTL_25;
++ else
++ offset = B53_ARL_SRCH_CTL;
++
+ /* Start search operation */
+ reg = ARL_SRCH_STDN;
+- b53_write8(priv, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, reg);
++ b53_write8(priv, offset, B53_ARL_SRCH_CTL, reg);
+
+ do {
+ ret = b53_arl_search_wait(priv);
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -286,30 +286,55 @@ struct b53_arl_entry {
+ u8 is_static:1;
+ };
+
+-static inline void b53_arl_to_entry(struct b53_arl_entry *ent,
++static inline void b53_arl_to_entry(struct b53_device *dev,
++ struct b53_arl_entry *ent,
+ u64 mac_vid, u32 fwd_entry)
+ {
+ memset(ent, 0, sizeof(*ent));
+- ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK;
+- ent->is_valid = !!(fwd_entry & ARLTBL_VALID);
+- ent->is_age = !!(fwd_entry & ARLTBL_AGE);
+- ent->is_static = !!(fwd_entry & ARLTBL_STATIC);
+- u64_to_ether_addr(mac_vid, ent->mac);
+- ent->vid = mac_vid >> ARLTBL_VID_S;
++ if (is5325(dev) || is5365(dev)) {
++ 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->vid = mac_vid >> ARLTBL_VID_S_65;
++ } else {
++ ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK;
++ ent->is_valid = !!(fwd_entry & ARLTBL_VALID);
++ ent->is_age = !!(fwd_entry & ARLTBL_AGE);
++ ent->is_static = !!(fwd_entry & ARLTBL_STATIC);
++ u64_to_ether_addr(mac_vid, ent->mac);
++ ent->vid = mac_vid >> ARLTBL_VID_S;
++ }
+ }
+
+-static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
++static inline void b53_arl_from_entry(struct b53_device *dev,
++ u64 *mac_vid, u32 *fwd_entry,
+ const struct b53_arl_entry *ent)
+ {
+ *mac_vid = ether_addr_to_u64(ent->mac);
+- *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S;
+- *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK;
+- if (ent->is_valid)
+- *fwd_entry |= ARLTBL_VALID;
+- if (ent->is_static)
+- *fwd_entry |= ARLTBL_STATIC;
+- if (ent->is_age)
+- *fwd_entry |= ARLTBL_AGE;
++ if (is5325(dev) || is5365(dev)) {
++ *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)
++ *mac_vid |= ARLTBL_VALID_25;
++ if (ent->is_static)
++ *mac_vid |= ARLTBL_STATIC_25;
++ if (ent->is_age)
++ *mac_vid |= ARLTBL_AGE_25;
++ } else {
++ *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S;
++ *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK;
++ if (ent->is_valid)
++ *fwd_entry |= ARLTBL_VALID;
++ if (ent->is_static)
++ *fwd_entry |= ARLTBL_STATIC;
++ if (ent->is_age)
++ *fwd_entry |= ARLTBL_AGE;
++ }
+ }
+
+ #ifdef CONFIG_BCM47XX
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -324,9 +324,10 @@
+ #define ARLTBL_VID_MASK 0xfff
+ #define ARLTBL_DATA_PORT_ID_S_25 48
+ #define ARLTBL_DATA_PORT_ID_MASK_25 0xf
+-#define ARLTBL_AGE_25 BIT(61)
+-#define ARLTBL_STATIC_25 BIT(62)
+-#define ARLTBL_VALID_25 BIT(63)
++#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)
+
+ /* ARL Table Data Entry N Registers (32 bit) */
+ #define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18)
diff --git a/target/linux/bmips/patches-6.12/131-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch b/target/linux/bmips/patches-6.12/131-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch
new file mode 100644
index 0000000000..2a70c431ff
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/131-net-dsa-b53-prevent-FAST_AGE-access-on-BCM5325.patch
@@ -0,0 +1,49 @@
+From b9441e624e39428f57baf30043aba225f02bfc73 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 22:44:47 +0200
+Subject: [PATCH] net: dsa: b53: prevent FAST_AGE access on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement FAST_AGE registers so we should avoid reading or
+writing them.
+
+Fixes: 967dd82ffc52 ("net: dsa: b53: Add support for Broadcom RoboSwitch")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -486,6 +486,9 @@ static int b53_flush_arl(struct b53_devi
+ {
+ unsigned int i;
+
++ if (is5325(dev))
++ return 0;
++
+ b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL,
+ FAST_AGE_DONE | FAST_AGE_DYNAMIC | mask);
+
+@@ -510,6 +513,9 @@ out:
+
+ static int b53_fast_age_port(struct b53_device *dev, int port)
+ {
++ if (is5325(dev))
++ return 0;
++
+ b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_PORT_CTRL, port);
+
+ return b53_flush_arl(dev, FAST_AGE_PORT);
+@@ -517,6 +523,9 @@ static int b53_fast_age_port(struct b53_
+
+ static int b53_fast_age_vlan(struct b53_device *dev, u16 vid)
+ {
++ if (is5325(dev))
++ return 0;
++
+ b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid);
+
+ return b53_flush_arl(dev, FAST_AGE_VLAN);
diff --git a/target/linux/bmips/patches-6.12/132-net-dsa-b53-prevent-SWITCH_CTRL-access-on-BCM5325.patch b/target/linux/bmips/patches-6.12/132-net-dsa-b53-prevent-SWITCH_CTRL-access-on-BCM5325.patch
new file mode 100644
index 0000000000..64d2cdf3ae
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/132-net-dsa-b53-prevent-SWITCH_CTRL-access-on-BCM5325.patch
@@ -0,0 +1,37 @@
+From 8cece037d71dd2464b7405871d5ba34d28695940 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 22:57:06 +0200
+Subject: [PATCH] net: dsa: b53: prevent SWITCH_CTRL access on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement SWITCH_CTRL register so we should avoid reading
+or writing it.
+
+Fixes: a424f0de6163 ("net: dsa: b53: Include IMP/CPU port in dumb forwarding mode")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -360,11 +360,12 @@ static void b53_set_forwarding(struct b5
+
+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
+
+- /* Include IMP port in dumb forwarding mode
+- */
+- b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt);
+- mgmt |= B53_MII_DUMB_FWDG_EN;
+- b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
++ if (!is5325(dev)) {
++ /* Include IMP port in dumb forwarding mode */
++ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt);
++ mgmt |= B53_MII_DUMB_FWDG_EN;
++ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
++ }
+
+ /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether
+ * frames should be flooded or not.
diff --git a/target/linux/bmips/patches-6.12/133-net-dsa-b53-fix-IP_MULTICAST_CTRL-on-BCM5325.patch b/target/linux/bmips/patches-6.12/133-net-dsa-b53-fix-IP_MULTICAST_CTRL-on-BCM5325.patch
new file mode 100644
index 0000000000..437f132b2c
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/133-net-dsa-b53-fix-IP_MULTICAST_CTRL-on-BCM5325.patch
@@ -0,0 +1,50 @@
+From 85499f7068e67f82194170412617591d3d23a123 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 23:00:55 +0200
+Subject: [PATCH] net: dsa: b53: fix IP_MULTICAST_CTRL on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement B53_UC_FWD_EN, B53_MC_FWD_EN or B53_IPMC_FWD_EN.
+
+Fixes: 53568438e381 ("net: dsa: b53: Add support for port_egress_floods callback")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 13 +++++++++----
+ drivers/net/dsa/b53/b53_regs.h | 1 +
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -367,11 +367,16 @@ static void b53_set_forwarding(struct b5
+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
+ }
+
+- /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether
+- * frames should be flooded or not.
+- */
+ b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt);
+- mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN;
++ if (is5325(dev)) {
++ /* Enable IP multicast address scheme. */
++ mgmt |= B53_IP_MCAST_25;
++ } else {
++ /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether
++ * frames should be flooded or not.
++ */
++ mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN;
++ }
+ b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt);
+ }
+
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -106,6 +106,7 @@
+
+ /* IP Multicast control (8 bit) */
+ #define B53_IP_MULTICAST_CTRL 0x21
++#define B53_IP_MCAST_25 BIT(0)
+ #define B53_IPMC_FWD_EN BIT(1)
+ #define B53_UC_FWD_EN BIT(6)
+ #define B53_MC_FWD_EN BIT(7)
diff --git a/target/linux/bmips/patches-6.12/134-net-dsa-b53-prevent-DIS_LEARNING-access-on-BCM5325.patch b/target/linux/bmips/patches-6.12/134-net-dsa-b53-prevent-DIS_LEARNING-access-on-BCM5325.patch
new file mode 100644
index 0000000000..e08308ffa9
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/134-net-dsa-b53-prevent-DIS_LEARNING-access-on-BCM5325.patch
@@ -0,0 +1,29 @@
+From 077a4a60a89a0423295a8e5684f7f36bc4b0bc72 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 23:13:01 +0200
+Subject: [PATCH] net: dsa: b53: prevent DIS_LEARNING access on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement DIS_LEARNING register so we should avoid reading
+or writing it.
+
+Fixes: f9b3827ee66c ("net: dsa: b53: Support setting learning on port")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -593,6 +593,9 @@ static void b53_port_set_learning(struct
+ {
+ u16 reg;
+
++ if (is5325(dev))
++ return;
++
+ b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, ®);
+ if (learning)
+ reg &= ~BIT(port);
diff --git a/target/linux/bmips/patches-6.12/135-net-dsa-b53-prevent-BRCM_HDR-access-on-BCM5325.patch b/target/linux/bmips/patches-6.12/135-net-dsa-b53-prevent-BRCM_HDR-access-on-BCM5325.patch
new file mode 100644
index 0000000000..9fc827bdbf
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/135-net-dsa-b53-prevent-BRCM_HDR-access-on-BCM5325.patch
@@ -0,0 +1,30 @@
+From 171f3a42be30e2a62c6590ec2b0e5a96ddad57a0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 23:18:03 +0200
+Subject: [PATCH] net: dsa: b53: prevent BRCM_HDR access on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement BRCM_HDR register so we should avoid reading or
+writing it.
+
+Fixes: b409a9efa183 ("net: dsa: b53: Move Broadcom header setup to b53")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -730,6 +730,10 @@ void b53_brcm_hdr_setup(struct dsa_switc
+ hdr_ctl |= GC_FRM_MGMT_PORT_M;
+ b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl);
+
++ /* B53_BRCM_HDR not present on BCM5325 */
++ if (is5325(dev))
++ return;
++
+ /* Enable Broadcom tags for IMP port */
+ b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl);
+ if (tag_en)
diff --git a/target/linux/bmips/patches-6.12/136-net-dsa-b53-prevent-GMII_PORT_OVERRIDE_CTRL-access-o.patch b/target/linux/bmips/patches-6.12/136-net-dsa-b53-prevent-GMII_PORT_OVERRIDE_CTRL-access-o.patch
new file mode 100644
index 0000000000..90ef4c9785
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/136-net-dsa-b53-prevent-GMII_PORT_OVERRIDE_CTRL-access-o.patch
@@ -0,0 +1,75 @@
+From d2dceddf182520b474d2aab0798d925e47a68c5a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Fri, 30 May 2025 23:33:13 +0200
+Subject: [PATCH] net: dsa: b53: prevent GMII_PORT_OVERRIDE_CTRL access on
+ BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement GMII_PORT_OVERRIDE_CTRL register so we should
+avoid reading or writing it.
+PORT_OVERRIDE_RX_FLOW and PORT_OVERRIDE_TX_FLOW aren't defined on BCM5325
+and we should use PORT_OVERRIDE_LP_FLOW_25 instead.
+
+Fixes: 5e004460f874 ("net: dsa: b53: Add helper to set link parameters")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 21 +++++++++++++++++----
+ drivers/net/dsa/b53/b53_regs.h | 1 +
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1278,6 +1278,8 @@ static void b53_force_link(struct b53_de
+ if (port == dev->imp_port) {
+ off = B53_PORT_OVERRIDE_CTRL;
+ val = PORT_OVERRIDE_EN;
++ } else if (is5325(dev)) {
++ return;
+ } else {
+ off = B53_GMII_PORT_OVERRIDE_CTRL(port);
+ val = GMII_PO_EN;
+@@ -1302,6 +1304,8 @@ static void b53_force_port_config(struct
+ if (port == dev->imp_port) {
+ off = B53_PORT_OVERRIDE_CTRL;
+ val = PORT_OVERRIDE_EN;
++ } else if (is5325(dev)) {
++ return;
+ } else {
+ off = B53_GMII_PORT_OVERRIDE_CTRL(port);
+ val = GMII_PO_EN;
+@@ -1332,10 +1336,19 @@ static void b53_force_port_config(struct
+ return;
+ }
+
+- if (rx_pause)
+- reg |= PORT_OVERRIDE_RX_FLOW;
+- if (tx_pause)
+- reg |= PORT_OVERRIDE_TX_FLOW;
++ if (rx_pause) {
++ if (is5325(dev))
++ reg |= PORT_OVERRIDE_LP_FLOW_25;
++ else
++ reg |= PORT_OVERRIDE_RX_FLOW;
++ }
++
++ if (tx_pause) {
++ if (is5325(dev))
++ reg |= PORT_OVERRIDE_LP_FLOW_25;
++ else
++ reg |= PORT_OVERRIDE_TX_FLOW;
++ }
+
+ b53_write8(dev, B53_CTRL_PAGE, off, reg);
+ }
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -95,6 +95,7 @@
+ #define PORT_OVERRIDE_SPEED_10M (0 << PORT_OVERRIDE_SPEED_S)
+ #define PORT_OVERRIDE_SPEED_100M (1 << PORT_OVERRIDE_SPEED_S)
+ #define PORT_OVERRIDE_SPEED_1000M (2 << PORT_OVERRIDE_SPEED_S)
++#define PORT_OVERRIDE_LP_FLOW_25 BIT(3) /* BCM5325 only */
+ #define PORT_OVERRIDE_RV_MII_25 BIT(4) /* BCM5325 only */
+ #define PORT_OVERRIDE_RX_FLOW BIT(4)
+ #define PORT_OVERRIDE_TX_FLOW BIT(5)
diff --git a/target/linux/bmips/patches-6.12/137-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM532.patch b/target/linux/bmips/patches-6.12/137-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM532.patch
new file mode 100644
index 0000000000..fe57bbf33b
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/137-net-dsa-b53-fix-unicast-multicast-flooding-on-BCM532.patch
@@ -0,0 +1,190 @@
+From 1124bbbad49e1a657cb12dd6ab938fcb3035e872 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Sat, 31 May 2025 09:31:55 +0200
+Subject: [PATCH] net: dsa: b53: fix unicast/multicast flooding on BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK
+registers.
+This has to be handled differently with other pages and registers.
+
+Fixes: a8b659e7ff75 ("net: dsa: act as passthrough for bridge port flags")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 85 +++++++++++++++++++++++++-------
+ drivers/net/dsa/b53/b53_regs.h | 38 ++++++++++++++
+ 2 files changed, 105 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -560,12 +560,36 @@ static void b53_port_set_ucast_flood(str
+ {
+ u16 uc;
+
+- b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
+- if (unicast)
+- uc |= BIT(port);
+- else
+- uc &= ~BIT(port);
+- b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
++ if (is5325(dev)) {
++ u8 rc;
++
++ if (port == B53_CPU_PORT_25)
++ port = B53_CPU_PORT;
++
++ b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, &uc);
++ if (unicast)
++ uc |= BIT(port) | B53_IEEE_UCAST_DROP_EN;
++ else
++ uc &= ~BIT(port);
++ b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, uc);
++
++ if (port >= B53_CPU_PORT_25)
++ return;
++
++ b53_read8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), &rc);
++ if (unicast)
++ rc |= (RC_DLF_EN | RC_BKT_SIZE_8K | RC_PERCENT_40);
++ else
++ rc &= ~(RC_DLF_EN);
++ b53_write8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), rc);
++ } else {
++ b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc);
++ if (unicast)
++ uc |= BIT(port);
++ else
++ uc &= ~BIT(port);
++ b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc);
++ }
+ }
+
+ static void b53_port_set_mcast_flood(struct b53_device *dev, int port,
+@@ -573,19 +597,44 @@ static void b53_port_set_mcast_flood(str
+ {
+ u16 mc;
+
+- b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
+- if (multicast)
+- mc |= BIT(port);
+- else
+- mc &= ~BIT(port);
+- b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
+-
+- b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
+- if (multicast)
+- mc |= BIT(port);
+- else
+- mc &= ~BIT(port);
+- b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
++ if (is5325(dev)) {
++ u8 rc;
++
++ if (port == B53_CPU_PORT_25)
++ port = B53_CPU_PORT;
++
++ b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, &mc);
++ if (multicast)
++ mc |= BIT(port) | B53_IEEE_MCAST_DROP_EN;
++ else
++ mc &= ~BIT(port);
++ b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, mc);
++
++ if (port >= B53_CPU_PORT_25)
++ return;
++
++ b53_read8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), &rc);
++ if (multicast)
++ rc |= (RC_BCAST_EN | RC_MCAST_EN | RC_BKT_SIZE_8K |
++ RC_PERCENT_40);
++ else
++ rc &= ~(RC_BCAST_EN | RC_MCAST_EN);
++ b53_write8(dev, B53_RATE_CTL_PAGE, B53_RATE_CONTROL(port), rc);
++ } else {
++ b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc);
++ if (multicast)
++ mc |= BIT(port);
++ else
++ mc &= ~BIT(port);
++ b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc);
++
++ b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc);
++ if (multicast)
++ mc |= BIT(port);
++ else
++ mc &= ~BIT(port);
++ b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc);
++ }
+ }
+
+ static void b53_port_set_learning(struct b53_device *dev, int port,
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -29,6 +29,7 @@
+ #define B53_ARLIO_PAGE 0x05 /* ARL Access */
+ #define B53_FRAMEBUF_PAGE 0x06 /* Management frame access */
+ #define B53_MEM_ACCESS_PAGE 0x08 /* Memory access */
++#define B53_IEEE_PAGE 0x0a /* IEEE 802.1X */
+
+ /* PHY Registers */
+ #define B53_PORT_MII_PAGE(i) (0x10 + (i)) /* Port i MII Registers */
+@@ -47,6 +48,9 @@
+ /* VLAN Registers */
+ #define B53_VLAN_PAGE 0x34
+
++/* Rate Control Registers */
++#define B53_RATE_CTL_PAGE 0x35
++
+ /* Jumbo Frame Registers */
+ #define B53_JUMBO_PAGE 0x40
+
+@@ -369,6 +373,18 @@
+ #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
+
+ /*************************************************************************
++ * IEEE 802.1X Registers
++ *************************************************************************/
++
++/* Multicast DLF Drop Control register (16 bit) */
++#define B53_IEEE_MCAST_DLF 0x94
++#define B53_IEEE_MCAST_DROP_EN BIT(11)
++
++/* Unicast DLF Drop Control register (16 bit) */
++#define B53_IEEE_UCAST_DLF 0x96
++#define B53_IEEE_UCAST_DROP_EN BIT(11)
++
++/*************************************************************************
+ * Port VLAN Registers
+ *************************************************************************/
+
+@@ -479,6 +495,28 @@
+ #define B53_VLAN_PORT_DEF_TAG(i) (0x10 + 2 * (i))
+
+ /*************************************************************************
++ * Rate Control Page Registers
++ *************************************************************************/
++
++#define B53_RATE_CONTROL(i) (0x00 + (i))
++#define RC_PERCENT_S 0
++#define RC_PERCENT_10 (0 << RC_PERCENT_S)
++#define RC_PERCENT_20 (1 << RC_PERCENT_S)
++#define RC_PERCENT_30 (2 << RC_PERCENT_S)
++#define RC_PERCENT_40 (3 << RC_PERCENT_S)
++#define RC_PERCENT_MASK (3 << RC_PERCENT_S)
++#define RC_BKT_SIZE_S 2
++#define RC_BKT_SIZE_2K (0 << RC_BKT_SIZE_S)
++#define RC_BKT_SIZE_4K (1 << RC_BKT_SIZE_S)
++#define RC_BKT_SIZE_6K (2 << RC_BKT_SIZE_S)
++#define RC_BKT_SIZE_8K (3 << RC_BKT_SIZE_S)
++#define RC_BKT_SIZE_MASK (3 << RC_BKT_SIZE_S)
++#define RC_DLF_EN BIT(4)
++#define RC_BCAST_EN BIT(5)
++#define RC_MCAST_EN BIT(6)
++#define RC_DROP_FRAME BIT(7)
++
++/*************************************************************************
+ * Jumbo Frame Page Registers
+ *************************************************************************/
+
diff --git a/target/linux/bmips/patches-6.12/138-net-dsa-b53-fix-b53_imp_vlan_setup-for-BCM5325.patch b/target/linux/bmips/patches-6.12/138-net-dsa-b53-fix-b53_imp_vlan_setup-for-BCM5325.patch
new file mode 100644
index 0000000000..c1a0bc52c9
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/138-net-dsa-b53-fix-b53_imp_vlan_setup-for-BCM5325.patch
@@ -0,0 +1,30 @@
+From f5ad83d0a9ce63d0524c5838b7f3a7360bd647ec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Sat, 31 May 2025 11:11:42 +0200
+Subject: [PATCH] net: dsa: b53: fix b53_imp_vlan_setup for BCM5325
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CPU port should be B53_CPU_PORT instead of B53_CPU_PORT_25 for
+B53_PVLAN_PORT_MASK register.
+
+Fixes: ff39c2d68679 ("net: dsa: b53: Add bridge support")
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -543,6 +543,10 @@ void b53_imp_vlan_setup(struct dsa_switc
+ unsigned int i;
+ u16 pvlan;
+
++ /* BCM5325 CPU port is at 8 */
++ if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25)
++ cpu_port = B53_CPU_PORT;
++
+ /* Enable the IMP port to be in the same VLAN as the other ports
+ * on a per-port basis such that we only have Port i and IMP in
+ * the same VLAN.
diff --git a/target/linux/bmips/patches-6.12/139-net-dsa-b53-ensure-BCM5325-PHYs-are-enabled.patch b/target/linux/bmips/patches-6.12/139-net-dsa-b53-ensure-BCM5325-PHYs-are-enabled.patch
new file mode 100644
index 0000000000..7491b6cbbc
--- /dev/null
+++ b/target/linux/bmips/patches-6.12/139-net-dsa-b53-ensure-BCM5325-PHYs-are-enabled.patch
@@ -0,0 +1,28 @@
+From 48d5f0b6bbead8e62647a94c18f23be931bcf7b0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari at gmail.com>
+Date: Sat, 31 May 2025 11:20:13 +0200
+Subject: [PATCH] net: dsa: b53: ensure BCM5325 PHYs are enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+According to the datasheet, BCM5325 uses B53_PD_MODE_CTRL_25 register to
+disable clocking to individual PHYs.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
+---
+ drivers/net/dsa/b53/b53_common.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1299,6 +1299,9 @@ static int b53_setup(struct dsa_switch *
+
+ b53_reset_mib(dev);
+
++ if (is5325(dev))
++ b53_write8(dev, B53_CTRL_PAGE, B53_PD_MODE_CTRL_25, 0);
++
+ ret = b53_apply_config(dev);
+ if (ret) {
+ dev_err(ds->dev, "failed to apply configuration\n");
More information about the lede-commits
mailing list