Commit cf6b5fb2 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-mv88e6xxx-fix-cross-chip-bridging'

Vivien Didelot says:

====================
net: dsa: mv88e6xxx: fix hardware cross-chip bridging

In order to accelerate cross-chip switching of frames with the hardware,
the DSA Tag ports, used to interconnect switch devices, must learn SA
and DA addresses, and share the same FDB with the user ports.

The two first patches restore address learning on DSA links. This fixes
hardware cross-chip bridging in a VLAN filtering enabled system, which
implements a bridge group as a 802.1Q VLAN and thus share an isolated
address database between DSA and user ports.

The third patch changes the distinct default databases used for each
port, to the same address database. This fixes the hardware cross-chip
bridging in a VLAN filtering disabled system, where a bridge group gets
implemented only as a port-based VLAN.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e47db94e 207afda1
...@@ -2181,27 +2181,10 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, ...@@ -2181,27 +2181,10 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
struct net_device *bridge) struct net_device *bridge)
{ {
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u16 fid;
int i, err; int i, err;
mutex_lock(&ps->smi_mutex); mutex_lock(&ps->smi_mutex);
/* Get or create the bridge FID and assign it to the port */
for (i = 0; i < ps->num_ports; ++i)
if (ps->ports[i].bridge_dev == bridge)
break;
if (i < ps->num_ports)
err = _mv88e6xxx_port_fid_get(ds, i, &fid);
else
err = _mv88e6xxx_fid_new(ds, &fid);
if (err)
goto unlock;
err = _mv88e6xxx_port_fid_set(ds, port, fid);
if (err)
goto unlock;
/* Assign the bridge and remap each port's VLANTable */ /* Assign the bridge and remap each port's VLANTable */
ps->ports[port].bridge_dev = bridge; ps->ports[port].bridge_dev = bridge;
...@@ -2213,7 +2196,6 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, ...@@ -2213,7 +2196,6 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
} }
} }
unlock:
mutex_unlock(&ps->smi_mutex); mutex_unlock(&ps->smi_mutex);
return err; return err;
...@@ -2223,16 +2205,10 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) ...@@ -2223,16 +2205,10 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
{ {
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct net_device *bridge = ps->ports[port].bridge_dev; struct net_device *bridge = ps->ports[port].bridge_dev;
u16 fid;
int i; int i;
mutex_lock(&ps->smi_mutex); mutex_lock(&ps->smi_mutex);
/* Give the port a fresh Filtering Information Database */
if (_mv88e6xxx_fid_new(ds, &fid) ||
_mv88e6xxx_port_fid_set(ds, port, fid))
netdev_warn(ds->ports[port], "failed to assign a new FID\n");
/* Unassign the bridge and remap each port's VLANTable */ /* Unassign the bridge and remap each port's VLANTable */
ps->ports[port].bridge_dev = NULL; ps->ports[port].bridge_dev = NULL;
...@@ -2476,9 +2452,9 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ...@@ -2476,9 +2452,9 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
* the other bits clear. * the other bits clear.
*/ */
reg = 1 << port; reg = 1 << port;
/* Disable learning for DSA and CPU ports */ /* Disable learning for CPU port */
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) if (dsa_is_cpu_port(ds, port))
reg = PORT_ASSOC_VECTOR_LOCKED_PORT; reg = 0;
ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg); ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg);
if (ret) if (ret)
...@@ -2558,11 +2534,11 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) ...@@ -2558,11 +2534,11 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
if (ret) if (ret)
goto abort; goto abort;
/* Port based VLAN map: give each port its own address /* Port based VLAN map: give each port the same default address
* database, and allow bidirectional communication between the * database, and allow bidirectional communication between the
* CPU and DSA port(s), and the other ports. * CPU and DSA port(s), and the other ports.
*/ */
ret = _mv88e6xxx_port_fid_set(ds, port, port + 1); ret = _mv88e6xxx_port_fid_set(ds, port, 0);
if (ret) if (ret)
goto abort; goto abort;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment