@@ -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 {
@@ -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)
@@ -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,
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@alliedtelesis.co.nz> --- 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(-)