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) ...@@ -1502,13 +1502,23 @@ static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
return mv88e6xxx_g1_vtu_flush(chip); return mv88e6xxx_g1_vtu_flush(chip);
} }
static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip, static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
struct mv88e6xxx_vtu_entry *entry) struct mv88e6xxx_vtu_entry *entry)
{ {
int err;
if (!chip->info->ops->vtu_getnext) if (!chip->info->ops->vtu_getnext)
return -EOPNOTSUPP; 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, 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, ...@@ -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)) if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
return 0; return 0;
vlan.vid = vid - 1; err = mv88e6xxx_vtu_get(chip, vid, &vlan);
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err) if (err)
return err; return err;
if (!vlan.valid) if (!vlan.valid)
return 0; return 0;
if (vlan.vid != vid)
return 0;
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i)) if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
continue; continue;
...@@ -1709,15 +1713,12 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, ...@@ -1709,15 +1713,12 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
if (err) if (err)
return err; return err;
} else { } else {
vlan.vid = vid - 1; err = mv88e6xxx_vtu_get(chip, vid, &vlan);
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err) if (err)
return err; return err;
/* switchdev expects -EOPNOTSUPP to honor software VLANs */ /* switchdev expects -EOPNOTSUPP to honor software VLANs */
if (vlan.vid != vid || !vlan.valid) if (!vlan.valid)
return -EOPNOTSUPP; return -EOPNOTSUPP;
fid = vlan.fid; fid = vlan.fid;
...@@ -1994,14 +1995,11 @@ static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port, ...@@ -1994,14 +1995,11 @@ static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
struct mv88e6xxx_vtu_entry vlan; struct mv88e6xxx_vtu_entry vlan;
int i, err; int i, err;
vlan.vid = vid - 1; err = mv88e6xxx_vtu_get(chip, vid, &vlan);
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err) if (err)
return err; return err;
if (vlan.vid != vid || !vlan.valid) { if (!vlan.valid) {
memset(&vlan, 0, sizeof(vlan)); memset(&vlan, 0, sizeof(vlan));
err = mv88e6xxx_atu_new(chip, &vlan.fid); err = mv88e6xxx_atu_new(chip, &vlan.fid);
...@@ -2097,17 +2095,14 @@ static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip, ...@@ -2097,17 +2095,14 @@ static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
if (!vid) if (!vid)
return -EOPNOTSUPP; return -EOPNOTSUPP;
vlan.vid = vid - 1; err = mv88e6xxx_vtu_get(chip, vid, &vlan);
vlan.valid = false;
err = mv88e6xxx_vtu_getnext(chip, &vlan);
if (err) if (err)
return err; return err;
/* If the VLAN doesn't exist in hardware or the port isn't a member, /* 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. * 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) vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
return -EOPNOTSUPP; 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