Skip to content

Commit 75d0de8

Browse files
committed
Merge branch 'dsa-cross-chip-FDB-support'
Vivien Didelot says: ==================== net: dsa: cross-chip FDB support DSA can have interconnected switches. For instance, the ZII Dev Rev B board described in arch/arm/boot/dts/vf610-zii-dev-rev-b.dts has a switch fabric composed of 3 switch devices like this: lan4 lan6 CPU (eth1) | lan5 | lan7 | | | | | [0 1 2 3 4 6 5]---[6 0 1 2 3 4 5]---[9 0 1 2 3 4 5 6 7 8] | | | | | | | lan0 | lan2 lan3 lan8 | optical4 lan1 optical3 One current issue with DSA is cross-chip FDB. If we add a static MAC address on lan3, only its parent switch 1 (the one in the middle) will be programmed. That is not correct in a cross-chip environment, because the DSA ports connecting to switch 1 of adjacent switch 0 (on the left) and switch 2 (on the right) must be programmed too. Without this patchset, a dump of the hardware FDB of switches 0, 1 and 2 after programming a MAC address on lan3 looks like this (*): # bridge fdb add 11:22:33:44:55:66 dev lan3 # cat /sys/kernel/debug/mv88e6xxx/sw*/atu/0 | grep -v FID 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 0 11:22:33:44:55:66 MC_STATIC_MGMT_PO n 0 - - - - - - 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 7 8 9 With this patchset applied, adjacent DSA ports get programmed too: # bridge fdb add 11:22:33:44:55:66 dev lan3 # cat /sys/kernel/debug/mv88e6xxx/sw*/atu/0 | grep -v FID 0 11:22:33:44:55:66 MC_STATIC_MGMT_PO n - - - - - 5 - 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 0 11:22:33:44:55:66 MC_STATIC_MGMT_PO n 0 - - - - - - 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 0 11:22:33:44:55:66 MC_STATIC_MGMT_PO n - - - - - - - - - 9 0 ff:ff:ff:ff:ff:ff MC_STATIC n 0 1 2 3 4 5 6 7 8 9 In order to do that, the first commit introduces a dsa_towards_port() helper which returns the local port of a switch which must be used to reach an arbitrary switch port (local or from an adjacent switch.) The second patch uses this helper to configure the port reaching the target port for every switches of the fabric. (*) a patch for squashed debugfs interface which applies on top of this patchset is available here: https://github.com/vivien/linux/commit/f8e6ba34c68a72d3bf42f4dea79abacb2e61a3cc.patch ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5420683 + 3169241 commit 75d0de8

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

include/net/dsa.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -296,20 +296,23 @@ static inline u32 dsa_user_ports(struct dsa_switch *ds)
296296
return mask;
297297
}
298298

299+
/* Return the local port used to reach an arbitrary switch port */
300+
static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device,
301+
int port)
302+
{
303+
if (device == ds->index)
304+
return port;
305+
else
306+
return ds->rtable[device];
307+
}
308+
309+
/* Return the local port used to reach the dedicated CPU port */
299310
static inline u8 dsa_upstream_port(struct dsa_switch *ds)
300311
{
301312
struct dsa_switch_tree *dst = ds->dst;
313+
struct dsa_port *cpu_dp = dst->cpu_dp;
302314

303-
/*
304-
* If this is the root switch (i.e. the switch that connects
305-
* to the CPU), return the cpu port number on this switch.
306-
* Else return the (DSA) port number that connects to the
307-
* switch that is one hop closer to the cpu.
308-
*/
309-
if (dst->cpu_dp->ds == ds)
310-
return dst->cpu_dp->index;
311-
else
312-
return ds->rtable[dst->cpu_dp->ds->index];
315+
return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index);
313316
}
314317

315318
typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,

net/dsa/switch.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,29 +83,23 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
8383
static int dsa_switch_fdb_add(struct dsa_switch *ds,
8484
struct dsa_notifier_fdb_info *info)
8585
{
86-
/* Do not care yet about other switch chips of the fabric */
87-
if (ds->index != info->sw_index)
88-
return 0;
86+
int port = dsa_towards_port(ds, info->sw_index, info->port);
8987

9088
if (!ds->ops->port_fdb_add)
9189
return -EOPNOTSUPP;
9290

93-
return ds->ops->port_fdb_add(ds, info->port, info->addr,
94-
info->vid);
91+
return ds->ops->port_fdb_add(ds, port, info->addr, info->vid);
9592
}
9693

9794
static int dsa_switch_fdb_del(struct dsa_switch *ds,
9895
struct dsa_notifier_fdb_info *info)
9996
{
100-
/* Do not care yet about other switch chips of the fabric */
101-
if (ds->index != info->sw_index)
102-
return 0;
97+
int port = dsa_towards_port(ds, info->sw_index, info->port);
10398

10499
if (!ds->ops->port_fdb_del)
105100
return -EOPNOTSUPP;
106101

107-
return ds->ops->port_fdb_del(ds, info->port, info->addr,
108-
info->vid);
102+
return ds->ops->port_fdb_del(ds, port, info->addr, info->vid);
109103
}
110104

111105
static int

0 commit comments

Comments
 (0)