realtek: remove store_mcgroups/load_mcgroups
authorJan Hoffmann <jan@3e8.eu>
Sat, 6 May 2023 23:05:34 +0000 (01:05 +0200)
committerSander Vanheule <sander@svanheule.net>
Sun, 7 May 2023 17:15:34 +0000 (19:15 +0200)
The current implementation only works when store and load are called for
the same port without any other calls in between. This is because the
store function only saves a single port number instead of a portmask for
each group. It also doesn't take into account that the allocation of
multicast group entries might change between store/load calls.

As a result, the multicast port mask table gets corrupted. This also
includes the reserved entry for unknown multicast, which gets corrupted
even when no other mdb entries have been added.

Remove the code for storing/loading multicast groups entirely, as the
original commit message doesn't offer a convincing reason why this would
be necessary in the first place.

Fixes: 724e4af530cd ("realtek: Store and Restore MC memberships for port enable/disable")
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/rtl838x.h
target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c
target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h

index 270ec172e3937002678edce948512d49bb29324a..6e615be0e50247b5b010618af71b3caff9f8bc10 100644 (file)
@@ -1032,31 +1032,6 @@ static u64 rtl83xx_mc_group_del_port(struct rtl838x_switch_priv *priv, int mc_gr
        return portmask;
 }
 
-static void store_mcgroups(struct rtl838x_switch_priv *priv, int port)
-{
-       int mc_group;
-
-       for (mc_group = 0; mc_group < MAX_MC_GROUPS; mc_group++) {
-               u64 portmask = priv->r->read_mcast_pmask(mc_group);
-               if (portmask & BIT_ULL(port)) {
-                       priv->mc_group_saves[mc_group] = port;
-                       rtl83xx_mc_group_del_port(priv, mc_group, port);
-               }
-       }
-}
-
-static void load_mcgroups(struct rtl838x_switch_priv *priv, int port)
-{
-       int mc_group;
-
-       for (mc_group = 0; mc_group < MAX_MC_GROUPS; mc_group++) {
-               if (priv->mc_group_saves[mc_group] == port) {
-                       rtl83xx_mc_group_add_port(priv, mc_group, port);
-                       priv->mc_group_saves[mc_group] = -1;
-               }
-       }
-}
-
 static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
                                struct phy_device *phydev)
 {
@@ -1075,8 +1050,6 @@ static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
        /* add port to switch mask of CPU_PORT */
        priv->r->traffic_enable(priv->cpu_port, port);
 
-       load_mcgroups(priv, port);
-
        if (priv->is_lagmember[port]) {
                pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
                return 0;
@@ -1112,7 +1085,6 @@ static void rtl83xx_port_disable(struct dsa_switch *ds, int port)
        // BUG: This does not work on RTL931X
        /* remove port from switch mask of CPU_PORT */
        priv->r->traffic_disable(priv->cpu_port, port);
-       store_mcgroups(priv, port);
 
        /* remove all other ports in the same bridge from switch mask of port */
        v = priv->r->traffic_get(port);
@@ -1212,7 +1184,6 @@ static int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
                        port_bitmap |= BIT_ULL(i);
                }
        }
-       load_mcgroups(priv, port);
 
        /* Add all other ports to this port matrix. */
        if (priv->ports[port].enable) {
@@ -1257,7 +1228,6 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                        port_bitmap |= BIT_ULL(i);
                }
        }
-       store_mcgroups(priv, port);
 
        /* Remove all other ports from this port matrix. */
        if (priv->ports[port].enable) {
index 3f1f1d49f8e711bcd7e13d65aed02b4da6daefd6..81656799a7f1af65a51e202e9b40ce0b0b2fd109 100644 (file)
@@ -1086,7 +1086,6 @@ struct rtl838x_switch_priv {
        struct notifier_block fib_nb;
        bool eee_enabled;
        unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5];
-       int mc_group_saves[MAX_MC_GROUPS];
        int n_pie_blocks;
        struct rhashtable tc_ht;
        unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5];
index b4cb39ed5d8f0792eaa7a916d55a76f96636e6f5..df78aa3737fa0facf94e8dc76e82664424b381fc 100644 (file)
@@ -1019,27 +1019,6 @@ static u64 rtl83xx_mc_group_del_port(struct rtl838x_switch_priv *priv, int mc_gr
        return portmask;
 }
 
-static void store_mcgroups(struct rtl838x_switch_priv *priv, int port)
-{
-       for (int mc_group = 0; mc_group < MAX_MC_GROUPS; mc_group++) {
-               u64 portmask = priv->r->read_mcast_pmask(mc_group);
-               if (portmask & BIT_ULL(port)) {
-                       priv->mc_group_saves[mc_group] = port;
-                       rtl83xx_mc_group_del_port(priv, mc_group, port);
-               }
-       }
-}
-
-static void load_mcgroups(struct rtl838x_switch_priv *priv, int port)
-{
-       for (int mc_group = 0; mc_group < MAX_MC_GROUPS; mc_group++) {
-               if (priv->mc_group_saves[mc_group] == port) {
-                       rtl83xx_mc_group_add_port(priv, mc_group, port);
-                       priv->mc_group_saves[mc_group] = -1;
-               }
-       }
-}
-
 static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
                                struct phy_device *phydev)
 {
@@ -1058,8 +1037,6 @@ static int rtl83xx_port_enable(struct dsa_switch *ds, int port,
        /* add port to switch mask of CPU_PORT */
        priv->r->traffic_enable(priv->cpu_port, port);
 
-       load_mcgroups(priv, port);
-
        if (priv->is_lagmember[port]) {
                pr_debug("%s: %d is lag slave. ignore\n", __func__, port);
                return 0;
@@ -1095,7 +1072,6 @@ static void rtl83xx_port_disable(struct dsa_switch *ds, int port)
        /* BUG: This does not work on RTL931X */
        /* remove port from switch mask of CPU_PORT */
        priv->r->traffic_disable(priv->cpu_port, port);
-       store_mcgroups(priv, port);
 
        /* remove all other ports in the same bridge from switch mask of port */
        v = priv->r->traffic_get(port);
@@ -1197,7 +1173,6 @@ static int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port,
                        port_bitmap |= BIT_ULL(i);
                }
        }
-       load_mcgroups(priv, port);
 
        /* Add all other ports to this port matrix. */
        if (priv->ports[port].enable) {
@@ -1241,7 +1216,6 @@ static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port,
                        port_bitmap |= BIT_ULL(i);
                }
        }
-       store_mcgroups(priv, port);
 
        /* Remove all other ports from this port matrix. */
        if (priv->ports[port].enable) {
index bfab576e06ecedebe6f12eebd8a12fe0b4cba50f..24d18d61fafde3eb9f9218a7b39620441638901c 100644 (file)
@@ -1082,7 +1082,6 @@ struct rtl838x_switch_priv {
        struct notifier_block fib_nb;
        bool eee_enabled;
        unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5];
-       int mc_group_saves[MAX_MC_GROUPS];
        int n_pie_blocks;
        struct rhashtable tc_ht;
        unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5];