When servicing ATU violations we need to walk the VTU to find the vlan id for the ATU's FID which is inefficient. Add a cache for this association and replace the VTU walk so we don't have to do this costly operation all the time. Signed-off-by: Elliot Ayrey <elliot.ayrey@xxxxxxxxxxxxxxxxxxx> --- drivers/net/dsa/mv88e6xxx/chip.h | 2 ++ drivers/net/dsa/mv88e6xxx/global1_vtu.c | 6 ++++- drivers/net/dsa/mv88e6xxx/switchdev.c | 35 ++----------------------- 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index 48399ab5355a..91c3e4b304cf 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -445,6 +445,8 @@ struct mv88e6xxx_chip { /* FID map */ DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); + + u16 vid_cache[MV88E6XXX_N_FID]; }; struct mv88e6xxx_bus_ops { diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c index b524f27a2f0d..af1c40480303 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c @@ -464,7 +464,11 @@ int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip, } /* Load/Purge VTU entry */ - return mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); + err = mv88e6xxx_g1_vtu_op(chip, MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE); + if (err == 0) + chip->vid_cache[entry->fid] = entry->valid ? entry->vid : 0; + + return err; } int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip) diff --git a/drivers/net/dsa/mv88e6xxx/switchdev.c b/drivers/net/dsa/mv88e6xxx/switchdev.c index 88761677ff10..e96daa2dcaf4 100644 --- a/drivers/net/dsa/mv88e6xxx/switchdev.c +++ b/drivers/net/dsa/mv88e6xxx/switchdev.c @@ -12,42 +12,11 @@ #include "global1.h" #include "switchdev.h" -struct mv88e6xxx_fid_search_ctx { - u16 fid_search; - u16 vid_found; -}; - -static int __mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, - const struct mv88e6xxx_vtu_entry *entry, - void *priv) -{ - struct mv88e6xxx_fid_search_ctx *ctx = priv; - - if (ctx->fid_search == entry->fid) { - ctx->vid_found = entry->vid; - return 1; - } - - return 0; -} - static int mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, u16 fid, u16 *vid) { - struct mv88e6xxx_fid_search_ctx ctx; - int err; - - ctx.fid_search = fid; - mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_vtu_walk(chip, __mv88e6xxx_find_vid, &ctx); - mv88e6xxx_reg_unlock(chip); - if (err < 0) - return err; - if (err == 1) - *vid = ctx.vid_found; - else - return -ENOENT; + *vid = chip->vid_cache[fid]; - return 0; + return *vid ? 0 : -ENOENT; } int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port,