diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 1704f71c72500cbe39f476e92b8d9633ccc7b132..0a7cf432adf35c4b5f40d9efb8def06f1f5a2e98 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -3792,26 +3792,42 @@ static void efx_ef10_filter_uc_addr_list(struct efx_nic *efx, bool *promisc)
 static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx, bool *promisc)
 {
 	struct efx_ef10_filter_table *table = efx->filter_state;
+	struct efx_ef10_nic_data *nic_data = efx->nic_data;
 	struct net_device *net_dev = efx->net_dev;
 	struct netdev_hw_addr *mc;
-	unsigned int i;
+	unsigned int i, addr_count;
 
-	if (netdev_mc_count(net_dev) + 2 /* room for broadcast and promisc */
-	    >= EFX_EF10_FILTER_DEV_MC_MAX) {
-		table->dev_mc_count = 1;
-		eth_broadcast_addr(table->dev_mc_list[0].addr);
+	if (net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI))
 		*promisc = true;
+
+	if (nic_data->workaround_26807) {
+		if (*promisc) {
+			table->dev_mc_count = 0;
+			return;
+		}
+		addr_count = netdev_mc_count(net_dev);
 	} else {
-		table->dev_mc_count = 1 + netdev_mc_count(net_dev);
-		eth_broadcast_addr(table->dev_mc_list[0].addr);
-		i = 1;
-		netdev_for_each_mc_addr(mc, net_dev) {
-			ether_addr_copy(table->dev_mc_list[i].addr, mc->addr);
-			i++;
+		/* Allow room for broadcast and promiscuous */
+		addr_count = netdev_mc_count(net_dev) + 2;
+	}
+
+	if (addr_count >= EFX_EF10_FILTER_DEV_MC_MAX) {
+		if (nic_data->workaround_26807) {
+			table->dev_mc_count = 0;
+		} else {
+			table->dev_mc_count = 1;
+			eth_broadcast_addr(table->dev_mc_list[0].addr);
 		}
+		*promisc = true;
+		return;
+	}
 
-		if (net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI))
-			*promisc = true;
+	table->dev_mc_count = 1 + netdev_mc_count(net_dev);
+	eth_broadcast_addr(table->dev_mc_list[0].addr);
+	i = 1;
+	netdev_for_each_mc_addr(mc, net_dev) {
+		ether_addr_copy(table->dev_mc_list[i].addr, mc->addr);
+		i++;
 	}
 }
 
@@ -3846,7 +3862,11 @@ static void efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
 			 * filter for multicast
 			 */
 			while (i--) {
-				if (multicast && i == 1)
+				struct efx_ef10_nic_data *nic_data =
+					efx->nic_data;
+
+				if (multicast && i == 1 &&
+				    !nic_data->workaround_26807)
 					break;
 
 				efx_ef10_filter_remove_safe(
@@ -3974,6 +3994,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
 static void efx_ef10_filter_sync_rx_mode(struct efx_nic *efx)
 {
 	struct efx_ef10_filter_table *table = efx->filter_state;
+	struct efx_ef10_nic_data *nic_data = efx->nic_data;
 	struct net_device *net_dev = efx->net_dev;
 	bool uc_promisc = false, mc_promisc = false;
 
@@ -3995,9 +4016,16 @@ static void efx_ef10_filter_sync_rx_mode(struct efx_nic *efx)
 
 	/* Insert/renew filters */
 	efx_ef10_filter_insert_addr_list(efx, false, &uc_promisc);
+
+	/* If changing promiscuous state with cascaded multicast filters, remove
+	 * old filters first, so that packets are dropped rather than duplicated
+	 */
+	if (nic_data->workaround_26807 && efx->mc_promisc != mc_promisc)
+		efx_ef10_filter_remove_old(efx);
 	efx_ef10_filter_insert_addr_list(efx, true, &mc_promisc);
 
 	efx_ef10_filter_remove_old(efx);
+	efx->mc_promisc = mc_promisc;
 }
 
 static int efx_ef10_set_mac_address(struct efx_nic *efx)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 47d1e3a96522668a1cf1c80cacd141d2afbf1193..4d35313a239db77d0d90a273e1d02aa6dfaabd81 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -925,6 +925,7 @@ struct vfdi_status;
  * @stats_lock: Statistics update lock. Must be held when calling
  *	efx_nic_type::{update,start,stop}_stats.
  * @n_rx_noskb_drops: Count of RX packets dropped due to failure to allocate an skb
+ * @mc_promisc: Whether in multicast promiscuous mode when last changed
  *
  * This is stored in the private area of the &struct net_device.
  */
@@ -1072,6 +1073,7 @@ struct efx_nic {
 	int last_irq_cpu;
 	spinlock_t stats_lock;
 	atomic_t n_rx_noskb_drops;
+	bool mc_promisc;
 };
 
 static inline int efx_dev_registered(struct efx_nic *efx)