The same dsa_fdb_dump_cb_t callback is used since there is no
distinction to do between FDB and MDB entries at this layer.

Implement mv88e6xxx_port_mdb_dump so that multicast addresses associated
to a switch port can be dumped.

Signed-off-by: Vivien Didelot <vivien.dide...@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <and...@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 33 +++++++++++++++++++++++++--------
 include/net/dsa.h                |  3 +++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c6678aa9b4ef..c66204423641 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1380,7 +1380,7 @@ static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, 
int port,
 }
 
 static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
-                                     u16 fid, u16 vid, int port,
+                                     u16 fid, u16 vid, int port, bool mc,
                                      dsa_fdb_dump_cb_t *cb, void *data)
 {
        struct mv88e6xxx_atu_entry addr;
@@ -1401,11 +1401,14 @@ static int mv88e6xxx_port_db_dump_fid(struct 
mv88e6xxx_chip *chip,
                if (addr.trunk || (addr.portvec & BIT(port)) == 0)
                        continue;
 
-               if (!is_unicast_ether_addr(addr.mac))
+               if ((is_unicast_ether_addr(addr.mac) && mc) ||
+                   (is_multicast_ether_addr(addr.mac) && !mc))
                        continue;
 
-               is_static = (addr.state ==
-                            MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
+               is_static = addr.state == mc ?
+                       MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC :
+                       MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC;
+
                err = cb(addr.mac, vid, is_static, data);
                if (err)
                        return err;
@@ -1415,7 +1418,7 @@ static int mv88e6xxx_port_db_dump_fid(struct 
mv88e6xxx_chip *chip,
 }
 
 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
-                                 dsa_fdb_dump_cb_t *cb, void *data)
+                                 bool mc, dsa_fdb_dump_cb_t *cb, void *data)
 {
        struct mv88e6xxx_vtu_entry vlan = {
                .vid = chip->info->max_vid,
@@ -1428,7 +1431,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip 
*chip, int port,
        if (err)
                return err;
 
-       err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
+       err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, mc, cb, data);
        if (err)
                return err;
 
@@ -1442,7 +1445,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip 
*chip, int port,
                        break;
 
                err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
-                                                cb, data);
+                                                mc, cb, data);
                if (err)
                        return err;
        } while (vlan.vid < chip->info->max_vid);
@@ -1457,7 +1460,7 @@ static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, 
int port,
        int err;
 
        mutex_lock(&chip->reg_lock);
-       err = mv88e6xxx_port_db_dump(chip, port, cb, data);
+       err = mv88e6xxx_port_db_dump(chip, port, false, cb, data);
        mutex_unlock(&chip->reg_lock);
 
        return err;
@@ -3777,6 +3780,19 @@ static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, 
int port,
        return err;
 }
 
+static int mv88e6xxx_port_mdb_dump(struct dsa_switch *ds, int port,
+                                  dsa_fdb_dump_cb_t *cb, void *data)
+{
+       struct mv88e6xxx_chip *chip = ds->priv;
+       int err;
+
+       mutex_lock(&chip->reg_lock);
+       err = mv88e6xxx_port_db_dump(chip, port, true, cb, data);
+       mutex_unlock(&chip->reg_lock);
+
+       return err;
+}
+
 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
        .probe                  = mv88e6xxx_drv_probe,
        .get_tag_protocol       = mv88e6xxx_get_tag_protocol,
@@ -3810,6 +3826,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = 
{
        .port_mdb_prepare       = mv88e6xxx_port_mdb_prepare,
        .port_mdb_add           = mv88e6xxx_port_mdb_add,
        .port_mdb_del           = mv88e6xxx_port_mdb_del,
+       .port_mdb_dump          = mv88e6xxx_port_mdb_dump,
        .crosschip_bridge_join  = mv88e6xxx_crosschip_bridge_join,
        .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
 };
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 1309ba0376ae..c0d1b6c47a50 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -312,6 +312,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
                return ds->rtable[dst->cpu_dp->ds->index];
 }
 
+/* FDB (and MDB) dump callback */
 typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
                              bool is_static, void *data);
 struct dsa_switch_ops {
@@ -441,6 +442,8 @@ struct dsa_switch_ops {
                                struct switchdev_trans *trans);
        int     (*port_mdb_del)(struct dsa_switch *ds, int port,
                                const struct switchdev_obj_port_mdb *mdb);
+       int     (*port_mdb_dump)(struct dsa_switch *ds, int port,
+                                dsa_fdb_dump_cb_t *cb, void *data);
        /*
         * RXNFC
         */
-- 
2.14.1

Reply via email to