net: sparx5: Support offloading of bridge port flooding flags
authorCasper Andersson <casper.casan@gmail.com>
Wed, 23 Feb 2022 08:27:00 +0000 (09:27 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 25 Feb 2022 05:17:20 +0000 (21:17 -0800)
Though the SparX-5i can control IPv4/6 multicasts separately from non-IP
multicasts, these are all muxed onto the bridge's BR_MCAST_FLOOD flag.

Signed-off-by: Casper Andersson <casper.casan@gmail.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Link: https://lore.kernel.org/r/20220223082700.qrot7lepwqcdnyzw@wse-c0155
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c

index f5271c3..dacb87f 100644 (file)
@@ -19,11 +19,27 @@ struct sparx5_switchdev_event_work {
        unsigned long event;
 };
 
+static int sparx5_port_attr_pre_bridge_flags(struct sparx5_port *port,
+                                            struct switchdev_brport_flags flags)
+{
+       if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD))
+               return -EINVAL;
+
+       return 0;
+}
+
 static void sparx5_port_attr_bridge_flags(struct sparx5_port *port,
                                          struct switchdev_brport_flags flags)
 {
+       int pgid;
+
        if (flags.mask & BR_MCAST_FLOOD)
-               sparx5_pgid_update_mask(port, PGID_MC_FLOOD, true);
+               for (pgid = PGID_MC_FLOOD; pgid <= PGID_IPV6_MC_CTRL; pgid++)
+                       sparx5_pgid_update_mask(port, pgid, !!(flags.val & BR_MCAST_FLOOD));
+       if (flags.mask & BR_FLOOD)
+               sparx5_pgid_update_mask(port, PGID_UC_FLOOD, !!(flags.val & BR_FLOOD));
+       if (flags.mask & BR_BCAST_FLOOD)
+               sparx5_pgid_update_mask(port, PGID_BCAST, !!(flags.val & BR_BCAST_FLOOD));
 }
 
 static void sparx5_attr_stp_state_set(struct sparx5_port *port,
@@ -72,6 +88,9 @@ static int sparx5_port_attr_set(struct net_device *dev, const void *ctx,
        struct sparx5_port *port = netdev_priv(dev);
 
        switch (attr->id) {
+       case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
+               return sparx5_port_attr_pre_bridge_flags(port,
+                                                        attr->u.brport_flags);
        case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
                sparx5_port_attr_bridge_flags(port, attr->u.brport_flags);
                break;