generic: 6.12: backport b53 patches from netdev-next
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Build all core packages / Build all core packages for selected target (push) Waiting to run

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@gmail.com>
This commit is contained in:
Álvaro Fernández Rojas 2025-11-19 09:42:20 +01:00
parent cd75f703c2
commit 08964109be
8 changed files with 1212 additions and 0 deletions

View file

@ -0,0 +1,85 @@
From a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-2-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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)

View file

@ -0,0 +1,117 @@
From 4a291fe7226736a465ddb3fa93c21fcef7162ec7 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-3-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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)

View file

@ -0,0 +1,93 @@
From bf6e9d2ae1dbafee53ec4ccd126595172e1e5278 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-4-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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);
}

View file

@ -0,0 +1,85 @@
From 1716be6db04af53bac9b869f01156a460595cf41 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-5-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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, &reg);
+ b53_read_arl_srch_ctl(dev, &reg);
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);

View file

@ -0,0 +1,86 @@
From e0c476f325a8c9b961a3d446c24d3c8ecae7d186 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-6-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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,

View file

@ -0,0 +1,348 @@
From a7e73339ad46ade76d29fb6cc7d7854222608c26 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-7-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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>

View file

@ -0,0 +1,221 @@
From 300f78e8b6b7be17c2c78afeded75be68acb1aa7 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-8-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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))

View file

@ -0,0 +1,177 @@
From 2b3013ac03028a2364d8779719bb6bfbc0212435 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@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@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251107080749.26936-9-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@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
*************************************************************************/