net: dsa: mv88e6xxx: Provide generic VTU iterator
Move the intricacies of correctly iterating over the VTU to a common implementation. Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ffcec3f257
commit
d89ef4b8b3
@ -1511,6 +1511,37 @@ static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
|
||||
return chip->info->ops->vtu_getnext(chip, entry);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
|
||||
int (*cb)(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *priv),
|
||||
void *priv)
|
||||
{
|
||||
struct mv88e6xxx_vtu_entry entry = {
|
||||
.vid = mv88e6xxx_max_vid(chip),
|
||||
.valid = false,
|
||||
};
|
||||
int err;
|
||||
|
||||
if (!chip->info->ops->vtu_getnext)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
do {
|
||||
err = chip->info->ops->vtu_getnext(chip, &entry);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!entry.valid)
|
||||
break;
|
||||
|
||||
err = cb(chip, &entry, priv);
|
||||
if (err)
|
||||
return err;
|
||||
} while (entry.vid < mv88e6xxx_max_vid(chip));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
|
||||
struct mv88e6xxx_vtu_entry *entry)
|
||||
{
|
||||
@ -1520,9 +1551,18 @@ static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
|
||||
return chip->info->ops->vtu_loadpurge(chip, entry);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *_fid_bitmap)
|
||||
{
|
||||
unsigned long *fid_bitmap = _fid_bitmap;
|
||||
|
||||
set_bit(entry->fid, fid_bitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
|
||||
{
|
||||
struct mv88e6xxx_vtu_entry vlan;
|
||||
int i, err;
|
||||
u16 fid;
|
||||
|
||||
@ -1538,21 +1578,7 @@ int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
|
||||
}
|
||||
|
||||
/* Set every FID bit used by the VLAN entries */
|
||||
vlan.vid = mv88e6xxx_max_vid(chip);
|
||||
vlan.valid = false;
|
||||
|
||||
do {
|
||||
err = mv88e6xxx_vtu_getnext(chip, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!vlan.valid)
|
||||
break;
|
||||
|
||||
set_bit(vlan.fid, fid_bitmap);
|
||||
} while (vlan.vid < mv88e6xxx_max_vid(chip));
|
||||
|
||||
return 0;
|
||||
return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
|
||||
@ -2198,10 +2224,30 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
|
||||
return err;
|
||||
}
|
||||
|
||||
struct mv88e6xxx_port_db_dump_vlan_ctx {
|
||||
int port;
|
||||
dsa_fdb_dump_cb_t *cb;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *_data)
|
||||
{
|
||||
struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data;
|
||||
|
||||
return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid,
|
||||
ctx->port, ctx->cb, ctx->data);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
dsa_fdb_dump_cb_t *cb, void *data)
|
||||
{
|
||||
struct mv88e6xxx_vtu_entry vlan;
|
||||
struct mv88e6xxx_port_db_dump_vlan_ctx ctx = {
|
||||
.port = port,
|
||||
.cb = cb,
|
||||
.data = data,
|
||||
};
|
||||
u16 fid;
|
||||
int err;
|
||||
|
||||
@ -2214,25 +2260,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Dump VLANs' Filtering Information Databases */
|
||||
vlan.vid = mv88e6xxx_max_vid(chip);
|
||||
vlan.valid = false;
|
||||
|
||||
do {
|
||||
err = mv88e6xxx_vtu_getnext(chip, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!vlan.valid)
|
||||
break;
|
||||
|
||||
err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
|
||||
cb, data);
|
||||
if (err)
|
||||
return err;
|
||||
} while (vlan.vid < mv88e6xxx_max_vid(chip));
|
||||
|
||||
return err;
|
||||
return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
|
||||
|
Loading…
x
Reference in New Issue
Block a user