net: dsa: mv88e6xxx: Provide generic VTU iterator
authorTobias Waldekranz <tobias@waldekranz.com>
Thu, 18 Mar 2021 19:25:35 +0000 (20:25 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Mar 2021 23:24:06 +0000 (16:24 -0700)
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>
drivers/net/dsa/mv88e6xxx/chip.c

index ed38b44..0a4e467 100644 (file)
@@ -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,