Skip to content

Commit 8d92057

Browse files
committed
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/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 4e3583c + 0b2b270 commit 8d92057

File tree

3 files changed

+62
-44
lines changed

3 files changed

+62
-44
lines changed

drivers/net/dsa/b53/b53_common.c

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -872,10 +872,7 @@ static void b53_enable_stp(struct b53_device *dev)
872872

873873
static u16 b53_default_pvid(struct b53_device *dev)
874874
{
875-
if (is5325(dev) || is5365(dev))
876-
return 1;
877-
else
878-
return 0;
875+
return 0;
879876
}
880877

881878
static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port)
@@ -1699,9 +1696,6 @@ static int b53_vlan_prepare(struct dsa_switch *ds, int port,
16991696
{
17001697
struct b53_device *dev = ds->priv;
17011698

1702-
if ((is5325(dev) || is5365(dev)) && vlan->vid == 0)
1703-
return -EOPNOTSUPP;
1704-
17051699
/* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of
17061700
* receiving VLAN tagged frames at all, we can still allow the port to
17071701
* be configured for egress untagged.
@@ -1853,19 +1847,24 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)
18531847
static void b53_arl_read_entry_25(struct b53_device *dev,
18541848
struct b53_arl_entry *ent, u8 idx)
18551849
{
1850+
u8 vid_entry;
18561851
u64 mac_vid;
18571852

1853+
b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx),
1854+
&vid_entry);
18581855
b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
18591856
&mac_vid);
1860-
b53_arl_to_entry_25(ent, mac_vid);
1857+
b53_arl_to_entry_25(ent, mac_vid, vid_entry);
18611858
}
18621859

18631860
static void b53_arl_write_entry_25(struct b53_device *dev,
18641861
const struct b53_arl_entry *ent, u8 idx)
18651862
{
1863+
u8 vid_entry;
18661864
u64 mac_vid;
18671865

1868-
b53_arl_from_entry_25(&mac_vid, ent);
1866+
b53_arl_from_entry_25(&mac_vid, &vid_entry, ent);
1867+
b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry);
18691868
b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx),
18701869
mac_vid);
18711870
}
@@ -1966,8 +1965,12 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
19661965

19671966
/* Perform a read for the given MAC and VID */
19681967
b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac);
1969-
if (!is5325m(dev))
1970-
b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
1968+
if (!is5325m(dev)) {
1969+
if (is5325(dev) || is5365(dev))
1970+
b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
1971+
else
1972+
b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid);
1973+
}
19711974

19721975
/* Issue a read operation for this MAC */
19731976
ret = b53_arl_rw_op(dev, 1);
@@ -2115,20 +2118,12 @@ static void b53_arl_search_read_25(struct b53_device *dev, u8 idx,
21152118
struct b53_arl_entry *ent)
21162119
{
21172120
u64 mac_vid;
2121+
u8 ext;
21182122

2123+
b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext);
21192124
b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25,
21202125
&mac_vid);
2121-
b53_arl_to_entry_25(ent, mac_vid);
2122-
}
2123-
2124-
static void b53_arl_search_read_65(struct b53_device *dev, u8 idx,
2125-
struct b53_arl_entry *ent)
2126-
{
2127-
u64 mac_vid;
2128-
2129-
b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65,
2130-
&mac_vid);
2131-
b53_arl_to_entry_25(ent, mac_vid);
2126+
b53_arl_search_to_entry_25(ent, mac_vid, ext);
21322127
}
21332128

21342129
static void b53_arl_search_read_89(struct b53_device *dev, u8 idx,
@@ -2742,12 +2737,6 @@ static const struct b53_arl_ops b53_arl_ops_25 = {
27422737
.arl_search_read = b53_arl_search_read_25,
27432738
};
27442739

2745-
static const struct b53_arl_ops b53_arl_ops_65 = {
2746-
.arl_read_entry = b53_arl_read_entry_25,
2747-
.arl_write_entry = b53_arl_write_entry_25,
2748-
.arl_search_read = b53_arl_search_read_65,
2749-
};
2750-
27512740
static const struct b53_arl_ops b53_arl_ops_89 = {
27522741
.arl_read_entry = b53_arl_read_entry_89,
27532742
.arl_write_entry = b53_arl_write_entry_89,
@@ -2810,7 +2799,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
28102799
.arl_buckets = 1024,
28112800
.imp_port = 5,
28122801
.duplex_reg = B53_DUPLEX_STAT_FE,
2813-
.arl_ops = &b53_arl_ops_65,
2802+
.arl_ops = &b53_arl_ops_25,
28142803
},
28152804
{
28162805
.chip_id = BCM5389_DEVICE_ID,

drivers/net/dsa/b53/b53_priv.h

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,18 @@ static inline void b53_arl_to_entry(struct b53_arl_entry *ent,
341341
}
342342

343343
static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent,
344-
u64 mac_vid)
344+
u64 mac_vid, u8 vid_entry)
345345
{
346346
memset(ent, 0, sizeof(*ent));
347-
ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) &
348-
ARLTBL_DATA_PORT_ID_MASK_25;
349347
ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
350348
ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
351349
ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
352350
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;
354356
}
355357

356358
static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent,
@@ -379,20 +381,22 @@ static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
379381
*fwd_entry |= ARLTBL_AGE;
380382
}
381383

382-
static inline void b53_arl_from_entry_25(u64 *mac_vid,
384+
static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry,
383385
const struct b53_arl_entry *ent)
384386
{
385387
*mac_vid = ether_addr_to_u64(ent->mac);
386-
*mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) <<
387-
ARLTBL_DATA_PORT_ID_S_25;
388-
*mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) <<
389-
ARLTBL_VID_S_65;
388+
if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25)
389+
*mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25;
390+
else
391+
*mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) &
392+
ARLTBL_DATA_PORT_ID_MASK_25;
390393
if (ent->is_valid)
391394
*mac_vid |= ARLTBL_VALID_25;
392395
if (ent->is_static)
393396
*mac_vid |= ARLTBL_STATIC_25;
394397
if (ent->is_age)
395398
*mac_vid |= ARLTBL_AGE_25;
399+
*vid_entry = ent->vid;
396400
}
397401

398402
static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry,
@@ -409,6 +413,24 @@ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry,
409413
*fwd_entry |= ARLTBL_AGE_89;
410414
}
411415

416+
static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent,
417+
u64 mac_vid, u8 ext)
418+
{
419+
memset(ent, 0, sizeof(*ent));
420+
ent->is_valid = !!(mac_vid & ARLTBL_VALID_25);
421+
ent->is_age = !!(mac_vid & ARLTBL_AGE_25);
422+
ent->is_static = !!(mac_vid & ARLTBL_STATIC_25);
423+
u64_to_ether_addr(mac_vid, ent->mac);
424+
ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >>
425+
ARL_SRCH_RSLT_VID_S_25;
426+
ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >>
427+
ARL_SRCH_RSLT_PORT_ID_S_25;
428+
if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII))
429+
ent->port |= BIT(B53_CPU_PORT_25);
430+
else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT)
431+
ent->port = B53_CPU_PORT_25;
432+
}
433+
412434
static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent,
413435
u64 mac_vid, u16 fwd_entry)
414436
{

drivers/net/dsa/b53/b53_regs.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,9 @@
329329
#define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10)
330330
#define ARLTBL_MAC_MASK 0xffffffffffffULL
331331
#define ARLTBL_VID_S 48
332-
#define ARLTBL_VID_MASK_25 0xff
333332
#define ARLTBL_VID_MASK 0xfff
334333
#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)
337335
#define ARLTBL_AGE_25 BIT_ULL(61)
338336
#define ARLTBL_STATIC_25 BIT_ULL(62)
339337
#define ARLTBL_VALID_25 BIT_ULL(63)
@@ -353,6 +351,9 @@
353351
#define ARLTBL_STATIC_89 BIT(14)
354352
#define ARLTBL_VALID_89 BIT(15)
355353

354+
/* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */
355+
#define B53_ARLTBL_VID_ENTRY_25(n) ((0x2 * (n)) + 0x30)
356+
356357
/* Maximum number of bin entries in the ARL for all switches */
357358
#define B53_ARLTBL_MAX_BIN_ENTRIES 4
358359

@@ -376,10 +377,16 @@
376377
#define B53_ARL_SRCH_RSLT_MACVID_89 0x33
377378
#define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34
378379

379-
/* Single register search result on 5325 */
380+
/* Single register search result on 5325/5365 */
380381
#define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24
381-
/* Single register search result on 5365 */
382-
#define B53_ARL_SRCH_RSTL_0_MACVID_65 0x30
382+
#define ARL_SRCH_RSLT_PORT_ID_S_25 48
383+
#define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48)
384+
#define ARL_SRCH_RSLT_VID_S_25 53
385+
#define ARL_SRCH_RSLT_VID_MASK_25 GENMASK_ULL(60, 53)
386+
387+
/* BCM5325/5365 Search result extend register (8 bit) */
388+
#define B53_ARL_SRCH_RSLT_EXT_25 0x2c
389+
#define ARL_SRCH_RSLT_EXT_MC_MII BIT(2)
383390

384391
/* ARL Search Data Result (32 bit) */
385392
#define B53_ARL_SRCH_RSTL_0 0x68

0 commit comments

Comments
 (0)