Commit 34065c58 authored by Tobias Waldekranz's avatar Tobias Waldekranz Committed by David S. Miller

net: dsa: mv88e6xxx: Remove some bureaucracy around querying the VTU

The hardware has a somewhat quirky protocol for reading out the VTU
entry for a particular VID. But there is no reason why we cannot
create a better API for ourselves in the driver.
Signed-off-by: default avatarTobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d89ef4b8
......@@ -1502,13 +1502,23 @@ static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
return mv88e6xxx_g1_vtu_flush(chip);
}
static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
struct mv88e6xxx_vtu_entry *entry)
static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
struct mv88e6xxx_vtu_entry *entry)
{
int err;
if (!chip->info->ops->vtu_getnext)
return -EOPNOTSUPP;
return chip->info->ops->vtu_getnext(chip, entry);
entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
entry->valid = false;
err = chip->info->ops->vtu_getnext(chip, entry);
if (entry->vid != vid)
entry->valid = false;
return err;
}
static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
......@@ -1615,19 +1625,13 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
return 0;
vlan.vid = vid - 1;
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
err = mv88e6xxx_vtu_get(chip, vid, &vlan);
if (err)
return err;
if (!vlan.valid)
return 0;
if (vlan.vid != vid)
return 0;
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
continue;
......@@ -1709,15 +1713,12 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
if (err)
return err;
} else {
vlan.vid = vid - 1;
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
err = mv88e6xxx_vtu_get(chip, vid, &vlan);
if (err)
return err;
/* switchdev expects -EOPNOTSUPP to honor software VLANs */
if (vlan.vid != vid || !vlan.valid)
if (!vlan.valid)
return -EOPNOTSUPP;
fid = vlan.fid;
......@@ -1994,14 +1995,11 @@ static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
struct mv88e6xxx_vtu_entry vlan;
int i, err;
vlan.vid = vid - 1;
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
err = mv88e6xxx_vtu_get(chip, vid, &vlan);
if (err)
return err;
if (vlan.vid != vid || !vlan.valid) {
if (!vlan.valid) {
memset(&vlan, 0, sizeof(vlan));
err = mv88e6xxx_atu_new(chip, &vlan.fid);
......@@ -2097,17 +2095,14 @@ static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
if (!vid)
return -EOPNOTSUPP;
vlan.vid = vid - 1;
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
err = mv88e6xxx_vtu_get(chip, vid, &vlan);
if (err)
return err;
/* If the VLAN doesn't exist in hardware or the port isn't a member,
* tell switchdev that this VLAN is likely handled in software.
*/
if (vlan.vid != vid || !vlan.valid ||
if (!vlan.valid ||
vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
return -EOPNOTSUPP;
......
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