[openwrt/openwrt] generic: 6.12: backport b53 patches from netdev-next
LEDE Commits
lede-commits at lists.infradead.org
Fri Nov 21 12:43:29 PST 2025
noltari pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/08964109beb25127936b1d3e5729c208bb79a7b4
commit 08964109beb25127936b1d3e5729c208bb79a7b4
Author: Álvaro Fernández Rojas <noltari at gmail.com>
AuthorDate: Wed Nov 19 09:42:20 2025 +0100
generic: 6.12: backport b53 patches from netdev-next
These patches have been accepted in netdev-next for linux v6.19.
2b3013ac0302 net: dsa: b53: add support for bcm63xx ARL entry format
300f78e8b6b7 net: dsa: b53: add support for 5389/5397/5398 ARL entry format
a7e73339ad46 net: dsa: b53: move ARL entry functions into ops struct
e0c476f325a8 net: dsa: b53: split reading search entry into their own functions
1716be6db04a net: dsa: b53: provide accessors for accessing ARL_SRCH_CTL
bf6e9d2ae1db net: dsa: b53: move writing ARL entries into their own functions
4a291fe72267 net: dsa: b53: move reading ARL entries into their own function
a6e4fd38bf2f net: dsa: b53: b53_arl_read{,25}(): use the entry for comparision
Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
...arl_read-25-use-the-entry-for-comparision.patch | 85 +++++
...ading-ARL-entries-into-their-own-function.patch | 117 +++++++
...ting-ARL-entries-into-their-own-functions.patch | 93 ++++++
...vide-accessors-for-accessing-ARL_SRCH_CTL.patch | 85 +++++
...ing-search-entry-into-their-own-functions.patch | 86 +++++
...-move-ARL-entry-functions-into-ops-struct.patch | 348 +++++++++++++++++++++
...pport-for-5389-5397-5398-ARL-entry-format.patch | 221 +++++++++++++
...-add-support-for-bcm63xx-ARL-entry-format.patch | 177 +++++++++++
8 files changed, 1212 insertions(+)
diff --git a/target/linux/generic/backport-6.12/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch b/target/linux/generic/backport-6.12/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch
new file mode 100644
index 0000000000..2b6cff796f
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-01-v6.19-net-dsa-b53-b53_arl_read-25-use-the-entry-for-comparision.patch
@@ -0,0 +1,85 @@
+From a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:42 +0100
+Subject: [PATCH] net: dsa: b53: b53_arl_read{,25}(): use the entry for
+ comparision
+
+Align the b53_arl_read{,25}() functions by consistently using the
+parsed arl entry instead of parsing the raw registers again.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-2-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1830,7 +1830,7 @@ static int b53_arl_rw_op(struct b53_devi
+ return b53_arl_op_wait(dev);
+ }
+
+-static int b53_arl_read(struct b53_device *dev, u64 mac,
++static int b53_arl_read(struct b53_device *dev, const u8 *mac,
+ u16 vid, struct b53_arl_entry *ent, u8 *idx)
+ {
+ DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
+@@ -1854,14 +1854,13 @@ static int b53_arl_read(struct b53_devic
+ B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
+ b53_arl_to_entry(ent, mac_vid, fwd_entry);
+
+- if (!(fwd_entry & ARLTBL_VALID)) {
++ if (!ent->is_valid) {
+ set_bit(i, free_bins);
+ continue;
+ }
+- if ((mac_vid & ARLTBL_MAC_MASK) != mac)
++ if (!ether_addr_equal(ent->mac, mac))
+ continue;
+- if (dev->vlan_enabled &&
+- ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
++ if (dev->vlan_enabled && ent->vid != vid)
+ continue;
+ *idx = i;
+ return 0;
+@@ -1871,7 +1870,7 @@ static int b53_arl_read(struct b53_devic
+ return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
+ }
+
+-static int b53_arl_read_25(struct b53_device *dev, u64 mac,
++static int b53_arl_read_25(struct b53_device *dev, const u8 *mac,
+ u16 vid, struct b53_arl_entry *ent, u8 *idx)
+ {
+ DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
+@@ -1893,14 +1892,13 @@ static int b53_arl_read_25(struct b53_de
+
+ b53_arl_to_entry_25(ent, mac_vid);
+
+- if (!(mac_vid & ARLTBL_VALID_25)) {
++ if (!ent->is_valid) {
+ set_bit(i, free_bins);
+ continue;
+ }
+- if ((mac_vid & ARLTBL_MAC_MASK) != mac)
++ if (!ether_addr_equal(ent->mac, mac))
+ continue;
+- if (dev->vlan_enabled &&
+- ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid)
++ if (dev->vlan_enabled && ent->vid != vid)
+ continue;
+ *idx = i;
+ return 0;
+@@ -1933,9 +1931,9 @@ static int b53_arl_op(struct b53_device
+ return ret;
+
+ if (is5325(dev) || is5365(dev))
+- ret = b53_arl_read_25(dev, mac, vid, &ent, &idx);
++ ret = b53_arl_read_25(dev, addr, vid, &ent, &idx);
+ else
+- ret = b53_arl_read(dev, mac, vid, &ent, &idx);
++ ret = b53_arl_read(dev, addr, vid, &ent, &idx);
+
+ /* If this is a read, just finish now */
+ if (op)
diff --git a/target/linux/generic/backport-6.12/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch b/target/linux/generic/backport-6.12/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch
new file mode 100644
index 0000000000..8cf85ce7ad
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-02-v6.19-net-dsa-b53-move-reading-ARL-entries-into-their-own-function.patch
@@ -0,0 +1,117 @@
+From 4a291fe7226736a465ddb3fa93c21fcef7162ec7 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:43 +0100
+Subject: [PATCH] net: dsa: b53: move reading ARL entries into their own
+ function
+
+Instead of duplicating the whole code iterating over all bins for
+BCM5325, factor out reading and parsing the entry into its own
+functions, and name it the modern one after the first chip with that ARL
+format, (BCM53)95.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-3-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 69 +++++++++++---------------------
+ 1 file changed, 23 insertions(+), 46 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1830,48 +1830,30 @@ static int b53_arl_rw_op(struct b53_devi
+ return b53_arl_op_wait(dev);
+ }
+
+-static int b53_arl_read(struct b53_device *dev, const u8 *mac,
+- u16 vid, struct b53_arl_entry *ent, u8 *idx)
++static void b53_arl_read_entry_25(struct b53_device *dev,
++ struct b53_arl_entry *ent, u8 idx)
+ {
+- DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
+- unsigned int i;
+- int ret;
+-
+- ret = b53_arl_op_wait(dev);
+- if (ret)
+- return ret;
++ u64 mac_vid;
+
+- bitmap_zero(free_bins, dev->num_arl_bins);
+-
+- /* Read the bins */
+- for (i = 0; i < dev->num_arl_bins; i++) {
+- u64 mac_vid;
+- u32 fwd_entry;
+-
+- 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);
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
++ &mac_vid);
++ b53_arl_to_entry_25(ent, mac_vid);
++}
+
+- if (!ent->is_valid) {
+- set_bit(i, free_bins);
+- continue;
+- }
+- if (!ether_addr_equal(ent->mac, mac))
+- continue;
+- if (dev->vlan_enabled && ent->vid != vid)
+- continue;
+- *idx = i;
+- return 0;
+- }
++static void b53_arl_read_entry_95(struct b53_device *dev,
++ struct b53_arl_entry *ent, u8 idx)
++{
++ u32 fwd_entry;
++ u64 mac_vid;
+
+- *idx = find_first_bit(free_bins, dev->num_arl_bins);
+- return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT;
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
++ &mac_vid);
++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry);
++ b53_arl_to_entry(ent, mac_vid, fwd_entry);
+ }
+
+-static int b53_arl_read_25(struct b53_device *dev, const u8 *mac,
+- u16 vid, struct b53_arl_entry *ent, u8 *idx)
++static int b53_arl_read(struct b53_device *dev, const u8 *mac,
++ u16 vid, struct b53_arl_entry *ent, u8 *idx)
+ {
+ DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
+ unsigned int i;
+@@ -1885,12 +1867,10 @@ static int b53_arl_read_25(struct b53_de
+
+ /* Read the bins */
+ for (i = 0; i < dev->num_arl_bins; i++) {
+- u64 mac_vid;
+-
+- b53_read64(dev, B53_ARLIO_PAGE,
+- B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid);
+-
+- b53_arl_to_entry_25(ent, mac_vid);
++ if (is5325(dev) || is5365(dev))
++ b53_arl_read_entry_25(dev, ent, i);
++ else
++ b53_arl_read_entry_95(dev, ent, i);
+
+ if (!ent->is_valid) {
+ set_bit(i, free_bins);
+@@ -1930,10 +1910,7 @@ static int b53_arl_op(struct b53_device
+ if (ret)
+ return ret;
+
+- if (is5325(dev) || is5365(dev))
+- ret = b53_arl_read_25(dev, addr, vid, &ent, &idx);
+- else
+- ret = b53_arl_read(dev, addr, vid, &ent, &idx);
++ ret = b53_arl_read(dev, addr, vid, &ent, &idx);
+
+ /* If this is a read, just finish now */
+ if (op)
diff --git a/target/linux/generic/backport-6.12/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch b/target/linux/generic/backport-6.12/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch
new file mode 100644
index 0000000000..a171232d49
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-03-v6.19-net-dsa-b53-move-writing-ARL-entries-into-their-own-functions.patch
@@ -0,0 +1,93 @@
+From bf6e9d2ae1dbafee53ec4ccd126595172e1e5278 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:44 +0100
+Subject: [PATCH] net: dsa: b53: move writing ARL entries into their own
+ functions
+
+Move writing ARL entries into individual functions for each format.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-4-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 38 ++++++++++++++++++++++----------
+ 1 file changed, 26 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1840,6 +1840,16 @@ static void b53_arl_read_entry_25(struct
+ b53_arl_to_entry_25(ent, mac_vid);
+ }
+
++static void b53_arl_write_entry_25(struct b53_device *dev,
++ const struct b53_arl_entry *ent, u8 idx)
++{
++ u64 mac_vid;
++
++ b53_arl_from_entry_25(&mac_vid, ent);
++ b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
++ mac_vid);
++}
++
+ static void b53_arl_read_entry_95(struct b53_device *dev,
+ struct b53_arl_entry *ent, u8 idx)
+ {
+@@ -1852,6 +1862,19 @@ static void b53_arl_read_entry_95(struct
+ b53_arl_to_entry(ent, mac_vid, fwd_entry);
+ }
+
++static void b53_arl_write_entry_95(struct b53_device *dev,
++ const struct b53_arl_entry *ent, u8 idx)
++{
++ u32 fwd_entry;
++ u64 mac_vid;
++
++ b53_arl_from_entry(&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);
++}
++
+ static int b53_arl_read(struct b53_device *dev, const u8 *mac,
+ u16 vid, struct b53_arl_entry *ent, u8 *idx)
+ {
+@@ -1892,9 +1915,8 @@ static int b53_arl_op(struct b53_device
+ const unsigned char *addr, u16 vid, bool is_valid)
+ {
+ struct b53_arl_entry ent;
+- u32 fwd_entry;
+- u64 mac, mac_vid = 0;
+ u8 idx = 0;
++ u64 mac;
+ int ret;
+
+ /* Convert the array into a 64-bit MAC */
+@@ -1927,7 +1949,6 @@ static int b53_arl_op(struct b53_device
+ /* We could not find a matching MAC, so reset to a new entry */
+ dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
+ addr, vid, idx);
+- fwd_entry = 0;
+ break;
+ default:
+ dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
+@@ -1955,16 +1976,9 @@ static int b53_arl_op(struct b53_device
+ ent.is_age = false;
+ memcpy(ent.mac, addr, ETH_ALEN);
+ if (is5325(dev) || is5365(dev))
+- b53_arl_from_entry_25(&mac_vid, &ent);
++ b53_arl_write_entry_25(dev, &ent, idx);
+ else
+- b53_arl_from_entry(&mac_vid, &fwd_entry, &ent);
+-
+- b53_write64(dev, B53_ARLIO_PAGE,
+- B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
+-
+- if (!is5325(dev) && !is5365(dev))
+- b53_write32(dev, B53_ARLIO_PAGE,
+- B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
++ b53_arl_write_entry_95(dev, &ent, idx);
+
+ return b53_arl_rw_op(dev, 0);
+ }
diff --git a/target/linux/generic/backport-6.12/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch b/target/linux/generic/backport-6.12/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch
new file mode 100644
index 0000000000..2ed88e4605
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-04-v6.19-net-dsa-b53-provide-accessors-for-accessing-ARL_SRCH_CTL.patch
@@ -0,0 +1,85 @@
+From 1716be6db04af53bac9b869f01156a460595cf41 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:45 +0100
+Subject: [PATCH] net: dsa: b53: provide accessors for accessing ARL_SRCH_CTL
+
+In order to more easily support more formats, move accessing
+ARL_SRCH_CTL into helper functions to contain the differences.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-5-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 37 +++++++++++++++++++++-----------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2013,18 +2013,37 @@ int b53_fdb_del(struct dsa_switch *ds, i
+ }
+ EXPORT_SYMBOL(b53_fdb_del);
+
+-static int b53_arl_search_wait(struct b53_device *dev)
++static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val)
+ {
+- unsigned int timeout = 1000;
+- u8 reg, offset;
++ u8 offset;
++
++ if (is5325(dev) || is5365(dev))
++ offset = B53_ARL_SRCH_CTL_25;
++ else
++ offset = B53_ARL_SRCH_CTL;
++
++ b53_read8(dev, B53_ARLIO_PAGE, offset, val);
++}
++
++static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val)
++{
++ u8 offset;
+
+ if (is5325(dev) || is5365(dev))
+ offset = B53_ARL_SRCH_CTL_25;
+ else
+ offset = B53_ARL_SRCH_CTL;
+
++ b53_write8(dev, B53_ARLIO_PAGE, offset, val);
++}
++
++static int b53_arl_search_wait(struct b53_device *dev)
++{
++ unsigned int timeout = 1000;
++ u8 reg;
++
+ do {
+- b53_read8(dev, B53_ARLIO_PAGE, offset, ®);
++ b53_read_arl_srch_ctl(dev, ®);
+ if (!(reg & ARL_SRCH_STDN))
+ return -ENOENT;
+
+@@ -2079,23 +2098,15 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ unsigned int count = 0, results_per_hit = 1;
+ struct b53_device *priv = ds->priv;
+ struct b53_arl_entry results[2];
+- u8 offset;
+ int ret;
+- u8 reg;
+
+ if (priv->num_arl_bins > 2)
+ results_per_hit = 2;
+
+ 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, offset, reg);
++ b53_write_arl_srch_ctl(priv, ARL_SRCH_STDN);
+
+ do {
+ ret = b53_arl_search_wait(priv);
diff --git a/target/linux/generic/backport-6.12/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch b/target/linux/generic/backport-6.12/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch
new file mode 100644
index 0000000000..3e263f8cfb
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-05-v6.19-net-dsa-b53-split-reading-search-entry-into-their-own-functions.patch
@@ -0,0 +1,86 @@
+From e0c476f325a8c9b961a3d446c24d3c8ecae7d186 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:46 +0100
+Subject: [PATCH] net: dsa: b53: split reading search entry into their own
+ functions
+
+Split reading search entries into a function for each format.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-6-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 56 ++++++++++++++++++++++----------
+ 1 file changed, 38 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2056,28 +2056,48 @@ static int b53_arl_search_wait(struct b5
+ return -ETIMEDOUT;
+ }
+
+-static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
+- struct b53_arl_entry *ent)
++static void b53_arl_search_read_25(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent)
+ {
+ u64 mac_vid;
+
+- if (is5325(dev)) {
+- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
+- &mac_vid);
+- b53_arl_to_entry_25(ent, mac_vid);
+- } else if (is5365(dev)) {
+- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
+- &mac_vid);
+- b53_arl_to_entry_25(ent, mac_vid);
+- } else {
+- u32 fwd_entry;
+-
+- 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);
+- }
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
++ &mac_vid);
++ 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_95(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent)
++{
++ u32 fwd_entry;
++ u64 mac_vid;
++
++ 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);
++}
++
++static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent)
++{
++ if (is5325(dev))
++ b53_arl_search_read_25(dev, idx, ent);
++ else if (is5365(dev))
++ b53_arl_search_read_65(dev, idx, ent);
++ else
++ b53_arl_search_read_95(dev, idx, ent);
+ }
+
+ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
diff --git a/target/linux/generic/backport-6.12/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch b/target/linux/generic/backport-6.12/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch
new file mode 100644
index 0000000000..dfa902d048
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-06-v6.19-net-dsa-b53-move-ARL-entry-functions-into-ops-struct.patch
@@ -0,0 +1,348 @@
+From a7e73339ad46ade76d29fb6cc7d7854222608c26 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:47 +0100
+Subject: [PATCH] net: dsa: b53: move ARL entry functions into ops struct
+
+Now that the differences in ARL entry formats are neatly contained into
+functions per chip family, wrap them into an ops struct and add wrapper
+functions to access them.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-7-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 67 ++++++++++++++++++++++----------
+ drivers/net/dsa/b53/b53_priv.h | 30 ++++++++++++++
+ 2 files changed, 76 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1890,10 +1890,7 @@ static int b53_arl_read(struct b53_devic
+
+ /* Read the bins */
+ for (i = 0; i < dev->num_arl_bins; i++) {
+- if (is5325(dev) || is5365(dev))
+- b53_arl_read_entry_25(dev, ent, i);
+- else
+- b53_arl_read_entry_95(dev, ent, i);
++ b53_arl_read_entry(dev, ent, i);
+
+ if (!ent->is_valid) {
+ set_bit(i, free_bins);
+@@ -1975,10 +1972,7 @@ static int b53_arl_op(struct b53_device
+ ent.is_static = true;
+ ent.is_age = false;
+ memcpy(ent.mac, addr, ETH_ALEN);
+- if (is5325(dev) || is5365(dev))
+- b53_arl_write_entry_25(dev, &ent, idx);
+- else
+- b53_arl_write_entry_95(dev, &ent, idx);
++ b53_arl_write_entry(dev, &ent, idx);
+
+ return b53_arl_rw_op(dev, 0);
+ }
+@@ -2089,17 +2083,6 @@ static void b53_arl_search_read_95(struc
+ b53_arl_to_entry(ent, mac_vid, fwd_entry);
+ }
+
+-static void b53_arl_search_rd(struct b53_device *dev, u8 idx,
+- struct b53_arl_entry *ent)
+-{
+- if (is5325(dev))
+- b53_arl_search_read_25(dev, idx, ent);
+- else if (is5365(dev))
+- b53_arl_search_read_65(dev, idx, ent);
+- else
+- b53_arl_search_read_95(dev, idx, ent);
+-}
+-
+ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
+ dsa_fdb_dump_cb_t *cb, void *data)
+ {
+@@ -2133,13 +2116,13 @@ int b53_fdb_dump(struct dsa_switch *ds,
+ if (ret)
+ break;
+
+- b53_arl_search_rd(priv, 0, &results[0]);
++ b53_arl_search_read(priv, 0, &results[0]);
+ ret = b53_fdb_copy(port, &results[0], cb, data);
+ if (ret)
+ break;
+
+ if (results_per_hit == 2) {
+- b53_arl_search_rd(priv, 1, &results[1]);
++ b53_arl_search_read(priv, 1, &results[1]);
+ ret = b53_fdb_copy(port, &results[1], cb, data);
+ if (ret)
+ break;
+@@ -2672,6 +2655,24 @@ static const struct dsa_switch_ops b53_s
+ .port_change_mtu = b53_change_mtu,
+ };
+
++static const struct b53_arl_ops b53_arl_ops_25 = {
++ .arl_read_entry = b53_arl_read_entry_25,
++ .arl_write_entry = b53_arl_write_entry_25,
++ .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_95 = {
++ .arl_read_entry = b53_arl_read_entry_95,
++ .arl_write_entry = b53_arl_write_entry_95,
++ .arl_search_read = b53_arl_search_read_95,
++};
++
+ struct b53_chip_data {
+ u32 chip_id;
+ const char *dev_name;
+@@ -2685,6 +2686,7 @@ struct b53_chip_data {
+ u8 duplex_reg;
+ u8 jumbo_pm_reg;
+ u8 jumbo_size_reg;
++ const struct b53_arl_ops *arl_ops;
+ };
+
+ #define B53_VTA_REGS \
+@@ -2704,6 +2706,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_25,
+ },
+ {
+ .chip_id = BCM5365_DEVICE_ID,
+@@ -2714,6 +2717,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,
+ },
+ {
+ .chip_id = BCM5389_DEVICE_ID,
+@@ -2727,6 +2731,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM5395_DEVICE_ID,
+@@ -2740,6 +2745,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM5397_DEVICE_ID,
+@@ -2753,6 +2759,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM5398_DEVICE_ID,
+@@ -2766,6 +2773,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53101_DEVICE_ID,
+@@ -2779,6 +2787,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53115_DEVICE_ID,
+@@ -2792,6 +2801,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53125_DEVICE_ID,
+@@ -2805,6 +2815,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53128_DEVICE_ID,
+@@ -2818,6 +2829,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM63XX_DEVICE_ID,
+@@ -2831,6 +2843,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_63XX,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53010_DEVICE_ID,
+@@ -2844,6 +2857,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53011_DEVICE_ID,
+@@ -2857,6 +2871,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53012_DEVICE_ID,
+@@ -2870,6 +2885,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53018_DEVICE_ID,
+@@ -2883,6 +2899,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53019_DEVICE_ID,
+@@ -2896,6 +2913,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM58XX_DEVICE_ID,
+@@ -2909,6 +2927,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM583XX_DEVICE_ID,
+@@ -2922,6 +2941,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ /* Starfighter 2 */
+ {
+@@ -2936,6 +2956,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM7445_DEVICE_ID,
+@@ -2949,6 +2970,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM7278_DEVICE_ID,
+@@ -2962,6 +2984,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ {
+ .chip_id = BCM53134_DEVICE_ID,
+@@ -2976,6 +2999,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
++ .arl_ops = &b53_arl_ops_95,
+ },
+ };
+
+@@ -3004,6 +3028,7 @@ static int b53_switch_init(struct b53_de
+ dev->num_vlans = chip->vlans;
+ dev->num_arl_bins = chip->arl_bins;
+ dev->num_arl_buckets = chip->arl_buckets;
++ dev->arl_ops = chip->arl_ops;
+ break;
+ }
+ }
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -58,6 +58,17 @@ struct b53_io_ops {
+ bool link_up);
+ };
+
++struct b53_arl_entry;
++
++struct b53_arl_ops {
++ void (*arl_read_entry)(struct b53_device *dev,
++ struct b53_arl_entry *ent, u8 idx);
++ void (*arl_write_entry)(struct b53_device *dev,
++ const struct b53_arl_entry *ent, u8 idx);
++ void (*arl_search_read)(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent);
++};
++
+ #define B53_INVALID_LANE 0xff
+
+ enum {
+@@ -127,6 +138,7 @@ struct b53_device {
+ struct mutex stats_mutex;
+ struct mutex arl_mutex;
+ const struct b53_io_ops *ops;
++ const struct b53_arl_ops *arl_ops;
+
+ /* chip specific data */
+ u32 chip_id;
+@@ -371,6 +383,24 @@ static inline void b53_arl_from_entry_25
+ *mac_vid |= ARLTBL_AGE_25;
+ }
+
++static inline void b53_arl_read_entry(struct b53_device *dev,
++ struct b53_arl_entry *ent, u8 idx)
++{
++ dev->arl_ops->arl_read_entry(dev, ent, idx);
++}
++
++static inline void b53_arl_write_entry(struct b53_device *dev,
++ const struct b53_arl_entry *ent, u8 idx)
++{
++ dev->arl_ops->arl_write_entry(dev, ent, idx);
++}
++
++static inline void b53_arl_search_read(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent)
++{
++ dev->arl_ops->arl_search_read(dev, idx, ent);
++}
++
+ #ifdef CONFIG_BCM47XX
+
+ #include <linux/bcm47xx_nvram.h>
diff --git a/target/linux/generic/backport-6.12/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch b/target/linux/generic/backport-6.12/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch
new file mode 100644
index 0000000000..f87a78355e
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-07-v6.19-net-dsa-b53-add-support-for-5389-5397-5398-ARL-entry-format.patch
@@ -0,0 +1,221 @@
+From 300f78e8b6b7be17c2c78afeded75be68acb1aa7 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:48 +0100
+Subject: [PATCH] net: dsa: b53: add support for 5389/5397/5398 ARL entry
+ format
+
+BCM5389, BCM5397 and BCM5398 use a different ARL entry format with just
+a 16 bit fwdentry register, as well as different search control and data
+offsets.
+
+So add appropriate ops for them and switch those chips to use them.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-8-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 53 ++++++++++++++++++++++++++++++--
+ drivers/net/dsa/b53/b53_priv.h | 26 ++++++++++++++++
+ drivers/net/dsa/b53/b53_regs.h | 13 ++++++++
+ 3 files changed, 89 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1850,6 +1850,31 @@ static void b53_arl_write_entry_25(struc
+ mac_vid);
+ }
+
++static void b53_arl_read_entry_89(struct b53_device *dev,
++ struct b53_arl_entry *ent, u8 idx)
++{
++ u64 mac_vid;
++ u16 fwd_entry;
++
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
++ &mac_vid);
++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry);
++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
++}
++
++static void b53_arl_write_entry_89(struct b53_device *dev,
++ const struct b53_arl_entry *ent, u8 idx)
++{
++ u32 fwd_entry;
++ u64 mac_vid;
++
++ b53_arl_from_entry_89(&mac_vid, &fwd_entry, ent);
++ b53_write64(dev, B53_ARLIO_PAGE,
++ B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid);
++ b53_write16(dev, B53_ARLIO_PAGE,
++ B53_ARLTBL_DATA_ENTRY(idx), fwd_entry);
++}
++
+ static void b53_arl_read_entry_95(struct b53_device *dev,
+ struct b53_arl_entry *ent, u8 idx)
+ {
+@@ -2013,6 +2038,8 @@ static void b53_read_arl_srch_ctl(struct
+
+ if (is5325(dev) || is5365(dev))
+ offset = B53_ARL_SRCH_CTL_25;
++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
++ offset = B53_ARL_SRCH_CTL_89;
+ else
+ offset = B53_ARL_SRCH_CTL;
+
+@@ -2025,6 +2052,8 @@ static void b53_write_arl_srch_ctl(struc
+
+ if (is5325(dev) || is5365(dev))
+ offset = B53_ARL_SRCH_CTL_25;
++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
++ offset = B53_ARL_SRCH_CTL_89;
+ else
+ offset = B53_ARL_SRCH_CTL;
+
+@@ -2070,6 +2099,18 @@ static void b53_arl_search_read_65(struc
+ 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)
++{
++ u16 fwd_entry;
++ u64 mac_vid;
++
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_89,
++ &mac_vid);
++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_89, &fwd_entry);
++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
++}
++
+ static void b53_arl_search_read_95(struct b53_device *dev, u8 idx,
+ struct b53_arl_entry *ent)
+ {
+@@ -2667,6 +2708,12 @@ static const struct b53_arl_ops b53_arl_
+ .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,
++ .arl_search_read = b53_arl_search_read_89,
++};
++
+ static const struct b53_arl_ops b53_arl_ops_95 = {
+ .arl_read_entry = b53_arl_read_entry_95,
+ .arl_write_entry = b53_arl_write_entry_95,
+@@ -2731,7 +2778,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+- .arl_ops = &b53_arl_ops_95,
++ .arl_ops = &b53_arl_ops_89,
+ },
+ {
+ .chip_id = BCM5395_DEVICE_ID,
+@@ -2759,7 +2806,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+- .arl_ops = &b53_arl_ops_95,
++ .arl_ops = &b53_arl_ops_89,
+ },
+ {
+ .chip_id = BCM5398_DEVICE_ID,
+@@ -2773,7 +2820,7 @@ static const struct b53_chip_data b53_sw
+ .duplex_reg = B53_DUPLEX_STAT_GE,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+- .arl_ops = &b53_arl_ops_95,
++ .arl_ops = &b53_arl_ops_89,
+ },
+ {
+ .chip_id = BCM53101_DEVICE_ID,
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -353,6 +353,18 @@ static inline void b53_arl_to_entry_25(s
+ ent->vid = mac_vid >> ARLTBL_VID_S_65;
+ }
+
++static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
++ u64 mac_vid, u16 fwd_entry)
++{
++ memset(ent, 0, sizeof(*ent));
++ ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK_89;
++ ent->is_valid = !!(fwd_entry & ARLTBL_VALID_89);
++ ent->is_age = !!(fwd_entry & ARLTBL_AGE_89);
++ ent->is_static = !!(fwd_entry & ARLTBL_STATIC_89);
++ 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,
+ const struct b53_arl_entry *ent)
+ {
+@@ -383,6 +395,20 @@ static inline void b53_arl_from_entry_25
+ *mac_vid |= ARLTBL_AGE_25;
+ }
+
++static inline void b53_arl_from_entry_89(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_89;
++ if (ent->is_valid)
++ *fwd_entry |= ARLTBL_VALID_89;
++ if (ent->is_static)
++ *fwd_entry |= ARLTBL_STATIC_89;
++ if (ent->is_age)
++ *fwd_entry |= ARLTBL_AGE_89;
++}
++
+ static inline void b53_arl_read_entry(struct b53_device *dev,
+ struct b53_arl_entry *ent, u8 idx)
+ {
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -342,12 +342,20 @@
+ #define ARLTBL_STATIC BIT(15)
+ #define ARLTBL_VALID BIT(16)
+
++/* BCM5389 ARL Table Data Entry N Register format (16 bit) */
++#define ARLTBL_DATA_PORT_ID_MASK_89 GENMASK(8, 0)
++#define ARLTBL_TC_MASK_89 GENMASK(12, 10)
++#define ARLTBL_AGE_89 BIT(13)
++#define ARLTBL_STATIC_89 BIT(14)
++#define ARLTBL_VALID_89 BIT(15)
++
+ /* Maximum number of bin entries in the ARL for all switches */
+ #define B53_ARLTBL_MAX_BIN_ENTRIES 4
+
+ /* ARL Search Control Register (8 bit) */
+ #define B53_ARL_SRCH_CTL 0x50
+ #define B53_ARL_SRCH_CTL_25 0x20
++#define B53_ARL_SRCH_CTL_89 0x30
+ #define ARL_SRCH_VLID BIT(0)
+ #define ARL_SRCH_STDN BIT(7)
+
+@@ -355,10 +363,12 @@
+ #define B53_ARL_SRCH_ADDR 0x51
+ #define B53_ARL_SRCH_ADDR_25 0x22
+ #define B53_ARL_SRCH_ADDR_65 0x24
++#define B53_ARL_SRCH_ADDR_89 0x31
+ #define ARL_ADDR_MASK GENMASK(14, 0)
+
+ /* ARL Search MAC/VID Result (64 bit) */
+ #define B53_ARL_SRCH_RSTL_0_MACVID 0x60
++#define B53_ARL_SRCH_RSLT_MACVID_89 0x33
+
+ /* Single register search result on 5325 */
+ #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
+@@ -368,6 +378,9 @@
+ /* ARL Search Data Result (32 bit) */
+ #define B53_ARL_SRCH_RSTL_0 0x68
+
++/* BCM5389 ARL Search Data Result (16 bit) */
++#define B53_ARL_SRCH_RSLT_89 0x3b
++
+ #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10))
+ #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
+
diff --git a/target/linux/generic/backport-6.12/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch b/target/linux/generic/backport-6.12/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch
new file mode 100644
index 0000000000..33aab1144d
--- /dev/null
+++ b/target/linux/generic/backport-6.12/612-08-v6.19-net-dsa-b53-add-support-for-bcm63xx-ARL-entry-format.patch
@@ -0,0 +1,177 @@
+From 2b3013ac03028a2364d8779719bb6bfbc0212435 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski at gmail.com>
+Date: Fri, 7 Nov 2025 09:07:49 +0100
+Subject: [PATCH] net: dsa: b53: add support for bcm63xx ARL entry format
+
+The ARL registers of BCM63XX embedded switches are somewhat unique. The
+normal ARL table access registers have the same format as BCM5389, but
+the ARL search registers differ:
+
+* SRCH_CTL is at the same offset of BCM5389, but 16 bits wide. It does
+ not have more fields, just needs to be accessed by a 16 bit read.
+* SRCH_RSLT_MACVID and SRCH_RSLT are aligned to 32 bit, and have shifted
+ offsets.
+* SRCH_RSLT has a different format than the normal ARL data entry
+ register.
+* There is only one set of ENTRY_N registers, implying a 1 bin layout.
+
+So add appropriate ops for bcm63xx and let it use it.
+
+Signed-off-by: Jonas Gorski <jonas.gorski at gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli at broadcom.com>
+Link: https://patch.msgid.link/20251107080749.26936-9-jonas.gorski@gmail.com
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/dsa/b53/b53_common.c | 44 +++++++++++++++++++++++++++-----
+ drivers/net/dsa/b53/b53_priv.h | 15 +++++++++++
+ drivers/net/dsa/b53/b53_regs.h | 9 +++++++
+ 3 files changed, 61 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2038,12 +2038,20 @@ static void b53_read_arl_srch_ctl(struct
+
+ if (is5325(dev) || is5365(dev))
+ offset = B53_ARL_SRCH_CTL_25;
+- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) ||
++ is63xx(dev))
+ offset = B53_ARL_SRCH_CTL_89;
+ else
+ offset = B53_ARL_SRCH_CTL;
+
+- b53_read8(dev, B53_ARLIO_PAGE, offset, val);
++ if (is63xx(dev)) {
++ u16 val16;
++
++ b53_read16(dev, B53_ARLIO_PAGE, offset, &val16);
++ *val = val16 & 0xff;
++ } else {
++ b53_read8(dev, B53_ARLIO_PAGE, offset, val);
++ }
+ }
+
+ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val)
+@@ -2052,12 +2060,16 @@ static void b53_write_arl_srch_ctl(struc
+
+ if (is5325(dev) || is5365(dev))
+ offset = B53_ARL_SRCH_CTL_25;
+- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev))
++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) ||
++ is63xx(dev))
+ offset = B53_ARL_SRCH_CTL_89;
+ else
+ offset = B53_ARL_SRCH_CTL;
+
+- b53_write8(dev, B53_ARLIO_PAGE, offset, val);
++ if (is63xx(dev))
++ b53_write16(dev, B53_ARLIO_PAGE, offset, val);
++ else
++ b53_write8(dev, B53_ARLIO_PAGE, offset, val);
+ }
+
+ static int b53_arl_search_wait(struct b53_device *dev)
+@@ -2111,6 +2123,18 @@ static void b53_arl_search_read_89(struc
+ b53_arl_to_entry_89(ent, mac_vid, fwd_entry);
+ }
+
++static void b53_arl_search_read_63xx(struct b53_device *dev, u8 idx,
++ struct b53_arl_entry *ent)
++{
++ u16 fwd_entry;
++ u64 mac_vid;
++
++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_63XX,
++ &mac_vid);
++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_63XX, &fwd_entry);
++ b53_arl_search_to_entry_63xx(ent, mac_vid, fwd_entry);
++}
++
+ static void b53_arl_search_read_95(struct b53_device *dev, u8 idx,
+ struct b53_arl_entry *ent)
+ {
+@@ -2714,6 +2738,12 @@ static const struct b53_arl_ops b53_arl_
+ .arl_search_read = b53_arl_search_read_89,
+ };
+
++static const struct b53_arl_ops b53_arl_ops_63xx = {
++ .arl_read_entry = b53_arl_read_entry_89,
++ .arl_write_entry = b53_arl_write_entry_89,
++ .arl_search_read = b53_arl_search_read_63xx,
++};
++
+ static const struct b53_arl_ops b53_arl_ops_95 = {
+ .arl_read_entry = b53_arl_read_entry_95,
+ .arl_write_entry = b53_arl_write_entry_95,
+@@ -2883,14 +2913,14 @@ static const struct b53_chip_data b53_sw
+ .dev_name = "BCM63xx",
+ .vlans = 4096,
+ .enabled_ports = 0, /* pdata must provide them */
+- .arl_bins = 4,
+- .arl_buckets = 1024,
++ .arl_bins = 1,
++ .arl_buckets = 4096,
+ .imp_port = 8,
+ .vta_regs = B53_VTA_REGS_63XX,
+ .duplex_reg = B53_DUPLEX_STAT_63XX,
+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
+- .arl_ops = &b53_arl_ops_95,
++ .arl_ops = &b53_arl_ops_63xx,
+ },
+ {
+ .chip_id = BCM53010_DEVICE_ID,
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -409,6 +409,21 @@ static inline void b53_arl_from_entry_89
+ *fwd_entry |= ARLTBL_AGE_89;
+ }
+
++static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
++ u64 mac_vid, u16 fwd_entry)
++{
++ memset(ent, 0, sizeof(*ent));
++ u64_to_ether_addr(mac_vid, ent->mac);
++ ent->vid = mac_vid >> ARLTBL_VID_S;
++
++ ent->port = fwd_entry & ARL_SRST_PORT_ID_MASK_63XX;
++ ent->port >>= 1;
++
++ ent->is_age = !!(fwd_entry & ARL_SRST_AGE_63XX);
++ ent->is_static = !!(fwd_entry & ARL_SRST_STATIC_63XX);
++ ent->is_valid = 1;
++}
++
+ static inline void b53_arl_read_entry(struct b53_device *dev,
+ struct b53_arl_entry *ent, u8 idx)
+ {
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -364,11 +364,13 @@
+ #define B53_ARL_SRCH_ADDR_25 0x22
+ #define B53_ARL_SRCH_ADDR_65 0x24
+ #define B53_ARL_SRCH_ADDR_89 0x31
++#define B53_ARL_SRCH_ADDR_63XX 0x32
+ #define ARL_ADDR_MASK GENMASK(14, 0)
+
+ /* ARL Search MAC/VID Result (64 bit) */
+ #define B53_ARL_SRCH_RSTL_0_MACVID 0x60
+ #define B53_ARL_SRCH_RSLT_MACVID_89 0x33
++#define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34
+
+ /* Single register search result on 5325 */
+ #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
+@@ -384,6 +386,13 @@
+ #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10))
+ #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10))
+
++/* 63XX ARL Search Data Result (16 bit) */
++#define B53_ARL_SRCH_RSLT_63XX 0x3c
++#define ARL_SRST_PORT_ID_MASK_63XX GENMASK(9, 1)
++#define ARL_SRST_TC_MASK_63XX GENMASK(13, 11)
++#define ARL_SRST_AGE_63XX BIT(14)
++#define ARL_SRST_STATIC_63XX BIT(15)
++
+ /*************************************************************************
+ * IEEE 802.1X Registers
+ *************************************************************************/
More information about the lede-commits
mailing list