l2_fwd[from].reach_port &= ~BIT(to);
 }
 
+static bool sja1105_can_forward(struct sja1105_l2_forwarding_entry *l2_fwd,
+                               int from, int to)
+{
+       return !!(l2_fwd[from].reach_port & BIT(to));
+}
+
 /* Structure used to temporarily transport device tree
  * settings into sja1105_setup
  */
                for (j = 0; j < SJA1105_NUM_TC; j++)
                        l2fwd[i].vlan_pmap[j] = j;
 
+               /* All ports start up with egress flooding enabled,
+                * including the CPU port.
+                */
+               priv->ucast_egress_floods |= BIT(i);
+               priv->bcast_egress_floods |= BIT(i);
+
                if (i == upstream)
                        continue;
 
        return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid);
 }
 
+/* Common function for unicast and broadcast flood configuration.
+ * Flooding is configured between each {ingress, egress} port pair, and since
+ * the bridge's semantics are those of "egress flooding", it means we must
+ * enable flooding towards this port from all ingress ports that are in the
+ * same forwarding domain.
+ */
+static int sja1105_manage_flood_domains(struct sja1105_private *priv)
+{
+       struct sja1105_l2_forwarding_entry *l2_fwd;
+       struct dsa_switch *ds = priv->ds;
+       int from, to, rc;
+
+       l2_fwd = priv->static_config.tables[BLK_IDX_L2_FORWARDING].entries;
+
+       for (from = 0; from < ds->num_ports; from++) {
+               u64 fl_domain = 0, bc_domain = 0;
+
+               for (to = 0; to < priv->ds->num_ports; to++) {
+                       if (!sja1105_can_forward(l2_fwd, from, to))
+                               continue;
+
+                       if (priv->ucast_egress_floods & BIT(to))
+                               fl_domain |= BIT(to);
+                       if (priv->bcast_egress_floods & BIT(to))
+                               bc_domain |= BIT(to);
+               }
+
+               /* Nothing changed, nothing to do */
+               if (l2_fwd[from].fl_domain == fl_domain &&
+                   l2_fwd[from].bc_domain == bc_domain)
+                       continue;
+
+               l2_fwd[from].fl_domain = fl_domain;
+               l2_fwd[from].bc_domain = bc_domain;
+
+               rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_FORWARDING,
+                                                 from, &l2_fwd[from], true);
+               if (rc < 0)
+                       return rc;
+       }
+
+       return 0;
+}
+
 static int sja1105_bridge_member(struct dsa_switch *ds, int port,
                                 struct net_device *br, bool member)
 {
                        return rc;
        }
 
-       return sja1105_dynamic_config_write(priv, BLK_IDX_L2_FORWARDING,
-                                           port, &l2_fwd[port], true);
+       rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_FORWARDING,
+                                         port, &l2_fwd[port], true);
+       if (rc)
+               return rc;
+
+       return sja1105_manage_flood_domains(priv);
 }
 
 static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
        return 0;
 }
 
-/* Common function for unicast and broadcast flood configuration.
- * Flooding is configured between each {ingress, egress} port pair, and since
- * the bridge's semantics are those of "egress flooding", it means we must
- * enable flooding towards this port from all ingress ports that are in the
- * same bridge. In practice, we just enable flooding from all possible ingress
- * ports regardless of whether they're in the same bridge or not, since the
- * reach_port configuration will not allow flooded frames to leak across
- * bridging domains anyway.
- */
 static int sja1105_port_ucast_bcast_flood(struct sja1105_private *priv, int to,
                                          struct switchdev_brport_flags flags)
 {
-       struct sja1105_l2_forwarding_entry *l2_fwd;
-       int from, rc;
-
-       l2_fwd = priv->static_config.tables[BLK_IDX_L2_FORWARDING].entries;
-
-       for (from = 0; from < priv->ds->num_ports; from++) {
-               if (dsa_is_unused_port(priv->ds, from))
-                       continue;
-               if (from == to)
-                       continue;
-
-               /* Unicast */
-               if (flags.mask & BR_FLOOD) {
-                       if (flags.val & BR_FLOOD)
-                               l2_fwd[from].fl_domain |= BIT(to);
-                       else
-                               l2_fwd[from].fl_domain &= ~BIT(to);
-               }
-               /* Broadcast */
-               if (flags.mask & BR_BCAST_FLOOD) {
-                       if (flags.val & BR_BCAST_FLOOD)
-                               l2_fwd[from].bc_domain |= BIT(to);
-                       else
-                               l2_fwd[from].bc_domain &= ~BIT(to);
-               }
+       if (flags.mask & BR_FLOOD) {
+               if (flags.val & BR_FLOOD)
+                       priv->ucast_egress_floods |= BIT(to);
+               else
+                       priv->ucast_egress_floods |= BIT(to);
+       }
 
-               rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_FORWARDING,
-                                                 from, &l2_fwd[from], true);
-               if (rc < 0)
-                       return rc;
+       if (flags.mask & BR_BCAST_FLOOD) {
+               if (flags.val & BR_BCAST_FLOOD)
+                       priv->bcast_egress_floods |= BIT(to);
+               else
+                       priv->bcast_egress_floods |= BIT(to);
        }
 
-       return 0;
+       return sja1105_manage_flood_domains(priv);
 }
 
 static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to,