Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-dsa-b53-fix-arl-accesses-for-bcm5325-65-and-allow-vid-0'

Jonas Gorski says:

====================
net: dsa: b53: fix ARL accesses for BCM5325/65 and allow VID 0

ARL entries on BCM5325 and BCM5365 were broken significantly in two
ways:

- Entries for the CPU port were using the wrong port id, pointing to a
non existing port.
- Setting the VLAN ID for entries was not done, adding them all to VLAN
0 instead.

While the former technically broke any communication to the CPU port,
with the latter they were added to the currently unused VID 0, so they
never became effective. Presumably the default PVID was set to 1 because
of these issues 0 was broken (and the root cause not found).

So fix writing and reading entries on BCM5325/65 by first fixing the CPU
port entries, then fixing setting the VLAN ID for entries.

Finally, re-allow VID 0 for BCM5325/65 to allow the whole 1-15 VLAN ID
range to be available to users, and align VLAN handling with all other
switch chips.
====================

Link: https://patch.msgid.link/20251128080625.27181-1-jonas.gorski@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+62 -44
+18 -29
drivers/net/dsa/b53/b53_common.c
··· 872 872 873 873 static u16 b53_default_pvid(struct b53_device *dev) 874 874 { 875 - if (is5325(dev) || is5365(dev)) 876 - return 1; 877 - else 878 - return 0; 875 + return 0; 879 876 } 880 877 881 878 static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) ··· 1696 1699 { 1697 1700 struct b53_device *dev = ds->priv; 1698 1701 1699 - if ((is5325(dev) || is5365(dev)) && vlan->vid == 0) 1700 - return -EOPNOTSUPP; 1701 - 1702 1702 /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of 1703 1703 * receiving VLAN tagged frames at all, we can still allow the port to 1704 1704 * be configured for egress untagged. ··· 1847 1853 static void b53_arl_read_entry_25(struct b53_device *dev, 1848 1854 struct b53_arl_entry *ent, u8 idx) 1849 1855 { 1856 + u8 vid_entry; 1850 1857 u64 mac_vid; 1851 1858 1859 + b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), 1860 + &vid_entry); 1852 1861 b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), 1853 1862 &mac_vid); 1854 - b53_arl_to_entry_25(ent, mac_vid); 1863 + b53_arl_to_entry_25(ent, mac_vid, vid_entry); 1855 1864 } 1856 1865 1857 1866 static void b53_arl_write_entry_25(struct b53_device *dev, 1858 1867 const struct b53_arl_entry *ent, u8 idx) 1859 1868 { 1869 + u8 vid_entry; 1860 1870 u64 mac_vid; 1861 1871 1862 - b53_arl_from_entry_25(&mac_vid, ent); 1872 + b53_arl_from_entry_25(&mac_vid, &vid_entry, ent); 1873 + b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry); 1863 1874 b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), 1864 1875 mac_vid); 1865 1876 } ··· 1965 1966 1966 1967 /* Perform a read for the given MAC and VID */ 1967 1968 b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac); 1968 - if (!is5325m(dev)) 1969 - b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); 1969 + if (!is5325m(dev)) { 1970 + if (is5325(dev) || is5365(dev)) 1971 + b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); 1972 + else 1973 + b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); 1974 + } 1970 1975 1971 1976 /* Issue a read operation for this MAC */ 1972 1977 ret = b53_arl_rw_op(dev, 1); ··· 2118 2115 struct b53_arl_entry *ent) 2119 2116 { 2120 2117 u64 mac_vid; 2118 + u8 ext; 2121 2119 2120 + b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext); 2122 2121 b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, 2123 2122 &mac_vid); 2124 - b53_arl_to_entry_25(ent, mac_vid); 2125 - } 2126 - 2127 - static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, 2128 - struct b53_arl_entry *ent) 2129 - { 2130 - u64 mac_vid; 2131 - 2132 - b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, 2133 - &mac_vid); 2134 - b53_arl_to_entry_25(ent, mac_vid); 2123 + b53_arl_search_to_entry_25(ent, mac_vid, ext); 2135 2124 } 2136 2125 2137 2126 static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, ··· 2737 2742 .arl_search_read = b53_arl_search_read_25, 2738 2743 }; 2739 2744 2740 - static const struct b53_arl_ops b53_arl_ops_65 = { 2741 - .arl_read_entry = b53_arl_read_entry_25, 2742 - .arl_write_entry = b53_arl_write_entry_25, 2743 - .arl_search_read = b53_arl_search_read_65, 2744 - }; 2745 - 2746 2745 static const struct b53_arl_ops b53_arl_ops_89 = { 2747 2746 .arl_read_entry = b53_arl_read_entry_89, 2748 2747 .arl_write_entry = b53_arl_write_entry_89, ··· 2799 2810 .arl_buckets = 1024, 2800 2811 .imp_port = 5, 2801 2812 .duplex_reg = B53_DUPLEX_STAT_FE, 2802 - .arl_ops = &b53_arl_ops_65, 2813 + .arl_ops = &b53_arl_ops_25, 2803 2814 }, 2804 2815 { 2805 2816 .chip_id = BCM5389_DEVICE_ID,
+31 -9
drivers/net/dsa/b53/b53_priv.h
··· 341 341 } 342 342 343 343 static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, 344 - u64 mac_vid) 344 + u64 mac_vid, u8 vid_entry) 345 345 { 346 346 memset(ent, 0, sizeof(*ent)); 347 - ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & 348 - ARLTBL_DATA_PORT_ID_MASK_25; 349 347 ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); 350 348 ent->is_age = !!(mac_vid & ARLTBL_AGE_25); 351 349 ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); 352 350 u64_to_ether_addr(mac_vid, ent->mac); 353 - ent->vid = mac_vid >> ARLTBL_VID_S_65; 351 + ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >> 352 + ARLTBL_DATA_PORT_ID_S_25; 353 + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) 354 + ent->port = B53_CPU_PORT_25; 355 + ent->vid = vid_entry; 354 356 } 355 357 356 358 static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent, ··· 381 379 *fwd_entry |= ARLTBL_AGE; 382 380 } 383 381 384 - static inline void b53_arl_from_entry_25(u64 *mac_vid, 382 + static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry, 385 383 const struct b53_arl_entry *ent) 386 384 { 387 385 *mac_vid = ether_addr_to_u64(ent->mac); 388 - *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << 389 - ARLTBL_DATA_PORT_ID_S_25; 390 - *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << 391 - ARLTBL_VID_S_65; 386 + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) 387 + *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; 388 + else 389 + *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) & 390 + ARLTBL_DATA_PORT_ID_MASK_25; 392 391 if (ent->is_valid) 393 392 *mac_vid |= ARLTBL_VALID_25; 394 393 if (ent->is_static) 395 394 *mac_vid |= ARLTBL_STATIC_25; 396 395 if (ent->is_age) 397 396 *mac_vid |= ARLTBL_AGE_25; 397 + *vid_entry = ent->vid; 398 398 } 399 399 400 400 static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, ··· 411 407 *fwd_entry |= ARLTBL_STATIC_89; 412 408 if (ent->is_age) 413 409 *fwd_entry |= ARLTBL_AGE_89; 410 + } 411 + 412 + static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent, 413 + u64 mac_vid, u8 ext) 414 + { 415 + memset(ent, 0, sizeof(*ent)); 416 + ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); 417 + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); 418 + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); 419 + u64_to_ether_addr(mac_vid, ent->mac); 420 + ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >> 421 + ARL_SRCH_RSLT_VID_S_25; 422 + ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >> 423 + ARL_SRCH_RSLT_PORT_ID_S_25; 424 + if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII)) 425 + ent->port |= BIT(B53_CPU_PORT_25); 426 + else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) 427 + ent->port = B53_CPU_PORT_25; 414 428 } 415 429 416 430 static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
+13 -6
drivers/net/dsa/b53/b53_regs.h
··· 329 329 #define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10) 330 330 #define ARLTBL_MAC_MASK 0xffffffffffffULL 331 331 #define ARLTBL_VID_S 48 332 - #define ARLTBL_VID_MASK_25 0xff 333 332 #define ARLTBL_VID_MASK 0xfff 334 333 #define ARLTBL_DATA_PORT_ID_S_25 48 335 - #define ARLTBL_DATA_PORT_ID_MASK_25 0xf 336 - #define ARLTBL_VID_S_65 53 334 + #define ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48) 337 335 #define ARLTBL_AGE_25 BIT_ULL(61) 338 336 #define ARLTBL_STATIC_25 BIT_ULL(62) 339 337 #define ARLTBL_VALID_25 BIT_ULL(63) ··· 350 352 #define ARLTBL_AGE_89 BIT(13) 351 353 #define ARLTBL_STATIC_89 BIT(14) 352 354 #define ARLTBL_VALID_89 BIT(15) 355 + 356 + /* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */ 357 + #define B53_ARLTBL_VID_ENTRY_25(n) ((0x2 * (n)) + 0x30) 353 358 354 359 /* Maximum number of bin entries in the ARL for all switches */ 355 360 #define B53_ARLTBL_MAX_BIN_ENTRIES 4 ··· 377 376 #define B53_ARL_SRCH_RSLT_MACVID_89 0x33 378 377 #define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34 379 378 380 - /* Single register search result on 5325 */ 379 + /* Single register search result on 5325/5365 */ 381 380 #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 382 - /* Single register search result on 5365 */ 383 - #define B53_ARL_SRCH_RSTL_0_MACVID_65 0x30 381 + #define ARL_SRCH_RSLT_PORT_ID_S_25 48 382 + #define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48) 383 + #define ARL_SRCH_RSLT_VID_S_25 53 384 + #define ARL_SRCH_RSLT_VID_MASK_25 GENMASK_ULL(60, 53) 385 + 386 + /* BCM5325/5365 Search result extend register (8 bit) */ 387 + #define B53_ARL_SRCH_RSLT_EXT_25 0x2c 388 + #define ARL_SRCH_RSLT_EXT_MC_MII BIT(2) 384 389 385 390 /* ARL Search Data Result (32 bit) */ 386 391 #define B53_ARL_SRCH_RSTL_0 0x68