diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index e295891c06..b34df416a2 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -210,13 +210,17 @@ virtual_ethdev_stats_reset(struct rte_eth_dev *dev)
 	memset(&dev_private->eth_stats, 0, sizeof(dev_private->eth_stats));
 }
 
-static void
+static int
 virtual_ethdev_promiscuous_mode_enable(struct rte_eth_dev *dev __rte_unused)
-{}
+{
+	return 0;
+}
 
-static void
+static int
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
-{}
+{
+	return 0;
+}
 
 static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index 66131b53e7..0495727281 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -458,41 +458,47 @@ eth_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask)
 {
 	struct ifreq ifr;
+	int ret = 0;
 	int s;
 
 	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s < 0)
-		return;
+		return -errno;
 
 	strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
-	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
+	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
+		ret = -errno;
 		goto out;
+	}
 	ifr.ifr_flags &= mask;
 	ifr.ifr_flags |= flags;
-	if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
+	if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) {
+		ret = -errno;
 		goto out;
+	}
 out:
 	close(s);
+	return ret;
 }
 
-static void
+static int
 eth_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
+	return eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
 }
 
-static void
+static int
 eth_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
+	return eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c
index aa716f3195..1da22ff866 100644
--- a/drivers/net/af_xdp/rte_eth_af_xdp.c
+++ b/drivers/net/af_xdp/rte_eth_af_xdp.c
@@ -750,37 +750,43 @@ static void
 eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask)
 {
 	struct ifreq ifr;
+	int ret = 0;
 	int s;
 
 	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s < 0)
-		return;
+		return -errno;
 
 	strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
-	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
+	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
+		ret = -errno;
 		goto out;
+	}
 	ifr.ifr_flags &= mask;
 	ifr.ifr_flags |= flags;
-	if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
+	if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) {
+		ret = -errno;
 		goto out;
+	}
 out:
 	close(s);
+	return ret;
 }
 
-static void
+static int
 eth_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
+	return eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
 }
 
-static void
+static int
 eth_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
 
-	eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
+	return eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index b056f8229a..5018529da1 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -24,8 +24,8 @@ static int  atl_dev_set_link_up(struct rte_eth_dev *dev);
 static int  atl_dev_set_link_down(struct rte_eth_dev *dev);
 static void atl_dev_close(struct rte_eth_dev *dev);
 static int  atl_dev_reset(struct rte_eth_dev *dev);
-static void atl_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void atl_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int  atl_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int  atl_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void atl_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void atl_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int  atl_dev_link_update(struct rte_eth_dev *dev, int wait);
@@ -1207,20 +1207,24 @@ atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 	return 0;
 }
 
-static void
+static int
 atl_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw_atl_rpfl2promiscuous_mode_en_set(hw, true);
+
+	return 0;
 }
 
-static void
+static int
 atl_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw_atl_rpfl2promiscuous_mode_en_set(hw, false);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index c5801f319a..050901990c 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -45,8 +45,8 @@ static int avp_dev_info_get(struct rte_eth_dev *dev,
 			    struct rte_eth_dev_info *dev_info);
 static int avp_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static int avp_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete);
-static void avp_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void avp_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int avp_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int avp_dev_promiscuous_disable(struct rte_eth_dev *dev);
 
 static int avp_dev_rx_queue_setup(struct rte_eth_dev *dev,
 				  uint16_t rx_queue_id,
@@ -2157,7 +2157,7 @@ avp_dev_link_update(struct rte_eth_dev *eth_dev,
 	return -1;
 }
 
-static void
+static int
 avp_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
@@ -2169,9 +2169,11 @@ avp_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 			    eth_dev->data->port_id);
 	}
 	rte_spinlock_unlock(&avp->lock);
+
+	return 0;
 }
 
-static void
+static int
 avp_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
 	struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
@@ -2183,6 +2185,8 @@ avp_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 			    eth_dev->data->port_id);
 	}
 	rte_spinlock_unlock(&avp->lock);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 5a7da75126..c43b5bfb6f 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -15,8 +15,8 @@ static int  axgbe_dev_start(struct rte_eth_dev *dev);
 static void axgbe_dev_stop(struct rte_eth_dev *dev);
 static void axgbe_dev_interrupt_handler(void *param);
 static void axgbe_dev_close(struct rte_eth_dev *dev);
-static void axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int axgbe_dev_link_update(struct rte_eth_dev *dev,
@@ -236,7 +236,7 @@ axgbe_dev_close(struct rte_eth_dev *dev)
 	axgbe_dev_clear_queues(dev);
 }
 
-static void
+static int
 axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct axgbe_port *pdata = dev->data->dev_private;
@@ -244,9 +244,11 @@ axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 1);
+
+	return 0;
 }
 
-static void
+static int
 axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct axgbe_port *pdata = dev->data->dev_private;
@@ -254,6 +256,8 @@ axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	PMD_INIT_FUNC_TRACE();
 
 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 0);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index b7359514e5..07168e9a8a 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -292,7 +292,7 @@ bnx2x_dev_close(struct rte_eth_dev *dev)
 	bnx2x_free_ilt_mem(sc);
 }
 
-static void
+static int
 bnx2x_promisc_enable(struct rte_eth_dev *dev)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
@@ -302,9 +302,11 @@ bnx2x_promisc_enable(struct rte_eth_dev *dev)
 	if (rte_eth_allmulticast_get(dev->data->port_id) == 1)
 		sc->rx_mode = BNX2X_RX_MODE_ALLMULTI_PROMISC;
 	bnx2x_set_rx_mode(sc);
+
+	return 0;
 }
 
-static void
+static int
 bnx2x_promisc_disable(struct rte_eth_dev *dev)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
@@ -314,6 +316,8 @@ bnx2x_promisc_disable(struct rte_eth_dev *dev)
 	if (rte_eth_allmulticast_get(dev->data->port_id) == 1)
 		sc->rx_mode = BNX2X_RX_MODE_ALLMULTI;
 	bnx2x_set_rx_mode(sc);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index b521a72963..7fff5d5b8f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1006,32 +1006,46 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
 	return rc;
 }
 
-static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
+static int bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	struct bnxt_vnic_info *vnic;
+	uint32_t old_flags;
+	int rc;
 
 	if (bp->vnic_info == NULL)
-		return;
+		return 0;
 
 	vnic = &bp->vnic_info[0];
 
+	old_flags = vnic->flags;
 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	if (rc != 0)
+		vnic->flags = old_flags;
+
+	return rc;
 }
 
-static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
+static int bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	struct bnxt_vnic_info *vnic;
+	uint32_t old_flags;
+	int rc;
 
 	if (bp->vnic_info == NULL)
-		return;
+		return 0;
 
 	vnic = &bp->vnic_info[0];
 
+	old_flags = vnic->flags;
 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	if (rc != 0)
+		vnic->flags = old_flags;
+
+	return rc;
 }
 
 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index edf660db34..f9b7b595df 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1915,7 +1915,7 @@ bond_ethdev_primary_set(struct bond_dev_private *internals,
 		}
 }
 
-static void
+static int
 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 
 static int
@@ -2482,7 +2482,7 @@ bond_ethdev_stats_reset(struct rte_eth_dev *dev)
 		rte_eth_stats_reset(internals->slaves[i].port_id);
 }
 
-static void
+static int
 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct bond_dev_private *internals = eth_dev->data->dev_private;
@@ -2495,7 +2495,9 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 	case BONDING_MODE_ROUND_ROBIN:
 	case BONDING_MODE_BALANCE:
 	case BONDING_MODE_BROADCAST:
-	case BONDING_MODE_8023AD:
+	case BONDING_MODE_8023AD: {
+		unsigned int slave_ok = 0;
+
 		for (i = 0; i < internals->slave_count; i++) {
 			port_id = internals->slaves[i].port_id;
 
@@ -2504,8 +2506,17 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 				RTE_BOND_LOG(ERR,
 					"Failed to enable promiscuous mode for port %u: %s",
 					port_id, rte_strerror(-ret));
+			else
+				slave_ok++;
 		}
+		/*
+		 * Report success if operation is successful on at least
+		 * on one slave. Otherwise return last error code.
+		 */
+		if (slave_ok > 0)
+			ret = 0;
 		break;
+	}
 	/* Promiscuous mode is propagated only to primary slave */
 	case BONDING_MODE_ACTIVE_BACKUP:
 	case BONDING_MODE_TLB:
@@ -2521,14 +2532,16 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 				"Failed to enable promiscuous mode for port %u: %s",
 				port_id, rte_strerror(-ret));
 	}
+
+	return ret;
 }
 
-static void
+static int
 bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct bond_dev_private *internals = dev->data->dev_private;
 	int i;
-	int ret;
+	int ret = 0;
 	uint16_t port_id;
 
 	switch (internals->mode) {
@@ -2536,21 +2549,34 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
 	case BONDING_MODE_ROUND_ROBIN:
 	case BONDING_MODE_BALANCE:
 	case BONDING_MODE_BROADCAST:
-	case BONDING_MODE_8023AD:
+	case BONDING_MODE_8023AD: {
+		unsigned int slave_ok = 0;
+
 		for (i = 0; i < internals->slave_count; i++) {
 			port_id = internals->slaves[i].port_id;
 
 			if (internals->mode == BONDING_MODE_8023AD &&
 			    bond_mode_8023ad_ports[port_id].forced_rx_flags ==
-					BOND_8023AD_FORCED_PROMISC)
+					BOND_8023AD_FORCED_PROMISC) {
+				slave_ok++;
 				continue;
+			}
 			ret = rte_eth_promiscuous_disable(port_id);
 			if (ret != 0)
 				RTE_BOND_LOG(ERR,
 					"Failed to disable promiscuous mode for port %u: %s",
 					port_id, rte_strerror(-ret));
+			else
+				slave_ok++;
 		}
+		/*
+		 * Report success if operation is successful on at least
+		 * on one slave. Otherwise return last error code.
+		 */
+		if (slave_ok > 0)
+			ret = 0;
 		break;
+	}
 	/* Promiscuous mode is propagated only to primary slave */
 	case BONDING_MODE_ACTIVE_BACKUP:
 	case BONDING_MODE_TLB:
@@ -2566,6 +2592,8 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
 				"Failed to disable promiscuous mode for port %u: %s",
 				port_id, rte_strerror(-ret));
 	}
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 19c2a3c4db..be001a0d24 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -150,22 +150,22 @@ int cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
+int cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
 
-	t4_set_rxmode(adapter, adapter->mbox, pi->viid, -1,
-		      1, -1, 1, -1, false);
+	return t4_set_rxmode(adapter, adapter->mbox, pi->viid, -1,
+			     1, -1, 1, -1, false);
 }
 
-void cxgbe_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
+int cxgbe_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
 
-	t4_set_rxmode(adapter, adapter->mbox, pi->viid, -1,
-		      0, -1, 1, -1, false);
+	return t4_set_rxmode(adapter, adapter->mbox, pi->viid, -1,
+			     0, -1, 1, -1, false);
 }
 
 void cxgbe_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 011ec13860..bfa07ba555 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -12,8 +12,8 @@ void cxgbe_dev_stop(struct rte_eth_dev *eth_dev);
 void cxgbe_dev_close(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 		       struct rte_eth_dev_info *device_info);
-void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
-void cxgbe_dev_promiscuous_disable(struct rte_eth_dev *eth_dev);
+int cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
+int cxgbe_dev_promiscuous_disable(struct rte_eth_dev *eth_dev);
 void cxgbe_dev_allmulticast_enable(struct rte_eth_dev *eth_dev);
 void cxgbe_dev_allmulticast_disable(struct rte_eth_dev *eth_dev);
 int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *addr);
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 25deadb949..ad28c110d7 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -514,22 +514,26 @@ dpaa_xstats_get_names_by_id(
 	return limit;
 }
 
-static void dpaa_eth_promiscuous_enable(struct rte_eth_dev *dev)
+static int dpaa_eth_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct dpaa_if *dpaa_intf = dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
 
 	fman_if_promiscuous_enable(dpaa_intf->fif);
+
+	return 0;
 }
 
-static void dpaa_eth_promiscuous_disable(struct rte_eth_dev *dev)
+static int dpaa_eth_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct dpaa_if *dpaa_intf = dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
 
 	fman_if_promiscuous_disable(dpaa_intf->fif);
+
+	return 0;
 }
 
 static void dpaa_eth_multicast_enable(struct rte_eth_dev *dev)
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 879bbc120d..d9cc2c3510 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -987,7 +987,7 @@ dpaa2_dev_close(struct rte_eth_dev *dev)
 	rte_eth_linkstatus_set(dev, &link);
 }
 
-static void
+static int
 dpaa2_dev_promiscuous_enable(
 		struct rte_eth_dev *dev)
 {
@@ -999,7 +999,7 @@ dpaa2_dev_promiscuous_enable(
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -ENODEV;
 	}
 
 	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
@@ -1009,9 +1009,11 @@ dpaa2_dev_promiscuous_enable(
 	ret = dpni_set_multicast_promisc(dpni, CMD_PRI_LOW, priv->token, true);
 	if (ret < 0)
 		DPAA2_PMD_ERR("Unable to enable M promisc mode %d", ret);
+
+	return ret;
 }
 
-static void
+static int
 dpaa2_dev_promiscuous_disable(
 		struct rte_eth_dev *dev)
 {
@@ -1023,7 +1025,7 @@ dpaa2_dev_promiscuous_disable(
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -ENODEV;
 	}
 
 	ret = dpni_set_unicast_promisc(dpni, CMD_PRI_LOW, priv->token, false);
@@ -1037,6 +1039,8 @@ dpaa2_dev_promiscuous_disable(
 			DPAA2_PMD_ERR("Unable to disable M promisc mode %d",
 				      ret);
 	}
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 305588f9b3..b23e840376 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -35,8 +35,8 @@ static int eth_em_configure(struct rte_eth_dev *dev);
 static int eth_em_start(struct rte_eth_dev *dev);
 static void eth_em_stop(struct rte_eth_dev *dev);
 static void eth_em_close(struct rte_eth_dev *dev);
-static void eth_em_promiscuous_enable(struct rte_eth_dev *dev);
-static void eth_em_promiscuous_disable(struct rte_eth_dev *dev);
+static int eth_em_promiscuous_enable(struct rte_eth_dev *dev);
+static int eth_em_promiscuous_disable(struct rte_eth_dev *dev);
 static void eth_em_allmulticast_enable(struct rte_eth_dev *dev);
 static void eth_em_allmulticast_disable(struct rte_eth_dev *dev);
 static int eth_em_link_update(struct rte_eth_dev *dev,
@@ -1263,7 +1263,7 @@ em_release_manageability(struct e1000_hw *hw)
 	}
 }
 
-static void
+static int
 eth_em_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw =
@@ -1273,9 +1273,11 @@ eth_em_promiscuous_enable(struct rte_eth_dev *dev)
 	rctl = E1000_READ_REG(hw, E1000_RCTL);
 	rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+	return 0;
 }
 
-static void
+static int
 eth_em_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw =
@@ -1289,6 +1291,8 @@ eth_em_promiscuous_disable(struct rte_eth_dev *dev)
 	else
 		rctl &= (~E1000_RCTL_MPE);
 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 6172f9ac64..a9f6de5d52 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -79,8 +79,8 @@ static int  eth_igb_dev_set_link_up(struct rte_eth_dev *dev);
 static int  eth_igb_dev_set_link_down(struct rte_eth_dev *dev);
 static void eth_igb_close(struct rte_eth_dev *dev);
 static int eth_igb_reset(struct rte_eth_dev *dev);
-static void eth_igb_promiscuous_enable(struct rte_eth_dev *dev);
-static void eth_igb_promiscuous_disable(struct rte_eth_dev *dev);
+static int  eth_igb_promiscuous_enable(struct rte_eth_dev *dev);
+static int  eth_igb_promiscuous_disable(struct rte_eth_dev *dev);
 static void eth_igb_allmulticast_enable(struct rte_eth_dev *dev);
 static void eth_igb_allmulticast_disable(struct rte_eth_dev *dev);
 static int  eth_igb_link_update(struct rte_eth_dev *dev,
@@ -156,8 +156,8 @@ static int igbvf_dev_configure(struct rte_eth_dev *dev);
 static int igbvf_dev_start(struct rte_eth_dev *dev);
 static void igbvf_dev_stop(struct rte_eth_dev *dev);
 static void igbvf_dev_close(struct rte_eth_dev *dev);
-static void igbvf_promiscuous_enable(struct rte_eth_dev *dev);
-static void igbvf_promiscuous_disable(struct rte_eth_dev *dev);
+static int igbvf_promiscuous_enable(struct rte_eth_dev *dev);
+static int igbvf_promiscuous_disable(struct rte_eth_dev *dev);
 static void igbvf_allmulticast_enable(struct rte_eth_dev *dev);
 static void igbvf_allmulticast_disable(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
@@ -2519,7 +2519,7 @@ igb_release_manageability(struct e1000_hw *hw)
 	}
 }
 
-static void
+static int
 eth_igb_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw =
@@ -2529,9 +2529,11 @@ eth_igb_promiscuous_enable(struct rte_eth_dev *dev)
 	rctl = E1000_READ_REG(hw, E1000_RCTL);
 	rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+	return 0;
 }
 
-static void
+static int
 eth_igb_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw =
@@ -2545,6 +2547,8 @@ eth_igb_promiscuous_disable(struct rte_eth_dev *dev)
 	else
 		rctl &= (~E1000_RCTL_MPE);
 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+	return 0;
 }
 
 static void
@@ -3390,16 +3394,18 @@ igbvf_dev_close(struct rte_eth_dev *dev)
 	igbvf_default_mac_addr_set(dev, &addr);
 }
 
-static void
+static int
 igbvf_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	/* Set both unicast and multicast promisc */
 	e1000_promisc_set_vf(hw, e1000_promisc_enabled);
+
+	return 0;
 }
 
-static void
+static int
 igbvf_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -3409,6 +3415,8 @@ igbvf_promiscuous_disable(struct rte_eth_dev *dev)
 		e1000_promisc_set_vf(hw, e1000_promisc_multicast);
 	else
 		e1000_promisc_set_vf(hw, e1000_promisc_disabled);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/enetc/enetc_ethdev.c b/drivers/net/enetc/enetc_ethdev.c
index dec42b9763..1ec66d0baf 100644
--- a/drivers/net/enetc/enetc_ethdev.c
+++ b/drivers/net/enetc/enetc_ethdev.c
@@ -523,7 +523,7 @@ enetc_dev_close(struct rte_eth_dev *dev)
 	dev->data->nb_tx_queues = 0;
 }
 
-static void
+static int
 enetc_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct enetc_eth_hw *hw =
@@ -537,9 +537,11 @@ enetc_promiscuous_enable(struct rte_eth_dev *dev)
 	psipmr |= ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0);
 
 	enetc_port_wr(enetc_hw, ENETC_PSIPMR, psipmr);
+
+	return 0;
 }
 
-static void
+static int
 enetc_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct enetc_eth_hw *hw =
@@ -555,6 +557,8 @@ enetc_promiscuous_disable(struct rte_eth_dev *dev)
 		psipmr &= (~ENETC_PSIPMR_SET_MP(0));
 
 	enetc_port_wr(enetc_hw, ENETC_PSIPMR, psipmr);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 5a92508f00..72b1e7956b 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -305,7 +305,7 @@ int enic_get_link_status(struct enic *enic);
 int enic_dev_stats_get(struct enic *enic,
 		       struct rte_eth_stats *r_stats);
 void enic_dev_stats_clear(struct enic *enic);
-void enic_add_packet_filter(struct enic *enic);
+int enic_add_packet_filter(struct enic *enic);
 int enic_set_mac_address(struct enic *enic, uint8_t *mac_addr);
 int enic_del_mac_address(struct enic *enic, int mac_index);
 unsigned int enic_cleanup_wq(struct enic *enic, struct vnic_wq *wq);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 90fdeda901..5d48930a9d 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -603,29 +603,39 @@ static const uint32_t *enicpmd_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
+static int enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return;
+		return -ENOTSUP;
 
 	ENICPMD_FUNC_TRACE();
 
 	enic->promisc = 1;
-	enic_add_packet_filter(enic);
+	ret = enic_add_packet_filter(enic);
+	if (ret != 0)
+		enic->promisc = 0;
+
+	return ret;
 }
 
-static void enicpmd_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
+static int enicpmd_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
+	int ret;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-		return;
+		return -ENOTSUP;
 
 	ENICPMD_FUNC_TRACE();
 	enic->promisc = 0;
-	enic_add_packet_filter(enic);
+	ret = enic_add_packet_filter(enic);
+	if (ret != 0)
+		enic->promisc = 1;
+
+	return ret;
 }
 
 static void enicpmd_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 40af3781b3..f4e76a057a 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1364,10 +1364,10 @@ int enic_set_vlan_strip(struct enic *enic)
 			       enic->rss_enable);
 }
 
-void enic_add_packet_filter(struct enic *enic)
+int enic_add_packet_filter(struct enic *enic)
 {
 	/* Args -> directed, multicast, broadcast, promisc, allmulti */
-	vnic_dev_packet_filter(enic->vdev, 1, 1, 1,
+	return vnic_dev_packet_filter(enic->vdev, 1, 1, 1,
 		enic->promisc, enic->allmulti);
 }
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index cbf143fb3c..8bc4dcebfd 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -654,7 +654,7 @@ fs_dev_free_queues(struct rte_eth_dev *dev)
 	dev->data->nb_tx_queues = 0;
 }
 
-static void
+static int
 fs_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
@@ -681,10 +681,10 @@ fs_promiscuous_enable(struct rte_eth_dev *dev)
 	}
 	fs_unlock(dev, 0);
 
-	return;
+	return ret;
 }
 
-static void
+static int
 fs_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
@@ -711,7 +711,7 @@ fs_promiscuous_disable(struct rte_eth_dev *dev)
 	}
 	fs_unlock(dev, 0);
 
-	return;
+	return ret;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 8cb7337ea5..f0f6290089 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -44,8 +44,8 @@ int fm10k_logtype_init;
 int fm10k_logtype_driver;
 
 static void fm10k_close_mbx_service(struct fm10k_hw *hw);
-static void fm10k_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void fm10k_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int fm10k_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int fm10k_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void fm10k_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void fm10k_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static inline int fm10k_glort_valid(struct fm10k_hw *hw);
@@ -908,7 +908,7 @@ static inline int fm10k_glort_valid(struct fm10k_hw *hw)
 		!= FM10K_DGLORTMAP_NONE);
 }
 
-static void
+static int
 fm10k_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -918,18 +918,22 @@ fm10k_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
 	/* Return if it didn't acquire valid glort range */
 	if ((hw->mac.type == fm10k_mac_pf) && !fm10k_glort_valid(hw))
-		return;
+		return 0;
 
 	fm10k_mbx_lock(hw);
 	status = hw->mac.ops.update_xcast_mode(hw, hw->mac.dglort_map,
 				FM10K_XCAST_MODE_PROMISC);
 	fm10k_mbx_unlock(hw);
 
-	if (status != FM10K_SUCCESS)
+	if (status != FM10K_SUCCESS) {
 		PMD_INIT_LOG(ERR, "Failed to enable promiscuous mode");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
-static void
+static int
 fm10k_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -940,7 +944,7 @@ fm10k_dev_promiscuous_disable(struct rte_eth_dev *dev)
 
 	/* Return if it didn't acquire valid glort range */
 	if ((hw->mac.type == fm10k_mac_pf) && !fm10k_glort_valid(hw))
-		return;
+		return 0;
 
 	if (dev->data->all_multicast == 1)
 		mode = FM10K_XCAST_MODE_ALLMULTI;
@@ -952,8 +956,12 @@ fm10k_dev_promiscuous_disable(struct rte_eth_dev *dev)
 				mode);
 	fm10k_mbx_unlock(hw);
 
-	if (status != FM10K_SUCCESS)
+	if (status != FM10K_SUCCESS) {
 		PMD_INIT_LOG(ERR, "Failed to disable promiscuous mode");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c
index 17a3625d63..c50cdd9f81 100644
--- a/drivers/net/hinic/hinic_pmd_ethdev.c
+++ b/drivers/net/hinic/hinic_pmd_ethdev.c
@@ -1325,8 +1325,12 @@ static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success,
+ *   negative error value otherwise.
  */
-static void hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
+static int hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	int rc = HINIC_OK;
 	struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
@@ -1338,6 +1342,8 @@ static void hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	rc = hinic_set_dev_promiscuous(nic_dev, true);
 	if (rc)
 		PMD_DRV_LOG(ERR, "Enable promiscuous failed");
+
+	return rc;
 }
 
 /**
@@ -1345,8 +1351,12 @@ static void hinic_dev_promiscuous_enable(struct rte_eth_dev *dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success,
+ *   negative error value otherwise.
  */
-static void hinic_dev_promiscuous_disable(struct rte_eth_dev *dev)
+static int hinic_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	int rc = HINIC_OK;
 	struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
@@ -1358,6 +1368,8 @@ static void hinic_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	rc = hinic_set_dev_promiscuous(nic_dev, false);
 	if (rc)
 		PMD_DRV_LOG(ERR, "Disable promiscuous failed");
+
+	return rc;
 }
 
 /**
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 390cb21964..79bd3a70c9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -223,8 +223,8 @@ static int i40e_dev_start(struct rte_eth_dev *dev);
 static void i40e_dev_stop(struct rte_eth_dev *dev);
 static void i40e_dev_close(struct rte_eth_dev *dev);
 static int  i40e_dev_reset(struct rte_eth_dev *dev);
-static void i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void i40e_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int i40e_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void i40e_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void i40e_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
@@ -2564,7 +2564,7 @@ i40e_dev_reset(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static void
+static int
 i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -2574,17 +2574,25 @@ i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
 						     true, NULL, true);
-	if (status != I40E_SUCCESS)
+	if (status != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to enable unicast promiscuous");
+		return -EAGAIN;
+	}
 
 	status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
 							TRUE, NULL);
-	if (status != I40E_SUCCESS)
+	if (status != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous");
+		/* Rollback unicast promiscuous mode */
+		i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
+						    false, NULL, true);
+		return -EAGAIN;
+	}
 
+	return 0;
 }
 
-static void
+static int
 i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -2594,17 +2602,26 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
 
 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
 						     false, NULL, true);
-	if (status != I40E_SUCCESS)
+	if (status != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
+		return -EAGAIN;
+	}
 
 	/* must remain in all_multicast mode */
 	if (dev->data->all_multicast == 1)
-		return;
+		return 0;
 
 	status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
 							false, NULL);
-	if (status != I40E_SUCCESS)
+	if (status != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous");
+		/* Rollback unicast promiscuous mode */
+		i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
+						    true, NULL, true);
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index eca418522f..2bbbacf00b 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -92,8 +92,8 @@ static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
 static int i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40evf_dev_close(struct rte_eth_dev *dev);
 static int  i40evf_dev_reset(struct rte_eth_dev *dev);
-static void i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void i40evf_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int i40evf_init_vlan(struct rte_eth_dev *dev);
@@ -2156,7 +2156,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	return rte_eth_linkstatus_set(dev, &new_link);
 }
 
-static void
+static int
 i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2164,14 +2164,18 @@ i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
 	/* If enabled, just return */
 	if (vf->promisc_unicast_enabled)
-		return;
+		return 0;
 
 	ret = i40evf_config_promisc(dev, 1, vf->promisc_multicast_enabled);
 	if (ret == 0)
 		vf->promisc_unicast_enabled = TRUE;
+	else
+		ret = -EAGAIN;
+
+	return ret;
 }
 
-static void
+static int
 i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
@@ -2179,11 +2183,15 @@ i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 
 	/* If disabled, just return */
 	if (!vf->promisc_unicast_enabled)
-		return;
+		return 0;
 
 	ret = i40evf_config_promisc(dev, 0, vf->promisc_multicast_enabled);
 	if (ret == 0)
 		vf->promisc_unicast_enabled = FALSE;
+	else
+		ret = -EAGAIN;
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index 652f0accca..7f69e27a24 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -274,22 +274,22 @@ i40e_vf_representor_stats_reset(struct rte_eth_dev *ethdev)
 		representor->vf_id, &representor->stats_offset);
 }
 
-static void
+static int
 i40e_vf_representor_promiscuous_enable(struct rte_eth_dev *ethdev)
 {
 	struct i40e_vf_representor *representor = ethdev->data->dev_private;
 
-	rte_pmd_i40e_set_vf_unicast_promisc(
+	return rte_pmd_i40e_set_vf_unicast_promisc(
 		representor->adapter->eth_dev->data->port_id,
 		representor->vf_id, 1);
 }
 
-static void
+static int
 i40e_vf_representor_promiscuous_disable(struct rte_eth_dev *ethdev)
 {
 	struct i40e_vf_representor *representor = ethdev->data->dev_private;
 
-	rte_pmd_i40e_set_vf_unicast_promisc(
+	return rte_pmd_i40e_set_vf_unicast_promisc(
 		representor->adapter->eth_dev->data->port_id,
 		representor->vf_id, 0);
 }
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 99b1f43b82..22a88c88dd 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -43,8 +43,8 @@ static const uint32_t *iavf_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int iavf_dev_stats_get(struct rte_eth_dev *dev,
 			     struct rte_eth_stats *stats);
 static void iavf_dev_stats_reset(struct rte_eth_dev *dev);
-static void iavf_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void iavf_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int iavf_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int iavf_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void iavf_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void iavf_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int iavf_dev_add_mac_addr(struct rte_eth_dev *dev,
@@ -634,7 +634,7 @@ iavf_dev_link_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 iavf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
@@ -643,14 +643,18 @@ iavf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	int ret;
 
 	if (vf->promisc_unicast_enabled)
-		return;
+		return 0;
 
 	ret = iavf_config_promisc(adapter, TRUE, vf->promisc_multicast_enabled);
 	if (!ret)
 		vf->promisc_unicast_enabled = TRUE;
+	else
+		ret = -EAGAIN;
+
+	return ret;
 }
 
-static void
+static int
 iavf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
@@ -659,11 +663,15 @@ iavf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	if (!vf->promisc_unicast_enabled)
-		return;
+		return 0;
 
 	ret = iavf_config_promisc(adapter, FALSE, vf->promisc_multicast_enabled);
 	if (!ret)
 		vf->promisc_unicast_enabled = FALSE;
+	else
+		ret = -EAGAIN;
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 9d0e339a5d..eecf9c86c2 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -58,8 +58,8 @@ static int ice_rss_hash_update(struct rte_eth_dev *dev,
 			       struct rte_eth_rss_conf *rss_conf);
 static int ice_rss_hash_conf_get(struct rte_eth_dev *dev,
 				 struct rte_eth_rss_conf *rss_conf);
-static void ice_promisc_enable(struct rte_eth_dev *dev);
-static void ice_promisc_disable(struct rte_eth_dev *dev);
+static int ice_promisc_enable(struct rte_eth_dev *dev);
+static int ice_promisc_disable(struct rte_eth_dev *dev);
 static void ice_allmulti_enable(struct rte_eth_dev *dev);
 static void ice_allmulti_disable(struct rte_eth_dev *dev);
 static int ice_vlan_filter_set(struct rte_eth_dev *dev,
@@ -2973,7 +2973,7 @@ ice_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 ice_promisc_enable(struct rte_eth_dev *dev)
 {
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -2981,18 +2981,26 @@ ice_promisc_enable(struct rte_eth_dev *dev)
 	struct ice_vsi *vsi = pf->main_vsi;
 	enum ice_status status;
 	uint8_t pmask;
+	int ret = 0;
 
 	pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX |
 		ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
 
 	status = ice_set_vsi_promisc(hw, vsi->idx, pmask, 0);
-	if (status == ICE_ERR_ALREADY_EXISTS)
+	switch (status) {
+	case ICE_ERR_ALREADY_EXISTS:
 		PMD_DRV_LOG(DEBUG, "Promisc mode has already been enabled");
-	else if (status != ICE_SUCCESS)
+	case ICE_SUCCESS:
+		break;
+	default:
 		PMD_DRV_LOG(ERR, "Failed to enable promisc, err=%d", status);
+		ret = -EAGAIN;
+	}
+
+	return ret;
 }
 
-static void
+static int
 ice_promisc_disable(struct rte_eth_dev *dev)
 {
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -3000,13 +3008,18 @@ ice_promisc_disable(struct rte_eth_dev *dev)
 	struct ice_vsi *vsi = pf->main_vsi;
 	enum ice_status status;
 	uint8_t pmask;
+	int ret = 0;
 
 	pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX |
 		ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX;
 
 	status = ice_clear_vsi_promisc(hw, vsi->idx, pmask, 0);
-	if (status != ICE_SUCCESS)
+	if (status != ICE_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to clear promisc, err=%d", status);
+		ret = -EAGAIN;
+	}
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.h b/drivers/net/ipn3ke/ipn3ke_ethdev.h
index c7b336bbd1..830e717970 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.h
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.h
@@ -539,9 +539,9 @@ ipn3ke_rpst_dev_set_link_down(struct rte_eth_dev *dev);
 int
 ipn3ke_rpst_link_update(struct rte_eth_dev *ethdev,
 	__rte_unused int wait_to_complete);
-void
+int
 ipn3ke_rpst_promiscuous_enable(struct rte_eth_dev *ethdev);
-void
+int
 ipn3ke_rpst_promiscuous_disable(struct rte_eth_dev *ethdev);
 void
 ipn3ke_rpst_allmulticast_enable(struct rte_eth_dev *ethdev);
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 476d5e52bd..9079073c95 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -2618,7 +2618,7 @@ ipn3ke_rpst_scan_check(void)
 	return 0;
 }
 
-void
+int
 ipn3ke_rpst_promiscuous_enable(struct rte_eth_dev *ethdev)
 {
 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(ethdev);
@@ -2641,9 +2641,11 @@ ipn3ke_rpst_promiscuous_enable(struct rte_eth_dev *ethdev)
 				rpst->port_id,
 				0);
 	}
+
+	return 0;
 }
 
-void
+int
 ipn3ke_rpst_promiscuous_disable(struct rte_eth_dev *ethdev)
 {
 	struct ipn3ke_hw *hw = IPN3KE_DEV_PRIVATE_TO_HW(ethdev);
@@ -2666,6 +2668,8 @@ ipn3ke_rpst_promiscuous_disable(struct rte_eth_dev *ethdev)
 				rpst->port_id,
 				0);
 	}
+
+	return 0;
 }
 
 void
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 223f6f0a0c..0db285ea54 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -149,8 +149,8 @@ static int  ixgbe_dev_set_link_up(struct rte_eth_dev *dev);
 static int  ixgbe_dev_set_link_down(struct rte_eth_dev *dev);
 static void ixgbe_dev_close(struct rte_eth_dev *dev);
 static int  ixgbe_dev_reset(struct rte_eth_dev *dev);
-static void ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int ixgbe_dev_link_update(struct rte_eth_dev *dev,
@@ -270,8 +270,8 @@ static int ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
 static void ixgbevf_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
 				 uint8_t queue, uint8_t msix_vector);
 static void ixgbevf_configure_msix(struct rte_eth_dev *dev);
-static void ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev);
 
@@ -4180,7 +4180,7 @@ ixgbevf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	return ixgbe_dev_link_update_share(dev, wait_to_complete, 1);
 }
 
-static void
+static int
 ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4189,9 +4189,11 @@ ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
 	fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+	return 0;
 }
 
-static void
+static int
 ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4204,6 +4206,8 @@ ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	else
 		fctrl &= (~IXGBE_FCTRL_MPE);
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+	return 0;
 }
 
 static void
@@ -8399,20 +8403,46 @@ ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 	return ret;
 }
 
-static void
+static int
 ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_PROMISC)) {
+	case IXGBE_SUCCESS:
+		ret = 0;
+		break;
+	case IXGBE_ERR_FEATURE_NOT_SUPPORTED:
+		ret = -ENOTSUP;
+		break;
+	default:
+		ret = -EAGAIN;
+		break;
+	}
 
-	hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_PROMISC);
+	return ret;
 }
 
-static void
+static int
 ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
 
-	hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE);
+	switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE)) {
+	case IXGBE_SUCCESS:
+		ret = 0;
+		break;
+	case IXGBE_ERR_FEATURE_NOT_SUPPORTED:
+		ret = -ENOTSUP;
+		break;
+	default:
+		ret = -EAGAIN;
+		break;
+	}
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index d97e357e3c..e1eaf9eb8a 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -961,8 +961,12 @@ lio_dev_link_update(struct rte_eth_dev *eth_dev,
 /**
  * \brief Net device enable, disable allmulticast
  * @param eth_dev Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *  On success return 0
+ *  On failure return negative errno
  */
-static void
+static int
 lio_change_dev_flag(struct rte_eth_dev *eth_dev)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -987,14 +991,18 @@ lio_change_dev_flag(struct rte_eth_dev *eth_dev)
 
 	if (lio_send_ctrl_pkt(lio_dev, &ctrl_pkt)) {
 		lio_dev_err(lio_dev, "Failed to send change flag message\n");
-		return;
+		return -EAGAIN;
 	}
 
-	if (lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd))
+	if (lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd)) {
 		lio_dev_err(lio_dev, "Change dev flag command timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
 }
 
-static void
+static int
 lio_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1002,20 +1010,20 @@ lio_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 	if (strcmp(lio_dev->firmware_version, LIO_VF_TRUST_MIN_VERSION) < 0) {
 		lio_dev_err(lio_dev, "Require firmware version >= %s\n",
 			    LIO_VF_TRUST_MIN_VERSION);
-		return;
+		return -EAGAIN;
 	}
 
 	if (!lio_dev->intf_open) {
 		lio_dev_err(lio_dev, "Port %d down, can't enable promiscuous\n",
 			    lio_dev->port_id);
-		return;
+		return -EAGAIN;
 	}
 
 	lio_dev->ifflags |= LIO_IFFLAG_PROMISC;
-	lio_change_dev_flag(eth_dev);
+	return lio_change_dev_flag(eth_dev);
 }
 
-static void
+static int
 lio_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1023,17 +1031,17 @@ lio_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 	if (strcmp(lio_dev->firmware_version, LIO_VF_TRUST_MIN_VERSION) < 0) {
 		lio_dev_err(lio_dev, "Require firmware version >= %s\n",
 			    LIO_VF_TRUST_MIN_VERSION);
-		return;
+		return -EAGAIN;
 	}
 
 	if (!lio_dev->intf_open) {
 		lio_dev_err(lio_dev, "Port %d down, can't disable promiscuous\n",
 			    lio_dev->port_id);
-		return;
+		return -EAGAIN;
 	}
 
 	lio_dev->ifflags &= ~LIO_IFFLAG_PROMISC;
-	lio_change_dev_flag(eth_dev);
+	return lio_change_dev_flag(eth_dev);
 }
 
 static void
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 7730b530af..21517d70a2 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -205,8 +205,8 @@ int mlx4_mtu_get(struct mlx4_priv *priv, uint16_t *mtu);
 int mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 int mlx4_dev_set_link_down(struct rte_eth_dev *dev);
 int mlx4_dev_set_link_up(struct rte_eth_dev *dev);
-void mlx4_promiscuous_enable(struct rte_eth_dev *dev);
-void mlx4_promiscuous_disable(struct rte_eth_dev *dev);
+int mlx4_promiscuous_enable(struct rte_eth_dev *dev);
+int mlx4_promiscuous_disable(struct rte_eth_dev *dev);
 void mlx4_allmulticast_enable(struct rte_eth_dev *dev);
 void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 623ebd88cb..c8a73bc1f4 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -341,13 +341,17 @@ enum rxmode_toggle {
  *   Pointer to Ethernet device structure.
  * @param toggle
  *   Toggle to set.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-static void
+static int
 mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle)
 {
 	struct mlx4_priv *priv = dev->data->dev_private;
 	const char *mode;
 	struct rte_flow_error error;
+	int ret;
 
 	switch (toggle) {
 	case RXMODE_TOGGLE_PROMISC_OFF:
@@ -363,12 +367,16 @@ mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle)
 	default:
 		mode = "undefined";
 	}
-	if (!mlx4_flow_sync(priv, &error))
-		return;
+
+	ret = mlx4_flow_sync(priv, &error);
+	if (!ret)
+		return 0;
+
 	ERROR("cannot toggle %s mode (code %d, \"%s\"),"
 	      " flow error type %d, cause %p, message: %s",
 	      mode, rte_errno, strerror(rte_errno), error.type, error.cause,
 	      error.message ? error.message : "(unspecified)");
+	return ret;
 }
 
 /**
@@ -376,8 +384,11 @@ mlx4_rxmode_toggle(struct rte_eth_dev *dev, enum rxmode_toggle toggle)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_ON);
@@ -388,8 +399,11 @@ mlx4_promiscuous_enable(struct rte_eth_dev *dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_OFF);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index cd08d001e9..0c202d8dd9 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -751,8 +751,8 @@ int mlx5_dev_rss_reta_update(struct rte_eth_dev *dev,
 
 /* mlx5_rxmode.c */
 
-void mlx5_promiscuous_enable(struct rte_eth_dev *dev);
-void mlx5_promiscuous_disable(struct rte_eth_dev *dev);
+int mlx5_promiscuous_enable(struct rte_eth_dev *dev);
+int mlx5_promiscuous_disable(struct rte_eth_dev *dev);
 void mlx5_allmulticast_enable(struct rte_eth_dev *dev);
 void mlx5_allmulticast_disable(struct rte_eth_dev *dev);
 
diff --git a/drivers/net/mlx5/mlx5_rxmode.c b/drivers/net/mlx5/mlx5_rxmode.c
index d5077db0db..c862fc9520 100644
--- a/drivers/net/mlx5/mlx5_rxmode.c
+++ b/drivers/net/mlx5/mlx5_rxmode.c
@@ -28,8 +28,11 @@
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
@@ -41,14 +44,24 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 			"port %u cannot enable promiscuous mode"
 			" in flow isolation mode",
 			dev->data->port_id);
-		return;
+		return 0;
+	}
+	if (priv->config.vf) {
+		ret = mlx5_nl_promisc(dev, 1);
+		if (ret)
+			goto error;
 	}
-	if (priv->config.vf)
-		mlx5_nl_promisc(dev, 1);
 	ret = mlx5_traffic_restart(dev);
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot enable promiscuous mode: %s",
 			dev->data->port_id, strerror(rte_errno));
+
+error:
+	/*
+	 * rte_eth_dev_promiscuous_enable() rollback
+	 * dev->data->promiscuous in the case of failure.
+	 */
+	return ret;
 }
 
 /**
@@ -56,20 +69,33 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	int ret;
 
 	dev->data->promiscuous = 0;
-	if (priv->config.vf)
-		mlx5_nl_promisc(dev, 0);
+	if (priv->config.vf) {
+		ret = mlx5_nl_promisc(dev, 0);
+		if (ret)
+			goto error;
+	}
 	ret = mlx5_traffic_restart(dev);
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot disable promiscuous mode: %s",
 			dev->data->port_id, strerror(rte_errno));
+
+error:
+	/*
+	 * rte_eth_dev_promiscuous_disable() rollback
+	 * dev->data->promiscuous in the case of failure.
+	 */
+	return ret;
 }
 
 /**
diff --git a/drivers/net/mvneta/mvneta_ethdev.c b/drivers/net/mvneta/mvneta_ethdev.c
index 3ba0ac76e2..1090af03b1 100644
--- a/drivers/net/mvneta/mvneta_ethdev.c
+++ b/drivers/net/mvneta/mvneta_ethdev.c
@@ -534,25 +534,30 @@ mvneta_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   always 0
  */
-static void
+static int
 mvneta_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct mvneta_priv *priv = dev->data->dev_private;
 	int ret, en;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	neta_ppio_get_promisc(priv->ppio, &en);
 	if (en) {
 		MVNETA_LOG(INFO, "Promiscuous already enabled");
-		return;
+		return 0;
 	}
 
 	ret = neta_ppio_set_promisc(priv->ppio, 1);
 	if (ret)
 		MVNETA_LOG(ERR, "Failed to enable promiscuous mode");
+
+	return 0;
 }
 
 /**
@@ -560,25 +565,30 @@ mvneta_promiscuous_enable(struct rte_eth_dev *dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   always 0
  */
-static void
+static int
 mvneta_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct mvneta_priv *priv = dev->data->dev_private;
 	int ret, en;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	neta_ppio_get_promisc(priv->ppio, &en);
 	if (!en) {
 		MVNETA_LOG(INFO, "Promiscuous already disabled");
-		return;
+		return 0;
 	}
 
 	ret = neta_ppio_set_promisc(priv->ppio, 0);
 	if (ret)
 		MVNETA_LOG(ERR, "Failed to disable promiscuous mode");
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 345c24404d..1e5a1e39aa 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -994,22 +994,29 @@ mrvl_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
-static void
+static int
 mrvl_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	if (priv->isolated)
-		return;
+		return 0;
 
 	ret = pp2_ppio_set_promisc(priv->ppio, 1);
-	if (ret)
+	if (ret) {
 		MRVL_LOG(ERR, "Failed to enable promiscuous mode");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
 /**
@@ -1018,7 +1025,7 @@ mrvl_promiscuous_enable(struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to Ethernet device structure.
  */
-static void
+static int
 mrvl_allmulticast_enable(struct rte_eth_dev *dev)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
@@ -1040,6 +1047,9 @@ mrvl_allmulticast_enable(struct rte_eth_dev *dev)
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
 static void
 mrvl_promiscuous_disable(struct rte_eth_dev *dev)
@@ -1048,11 +1058,15 @@ mrvl_promiscuous_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	ret = pp2_ppio_set_promisc(priv->ppio, 0);
-	if (ret)
+	if (ret) {
 		MRVL_LOG(ERR, "Failed to disable promiscuous mode");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index 7353211c12..d04a6c8acb 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -416,16 +416,16 @@ static int hn_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 hn_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct hn_data *hv = dev->data->dev_private;
 
 	hn_rndis_set_rxfilter(hv, NDIS_PACKET_TYPE_PROMISCUOUS);
-	hn_vf_promiscuous_enable(dev);
+	return hn_vf_promiscuous_enable(dev);
 }
 
-static void
+static int
 hn_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct hn_data *hv = dev->data->dev_private;
@@ -435,7 +435,7 @@ hn_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	if (dev->data->all_multicast)
 		filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
 	hn_rndis_set_rxfilter(hv, filter);
-	hn_vf_promiscuous_disable(dev);
+	return hn_vf_promiscuous_disable(dev);
 }
 
 static void
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index e0ebe4e1c8..01f2276482 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -214,8 +214,8 @@ void	hn_vf_close(struct rte_eth_dev *dev);
 
 void	hn_vf_allmulticast_enable(struct rte_eth_dev *dev);
 void	hn_vf_allmulticast_disable(struct rte_eth_dev *dev);
-void	hn_vf_promiscuous_enable(struct rte_eth_dev *dev);
-void	hn_vf_promiscuous_disable(struct rte_eth_dev *dev);
+int	hn_vf_promiscuous_enable(struct rte_eth_dev *dev);
+int	hn_vf_promiscuous_disable(struct rte_eth_dev *dev);
 int	hn_vf_mc_addr_list(struct rte_eth_dev *dev,
 			   struct rte_ether_addr *mc_addr_set,
 			   uint32_t nb_mc_addr);
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index d53d27bb73..d133438bbd 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -362,6 +362,20 @@ void hn_vf_stop(struct rte_eth_dev *dev)
 		rte_spinlock_unlock(&hv->vf_lock);		\
 	}
 
+/* If VF is present, then cascade configuration down */
+#define VF_ETHDEV_FUNC_RET_STATUS(dev, func)			\
+	{							\
+		struct hn_data *hv = (dev)->data->dev_private;	\
+		struct rte_eth_dev *vf_dev;			\
+		int ret = 0;					\
+		rte_spinlock_lock(&hv->vf_lock);		\
+		vf_dev = hn_get_vf_dev(hv);			\
+		if (vf_dev)					\
+			ret = func(vf_dev->data->port_id);	\
+		rte_spinlock_unlock(&hv->vf_lock);		\
+		return ret;					\
+	}
+
 void hn_vf_reset(struct rte_eth_dev *dev)
 {
 	VF_ETHDEV_FUNC(dev, rte_eth_dev_reset);
@@ -396,14 +410,14 @@ void hn_vf_allmulticast_disable(struct rte_eth_dev *dev)
 	VF_ETHDEV_FUNC(dev, rte_eth_allmulticast_disable);
 }
 
-void hn_vf_promiscuous_enable(struct rte_eth_dev *dev)
+int hn_vf_promiscuous_enable(struct rte_eth_dev *dev)
 {
-	VF_ETHDEV_FUNC(dev, rte_eth_promiscuous_enable);
+	VF_ETHDEV_FUNC_RET_STATUS(dev, rte_eth_promiscuous_enable);
 }
 
-void hn_vf_promiscuous_disable(struct rte_eth_dev *dev)
+int hn_vf_promiscuous_disable(struct rte_eth_dev *dev)
 {
-	VF_ETHDEV_FUNC(dev, rte_eth_promiscuous_disable);
+	VF_ETHDEV_FUNC_RET_STATUS(dev, rte_eth_promiscuous_disable);
 }
 
 int hn_vf_mc_addr_list(struct rte_eth_dev *dev,
diff --git a/drivers/net/nfb/nfb_rxmode.c b/drivers/net/nfb/nfb_rxmode.c
index 97bfcb238d..17708c84c6 100644
--- a/drivers/net/nfb/nfb_rxmode.c
+++ b/drivers/net/nfb/nfb_rxmode.c
@@ -7,7 +7,7 @@
 #include "nfb_rxmode.h"
 #include "nfb.h"
 
-void
+int
 nfb_eth_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = (struct pmd_internals *)
@@ -20,9 +20,11 @@ nfb_eth_promiscuous_enable(struct rte_eth_dev *dev)
 		nc_rxmac_mac_filter_enable(internals->rxmac[i],
 			RXMAC_MAC_FILTER_PROMISCUOUS);
 	}
+
+	return 0;
 }
 
-void
+int
 nfb_eth_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *internals = (struct pmd_internals *)
@@ -33,12 +35,14 @@ nfb_eth_promiscuous_disable(struct rte_eth_dev *dev)
 
 	/* if promisc is not enabled, do nothing */
 	if (!nfb_eth_promiscuous_get(dev))
-		return;
+		return 0;
 
 	for (i = 0; i < internals->max_rxmac; ++i) {
 		nc_rxmac_mac_filter_enable(internals->rxmac[i],
 			RXMAC_MAC_FILTER_TABLE);
 	}
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/nfb/nfb_rxmode.h b/drivers/net/nfb/nfb_rxmode.h
index 4c59651d66..1d5bafa98a 100644
--- a/drivers/net/nfb/nfb_rxmode.h
+++ b/drivers/net/nfb/nfb_rxmode.h
@@ -26,8 +26,10 @@ nfb_eth_promiscuous_get(struct rte_eth_dev *dev);
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return always 0
  */
-void
+int
 nfb_eth_promiscuous_enable(struct rte_eth_dev *dev);
 
 /**
@@ -35,8 +37,10 @@ nfb_eth_promiscuous_enable(struct rte_eth_dev *dev);
  *
  * @param dev
  *   Pointer to Ethernet device structure.
+ *
+ * @return always 0
  */
-void
+int
 nfb_eth_promiscuous_disable(struct rte_eth_dev *dev);
 
 /**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 3d5b99c943..a9858036a9 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -85,8 +85,8 @@ static int nfp_net_infos_get(struct rte_eth_dev *dev,
 			     struct rte_eth_dev_info *dev_info);
 static int nfp_net_init(struct rte_eth_dev *eth_dev);
 static int nfp_net_link_update(struct rte_eth_dev *dev, int wait_to_complete);
-static void nfp_net_promisc_enable(struct rte_eth_dev *dev);
-static void nfp_net_promisc_disable(struct rte_eth_dev *dev);
+static int nfp_net_promisc_enable(struct rte_eth_dev *dev);
+static int nfp_net_promisc_disable(struct rte_eth_dev *dev);
 static int nfp_net_rx_fill_freelist(struct nfp_net_rxq *rxq);
 static uint32_t nfp_net_rx_queue_count(struct rte_eth_dev *dev,
 				       uint16_t queue_idx);
@@ -931,11 +931,12 @@ nfp_net_close(struct rte_eth_dev *dev)
 	 */
 }
 
-static void
+static int
 nfp_net_promisc_enable(struct rte_eth_dev *dev)
 {
 	uint32_t new_ctrl, update = 0;
 	struct nfp_net_hw *hw;
+	int ret;
 
 	PMD_DRV_LOG(DEBUG, "Promiscuous mode enable");
 
@@ -943,12 +944,12 @@ nfp_net_promisc_enable(struct rte_eth_dev *dev)
 
 	if (!(hw->cap & NFP_NET_CFG_CTRL_PROMISC)) {
 		PMD_INIT_LOG(INFO, "Promiscuous mode not supported");
-		return;
+		return -ENOTSUP;
 	}
 
 	if (hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) {
 		PMD_DRV_LOG(INFO, "Promiscuous mode already enabled");
-		return;
+		return 0;
 	}
 
 	new_ctrl = hw->ctrl | NFP_NET_CFG_CTRL_PROMISC;
@@ -958,23 +959,27 @@ nfp_net_promisc_enable(struct rte_eth_dev *dev)
 	 * DPDK sets promiscuous mode on just after this call assuming
 	 * it can not fail ...
 	 */
-	if (nfp_net_reconfig(hw, new_ctrl, update) < 0)
-		return;
+	ret = nfp_net_reconfig(hw, new_ctrl, update);
+	if (ret < 0)
+		return ret;
 
 	hw->ctrl = new_ctrl;
+
+	return 0;
 }
 
-static void
+static int
 nfp_net_promisc_disable(struct rte_eth_dev *dev)
 {
 	uint32_t new_ctrl, update = 0;
 	struct nfp_net_hw *hw;
+	int ret;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	if ((hw->ctrl & NFP_NET_CFG_CTRL_PROMISC) == 0) {
 		PMD_DRV_LOG(INFO, "Promiscuous mode already disabled");
-		return;
+		return 0;
 	}
 
 	new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_PROMISC;
@@ -984,10 +989,13 @@ nfp_net_promisc_disable(struct rte_eth_dev *dev)
 	 * DPDK sets promiscuous mode off just before this call
 	 * assuming it can not fail ...
 	 */
-	if (nfp_net_reconfig(hw, new_ctrl, update) < 0)
-		return;
+	ret = nfp_net_reconfig(hw, new_ctrl, update);
+	if (ret < 0)
+		return ret;
 
 	hw->ctrl = new_ctrl;
+
+	return 0;
 }
 
 /*
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 1faa7b7c6b..47cea4e9b2 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -174,7 +174,7 @@ octeontx_port_stop(struct octeontx_nic *nic)
 	return octeontx_bgx_port_stop(nic->port_id);
 }
 
-static void
+static int
 octeontx_port_promisc_set(struct octeontx_nic *nic, int en)
 {
 	struct rte_eth_dev *dev;
@@ -185,15 +185,19 @@ octeontx_port_promisc_set(struct octeontx_nic *nic, int en)
 	dev = nic->dev;
 
 	res = octeontx_bgx_port_promisc_set(nic->port_id, en);
-	if (res < 0)
+	if (res < 0) {
 		octeontx_log_err("failed to set promiscuous mode %d",
 				nic->port_id);
+		return res;
+	}
 
 	/* Set proper flag for the mode */
 	dev->data->promiscuous = (en != 0) ? 1 : 0;
 
 	octeontx_log_dbg("port %d : promiscuous mode %s",
 			nic->port_id, en ? "set" : "unset");
+
+	return 0;
 }
 
 static int
@@ -444,22 +448,22 @@ octeontx_dev_stop(struct rte_eth_dev *dev)
 	}
 }
 
-static void
+static int
 octeontx_dev_promisc_enable(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 
 	PMD_INIT_FUNC_TRACE();
-	octeontx_port_promisc_set(nic, 1);
+	return octeontx_port_promisc_set(nic, 1);
 }
 
-static void
+static int
 octeontx_dev_promisc_disable(struct rte_eth_dev *dev)
 {
 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
 
 	PMD_INIT_FUNC_TRACE();
-	octeontx_port_promisc_set(nic, 0);
+	return octeontx_port_promisc_set(nic, 0);
 }
 
 static int
diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h
index 5de0a1d4d1..8814622e43 100644
--- a/drivers/net/octeontx2/otx2_ethdev.h
+++ b/drivers/net/octeontx2/otx2_ethdev.h
@@ -379,8 +379,8 @@ int otx2_nix_rx_descriptor_done(void *rxq, uint16_t offset);
 int otx2_nix_rx_descriptor_status(void *rx_queue, uint16_t offset);
 
 void otx2_nix_promisc_config(struct rte_eth_dev *eth_dev, int en);
-void otx2_nix_promisc_enable(struct rte_eth_dev *eth_dev);
-void otx2_nix_promisc_disable(struct rte_eth_dev *eth_dev);
+int otx2_nix_promisc_enable(struct rte_eth_dev *eth_dev);
+int otx2_nix_promisc_disable(struct rte_eth_dev *eth_dev);
 void otx2_nix_allmulticast_enable(struct rte_eth_dev *eth_dev);
 void otx2_nix_allmulticast_disable(struct rte_eth_dev *eth_dev);
 int otx2_nix_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx);
diff --git a/drivers/net/octeontx2/otx2_ethdev_ops.c b/drivers/net/octeontx2/otx2_ethdev_ops.c
index 024c295aa6..5a97a090ae 100644
--- a/drivers/net/octeontx2/otx2_ethdev_ops.c
+++ b/drivers/net/octeontx2/otx2_ethdev_ops.c
@@ -129,18 +129,22 @@ otx2_nix_promisc_config(struct rte_eth_dev *eth_dev, int en)
 	otx2_nix_vlan_update_promisc(eth_dev, en);
 }
 
-void
+int
 otx2_nix_promisc_enable(struct rte_eth_dev *eth_dev)
 {
 	otx2_nix_promisc_config(eth_dev, 1);
 	nix_cgx_promisc_config(eth_dev, 1);
+
+	return 0;
 }
 
-void
+int
 otx2_nix_promisc_disable(struct rte_eth_dev *eth_dev)
 {
 	otx2_nix_promisc_config(eth_dev, 0);
 	nix_cgx_promisc_config(eth_dev, 0);
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 9eb57fd78e..cfca6c4bc7 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1383,33 +1383,39 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
 	return rte_eth_linkstatus_set(eth_dev, &link);
 }
 
-static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
+static int qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC;
+	enum _ecore_status_t ecore_status;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
 		type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
 
-	qed_configure_filter_rx_mode(eth_dev, type);
+	ecore_status = qed_configure_filter_rx_mode(eth_dev, type);
+
+	return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN;
 }
 
-static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
+static int qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
+	enum _ecore_status_t ecore_status;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
-		qed_configure_filter_rx_mode(eth_dev,
+		ecore_status = qed_configure_filter_rx_mode(eth_dev,
 				QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
 	else
-		qed_configure_filter_rx_mode(eth_dev,
+		ecore_status = qed_configure_filter_rx_mode(eth_dev,
 				QED_FILTER_RX_MODE_TYPE_REGULAR);
+
+	return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN;
 }
 
 static void qede_poll_sp_sb_cb(void *param)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 013b6bbd63..5faf14b674 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -366,7 +366,7 @@ sfc_dev_close(struct rte_eth_dev *dev)
 	free(sa);
 }
 
-static void
+static int
 sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
 		   boolean_t enabled)
 {
@@ -375,6 +375,7 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
 	boolean_t allmulti = (mode == SFC_DEV_FILTER_MODE_ALLMULTI);
 	const char *desc = (allmulti) ? "all-multi" : "promiscuous";
+	int rc = 0;
 
 	sfc_adapter_lock(sa);
 
@@ -390,7 +391,7 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
 				     "start provided that isolated mode is "
 				     "disabled prior the next start");
 		} else if ((sa->state == SFC_ADAPTER_STARTED) &&
-			   (sfc_set_rx_mode(sa) != 0)) {
+			   ((rc = sfc_set_rx_mode(sa)) != 0)) {
 			*toggle = !(enabled);
 			sfc_warn(sa, "Failed to %s %s mode",
 				 ((enabled) ? "enable" : "disable"), desc);
@@ -398,18 +399,19 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
 	}
 
 	sfc_adapter_unlock(sa);
+	return rc;
 }
 
-static void
+static int
 sfc_dev_promisc_enable(struct rte_eth_dev *dev)
 {
-	sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+	return sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
 }
 
-static void
+static int
 sfc_dev_promisc_disable(struct rte_eth_dev *dev)
 {
-	sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+	return sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
 }
 
 static void
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index ca066a3d3d..2f3811b67f 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1344,18 +1344,20 @@ eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 	return 0;
 }
 
-static void
+static int
 eth_promiscuous_enable(struct rte_eth_dev *dev __rte_unused)
 {
 	PMD_DRV_LOG(WARNING, "Enabling promiscuous mode is not supported. "
 			"The card is always in promiscuous mode.");
+	return 0;
 }
 
-static void
+static int
 eth_promiscuous_disable(struct rte_eth_dev *dev __rte_unused)
 {
 	PMD_DRV_LOG(WARNING, "Disabling promiscuous mode is not supported. "
 			"The card is always in promiscuous mode.");
+	return -ENOTSUP;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index f85458c3cd..41612ce838 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -1100,28 +1100,60 @@ tap_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
 	return 0;
 }
 
-static void
+static int
 tap_promisc_enable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
+	int ret;
 
-	dev->data->promiscuous = 1;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
-	if (pmd->remote_if_index && !pmd->flow_isolate)
-		tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
+	ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+	if (ret != 0)
+		return ret;
+
+	if (pmd->remote_if_index && !pmd->flow_isolate) {
+		dev->data->promiscuous = 1;
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
+		if (ret != 0) {
+			/* Rollback promisc flag */
+			tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+			/*
+			 * rte_eth_dev_promiscuous_enable() rollback
+			 * dev->data->promiscuous in the case of failure.
+			 */
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
-static void
+static int
 tap_promisc_disable(struct rte_eth_dev *dev)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
+	int ret;
 
-	dev->data->promiscuous = 0;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
-	if (pmd->remote_if_index && !pmd->flow_isolate)
-		tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
+	ret = tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
+	if (ret != 0)
+		return ret;
+
+	if (pmd->remote_if_index && !pmd->flow_isolate) {
+		dev->data->promiscuous = 0;
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
+		if (ret != 0) {
+			/* Rollback promisc flag */
+			tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
+			/*
+			 * rte_eth_dev_promiscuous_disable() rollback
+			 * dev->data->promiscuous in the case of failure.
+			 */
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index f3ba07ae37..edc956bb3d 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -401,9 +401,10 @@ nicvf_dev_stats_reset(struct rte_eth_dev *dev)
 }
 
 /* Promiscuous mode enabled by default in LMAC to VF 1:1 map configuration */
-static void
+static int
 nicvf_dev_promisc_enable(struct rte_eth_dev *dev __rte_unused)
 {
+	return 0;
 }
 
 static inline uint64_t
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 8fe9dcebda..1ba4aa37e8 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -41,8 +41,8 @@ static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
 static int  virtio_dev_start(struct rte_eth_dev *dev);
 static void virtio_dev_stop(struct rte_eth_dev *dev);
-static void virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void virtio_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int virtio_dev_info_get(struct rte_eth_dev *dev,
@@ -746,7 +746,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	}
 }
 
-static void
+static int
 virtio_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -756,7 +756,7 @@ virtio_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
-		return;
+		return -ENOTSUP;
 	}
 
 	ctrl.hdr.class = VIRTIO_NET_CTRL_RX;
@@ -765,11 +765,15 @@ virtio_dev_promiscuous_enable(struct rte_eth_dev *dev)
 	dlen[0] = 1;
 
 	ret = virtio_send_command(hw->cvq, &ctrl, dlen, 1);
-	if (ret)
+	if (ret) {
 		PMD_INIT_LOG(ERR, "Failed to enable promisc");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
-static void
+static int
 virtio_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -779,7 +783,7 @@ virtio_dev_promiscuous_disable(struct rte_eth_dev *dev)
 
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX)) {
 		PMD_INIT_LOG(INFO, "host does not support rx control");
-		return;
+		return -ENOTSUP;
 	}
 
 	ctrl.hdr.class = VIRTIO_NET_CTRL_RX;
@@ -788,8 +792,12 @@ virtio_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	dlen[0] = 1;
 
 	ret = virtio_send_command(hw->cvq, &ctrl, dlen, 1);
-	if (ret)
+	if (ret) {
 		PMD_INIT_LOG(ERR, "Failed to disable promisc");
+		return -EAGAIN;
+	}
+
+	return 0;
 }
 
 static void
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 551c511943..8bfe16c482 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -65,8 +65,8 @@ static int vmxnet3_dev_start(struct rte_eth_dev *dev);
 static void vmxnet3_dev_stop(struct rte_eth_dev *dev);
 static void vmxnet3_dev_close(struct rte_eth_dev *dev);
 static void vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set);
-static void vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev);
-static void vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static int vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static void vmxnet3_dev_allmulticast_enable(struct rte_eth_dev *dev);
 static void vmxnet3_dev_allmulticast_disable(struct rte_eth_dev *dev);
 static int __vmxnet3_dev_link_update(struct rte_eth_dev *dev,
@@ -1262,7 +1262,7 @@ vmxnet3_dev_set_rxmode(struct vmxnet3_hw *hw, uint32_t feature, int set)
 }
 
 /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
-static void
+static int
 vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
@@ -1273,10 +1273,12 @@ vmxnet3_dev_promiscuous_enable(struct rte_eth_dev *dev)
 
 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
 			       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+
+	return 0;
 }
 
 /* Promiscuous supported only if Vmxnet3_DriverShared is initialized in adapter */
-static void
+static int
 vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
@@ -1290,6 +1292,8 @@ vmxnet3_dev_promiscuous_disable(struct rte_eth_dev *dev)
 	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_PROMISC, 0);
 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
 			       VMXNET3_CMD_UPDATE_VLAN_FILTERS);
+
+	return 0;
 }
 
 /* Allmulticast supported only if Vmxnet3_DriverShared is initialized in adapter */
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 0f6dedbe23..73521fe5b0 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -1892,30 +1892,38 @@ int
 rte_eth_promiscuous_enable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
+	uint8_t old_promiscuous;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
-	(*dev->dev_ops->promiscuous_enable)(dev);
-	dev->data->promiscuous = 1;
+	old_promiscuous = dev->data->promiscuous;
+	ret = (*dev->dev_ops->promiscuous_enable)(dev);
+	dev->data->promiscuous = (ret == 0) ? 1 : old_promiscuous;
 
-	return 0;
+	return ret;
 }
 
 int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
+	uint8_t old_promiscuous;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
 
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
+	old_promiscuous = dev->data->promiscuous;
 	dev->data->promiscuous = 0;
-	(*dev->dev_ops->promiscuous_disable)(dev);
+	ret = (*dev->dev_ops->promiscuous_disable)(dev);
+	if (ret != 0)
+		dev->data->promiscuous = old_promiscuous;
 
-	return 0;
+	return ret;
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2394b32c83..6322348d17 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -52,10 +52,10 @@ typedef int (*eth_dev_reset_t)(struct rte_eth_dev *dev);
 typedef int (*eth_is_removed_t)(struct rte_eth_dev *dev);
 /**< @internal Function used to detect an Ethernet device removal. */
 
-typedef void (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev);
+typedef int (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev);
 /**< @internal Function used to enable the RX promiscuous mode of an Ethernet device. */
 
-typedef void (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
+typedef int (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
 /**< @internal Function used to disable the RX promiscuous mode of an Ethernet device. */
 
 typedef void (*eth_allmulticast_enable_t)(struct rte_eth_dev *dev);
