]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: dsa: b53: add support for 5389/5397/5398 ARL entry format
authorJonas Gorski <jonas.gorski@gmail.com>
Fri, 7 Nov 2025 08:07:48 +0000 (09:07 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 11 Nov 2025 01:11:07 +0000 (17:11 -0800)
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
drivers/net/dsa/b53/b53_priv.h
drivers/net/dsa/b53/b53_regs.h

index c69022cc85bf355867889b1f1a13417a768e0440..73ea9adb95b71164edb7e8a6e22245d7fae99eb7 100644 (file)
@@ -1870,6 +1870,31 @@ static void b53_arl_write_entry_25(struct b53_device *dev,
                    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)
 {
@@ -2033,6 +2058,8 @@ static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val)
 
        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;
 
@@ -2045,6 +2072,8 @@ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val)
 
        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;
 
@@ -2090,6 +2119,18 @@ static void b53_arl_search_read_65(struct b53_device *dev, u8 idx,
        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)
 {
@@ -2683,6 +2724,12 @@ static const struct b53_arl_ops b53_arl_ops_65 = {
        .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,
@@ -2747,7 +2794,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
                .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,
@@ -2775,7 +2822,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
                .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,
@@ -2789,7 +2836,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
                .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,
index ef2413509b5db50178bb439256a41dcf4821e62f..d6d25bb3945b4d2b5b778bbf9273670e952f291c 100644 (file)
@@ -353,6 +353,18 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent,
        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(u64 *mac_vid,
                *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)
 {
index c36a3dfb2ee89c2920cfd968a6e2038c91837b1b..c303507d30343cc8274b7d5be0d27c875572a6f3 100644 (file)
 #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)
 
 #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
 /* 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))