net: lan966x: Update mdb when enabling/disabling mcast_snooping
authorHoratiu Vultur <horatiu.vultur@microchip.com>
Fri, 4 Feb 2022 09:14:52 +0000 (10:14 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 5 Feb 2022 15:00:43 +0000 (15:00 +0000)
When the multicast snooping is disabled, the mdb entries should be
removed from the HW, but they still need to be kept in memory for when
the mcast_snooping will be enabled again.

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

index 31fc542..058e435 100644 (file)
@@ -267,6 +267,8 @@ int lan966x_handle_port_mdb_del(struct lan966x_port *port,
                                const struct switchdev_obj *obj);
 void lan966x_mdb_erase_entries(struct lan966x *lan966x, u16 vid);
 void lan966x_mdb_write_entries(struct lan966x *lan966x, u16 vid);
+void lan966x_mdb_clear_entries(struct lan966x *lan966x);
+void lan966x_mdb_restore_entries(struct lan966x *lan966x);
 
 int lan966x_ptp_init(struct lan966x *lan966x);
 void lan966x_ptp_deinit(struct lan966x *lan966x);
index c68d0a9..2af5526 100644 (file)
@@ -504,3 +504,48 @@ void lan966x_mdb_erase_entries(struct lan966x *lan966x, u16 vid)
                        lan966x_mdb_l2_cpu_remove(lan966x, mdb_entry, type);
        }
 }
+
+void lan966x_mdb_clear_entries(struct lan966x *lan966x)
+{
+       struct lan966x_mdb_entry *mdb_entry;
+       enum macaccess_entry_type type;
+       unsigned char mac[ETH_ALEN];
+
+       list_for_each_entry(mdb_entry, &lan966x->mdb_entries, list) {
+               type = lan966x_mdb_classify(mdb_entry->mac);
+
+               lan966x_mdb_encode_mac(mac, mdb_entry, type);
+               /* Remove just the MAC entry, still keep the PGID in case of L2
+                * entries because this can be restored at later point
+                */
+               lan966x_mac_forget(lan966x, mac, mdb_entry->vid, type);
+       }
+}
+
+void lan966x_mdb_restore_entries(struct lan966x *lan966x)
+{
+       struct lan966x_mdb_entry *mdb_entry;
+       enum macaccess_entry_type type;
+       unsigned char mac[ETH_ALEN];
+       bool cpu_copy = false;
+
+       list_for_each_entry(mdb_entry, &lan966x->mdb_entries, list) {
+               type = lan966x_mdb_classify(mdb_entry->mac);
+
+               lan966x_mdb_encode_mac(mac, mdb_entry, type);
+               if (type == ENTRYTYPE_MACV4 || type == ENTRYTYPE_MACV6) {
+                       /* Copy the frame to CPU only if the CPU is in the VLAN */
+                       if (lan966x_vlan_cpu_member_cpu_vlan_mask(lan966x,
+                                                                 mdb_entry->vid) &&
+                           mdb_entry->cpu_copy)
+                               cpu_copy = true;
+
+                       lan966x_mac_ip_learn(lan966x, cpu_copy, mac,
+                                            mdb_entry->vid, type);
+               } else {
+                       lan966x_mac_learn(lan966x, mdb_entry->pgid->index,
+                                         mdb_entry->mac,
+                                         mdb_entry->vid, type);
+               }
+       }
+}
index cf2535c..9fce865 100644 (file)
@@ -185,6 +185,10 @@ static void lan966x_port_mc_set(struct lan966x_port *port, bool mcast_ena)
        struct lan966x *lan966x = port->lan966x;
 
        port->mcast_ena = mcast_ena;
+       if (mcast_ena)
+               lan966x_mdb_restore_entries(lan966x);
+       else
+               lan966x_mdb_clear_entries(lan966x);
 
        lan_rmw(ANA_CPU_FWD_CFG_IGMP_REDIR_ENA_SET(mcast_ena) |
                ANA_CPU_FWD_CFG_MLD_REDIR_ENA_SET(mcast_ena) |