net: lan966x: Extend switchdev bridge flags
authorHoratiu Vultur <horatiu.vultur@microchip.com>
Sat, 18 Dec 2021 21:49:45 +0000 (22:49 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Dec 2021 11:44:06 +0000 (11:44 +0000)
Currently allow a port to be part or not of the multicast flooding mask.
By implementing the switchdev calls SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS
and SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c

index 81e37624b553bf00a7b9976e2e2b79238084d68c..af058700a95bc836c344947f5931ad23a7d4a21d 100644 (file)
@@ -9,6 +9,39 @@ static struct notifier_block lan966x_netdevice_nb __read_mostly;
 static struct notifier_block lan966x_switchdev_nb __read_mostly;
 static struct notifier_block lan966x_switchdev_blocking_nb __read_mostly;
 
+static void lan966x_port_set_mcast_flood(struct lan966x_port *port,
+                                        bool enabled)
+{
+       u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_MC));
+
+       val = ANA_PGID_PGID_GET(val);
+       if (enabled)
+               val |= BIT(port->chip_port);
+       else
+               val &= ~BIT(port->chip_port);
+
+       lan_rmw(ANA_PGID_PGID_SET(val),
+               ANA_PGID_PGID,
+               port->lan966x, ANA_PGID(PGID_MC));
+}
+
+static void lan966x_port_bridge_flags(struct lan966x_port *port,
+                                     struct switchdev_brport_flags flags)
+{
+       if (flags.mask & BR_MCAST_FLOOD)
+               lan966x_port_set_mcast_flood(port,
+                                            !!(flags.val & BR_MCAST_FLOOD));
+}
+
+static int lan966x_port_pre_bridge_flags(struct lan966x_port *port,
+                                        struct switchdev_brport_flags flags)
+{
+       if (flags.mask & ~BR_MCAST_FLOOD)
+               return -EINVAL;
+
+       return 0;
+}
+
 static void lan966x_update_fwd_mask(struct lan966x *lan966x)
 {
        int i;
@@ -67,6 +100,12 @@ static int lan966x_port_attr_set(struct net_device *dev, const void *ctx,
                return 0;
 
        switch (attr->id) {
+       case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+               lan966x_port_bridge_flags(port, attr->u.brport_flags);
+               break;
+       case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
+               err = lan966x_port_pre_bridge_flags(port, attr->u.brport_flags);
+               break;
        case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
                lan966x_port_stp_state_set(port, attr->u.stp_state);
                break;