From 9dc8b13e230a802f2510de5e37bfceaa59c9e281 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 21 Oct 2019 16:51:26 -0400 Subject: net: dsa: mv88e6xxx: use ports list to map port VLAN Instead of digging into the other dsa_switch structures of the fabric and relying too much on the dsa_to_port helper, use the new list of switch fabric ports to define the mask of the local ports allowed to receive frames from another port of the fabric. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/chip.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers/net/dsa/mv88e6xxx/chip.c') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 510ccdc2d03c..af8943142053 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -1057,35 +1057,43 @@ static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port, return 0; } +/* Mask of the local ports allowed to receive frames from a given fabric port */ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port) { - struct dsa_switch *ds = NULL; + struct dsa_switch *ds = chip->ds; + struct dsa_switch_tree *dst = ds->dst; struct net_device *br; + struct dsa_port *dp; + bool found = false; u16 pvlan; - int i; - if (dev < DSA_MAX_SWITCHES) - ds = chip->ds->dst->ds[dev]; + list_for_each_entry(dp, &dst->ports, list) { + if (dp->ds->index == dev && dp->index == port) { + found = true; + break; + } + } /* Prevent frames from unknown switch or port */ - if (!ds || port >= ds->num_ports) + if (!found) return 0; /* Frames from DSA links and CPU ports can egress any local port */ - if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) + if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) return mv88e6xxx_port_mask(chip); - br = dsa_to_port(ds, port)->bridge_dev; + br = dp->bridge_dev; pvlan = 0; /* Frames from user ports can egress any local DSA links and CPU ports, * as well as any local member of their bridge group. */ - for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) - if (dsa_is_cpu_port(chip->ds, i) || - dsa_is_dsa_port(chip->ds, i) || - (br && dsa_to_port(chip->ds, i)->bridge_dev == br)) - pvlan |= BIT(i); + list_for_each_entry(dp, &dst->ports, list) + if (dp->ds == ds && + (dp->type == DSA_PORT_TYPE_CPU || + dp->type == DSA_PORT_TYPE_DSA || + (br && dp->bridge_dev == br))) + pvlan |= BIT(dp->index); return pvlan; } -- cgit