net: dsa: mv88e6xxx: include DSA ports in VLANs
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Tue, 3 Nov 2015 15:52:52 +0000 (10:52 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 3 Nov 2015 16:30:17 +0000 (11:30 -0500)
DSA ports must be members of a VLAN in order to ensure frame bridging
between chained switch chips.

Thus tag them in addition to the CPU port when adding a VLAN, and skip
them when deleting a VLAN and reporting VLAN members.

Also use the UNMODIFIED egress policy, so that frames egress on these
ports as they ingress, tagged or untagged.

Fixes: 0d3b33e60206 ("net: dsa: mv88e6xxx: add VLAN Load support")
Reported-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx.c

index 3116990ccab9522d8b374eccadb45503bf983bb7..04cff58d771bd5a86f3b2a0bf2a047de1ee4b6f4 100644 (file)
@@ -1418,11 +1418,11 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
        };
        int i;
 
-       /* exclude all ports except the CPU */
+       /* exclude all ports except the CPU and DSA ports */
        for (i = 0; i < ps->num_ports; ++i)
-               vlan.data[i] = dsa_is_cpu_port(ds, i) ?
-                       GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED :
-                       GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
+               vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
+                       ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
+                       GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
 
        if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) ||
            mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds)) {
@@ -1545,7 +1545,7 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
        /* keep the VLAN unless all ports are excluded */
        vlan.valid = false;
        for (i = 0; i < ps->num_ports; ++i) {
-               if (dsa_is_cpu_port(ds, i))
+               if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
                        continue;
 
                if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
@@ -1624,7 +1624,7 @@ unlock:
                clear_bit(port, ports);
                clear_bit(port, untagged);
 
-               if (dsa_is_cpu_port(ds, port))
+               if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
                        continue;
 
                if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED ||