DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: "John W. Linville" <linville@tuxdriver.com>,
	Xiaolong Ye <xiaolong.ye@intel.com>,
	Qi Zhang <qi.z.zhang@intel.com>,
	Igor Russkikh <igor.russkikh@aquantia.com>,
	Pavel Belous <pavel.belous@aquantia.com>,
	Allain Legacy <allain.legacy@windriver.com>,
	Matt Peters <matt.peters@windriver.com>,
	Ravi Kumar <ravi1.kumar@amd.com>, Rasesh Mody <rmody@marvell.com>,
	Shahed Shaikh <shshaikh@marvell.com>,
	Ajit Khaparde <ajit.khaparde@broadcom.com>,
	Somnath Kotur <somnath.kotur@broadcom.com>,
	Chas Williams <chas3@att.com>,
	Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>,
	Hemant Agrawal <hemant.agrawal@nxp.com>,
	Sachin Saxena <sachin.saxena@nxp.com>,
	Wenzhuo Lu <wenzhuo.lu@intel.com>,
	Gagandeep Singh <g.singh@nxp.com>,
	John Daley <johndale@cisco.com>,
	"Hyong Youb Kim" <hyonkim@cisco.com>,
	Gaetan Rivet <gaetan.rivet@6wind.com>,
	"Xiao Wang" <xiao.w.wang@intel.com>,
	Ziyang Xuan <xuanziyang2@huawei.com>,
	"Xiaoyun Wang" <cloud.wangxiaoyun@huawei.com>,
	Guoyang Zhou <zhouguoyang@huawei.com>,
	Beilei Xing <beilei.xing@intel.com>,
	Jingjing Wu <jingjing.wu@intel.com>,
	Qiming Yang <qiming.yang@intel.com>,
	Rosen Xu <rosen.xu@intel.com>,
	Konstantin Ananyev <konstantin.ananyev@intel.com>,
	Shijith Thotton <sthotton@marvell.com>,
	Srisivasubramanian Srinivasan <srinivasan@marvell.com>,
	Matan Azrad <matan@mellanox.com>,
	Shahaf Shuler <shahafs@mellanox.com>,
	Viacheslav Ovsiienko <viacheslavo@mellanox.com>,
	"Zyta Szpak" <zr@semihalf.com>, Liron Himi <lironh@marvell.com>,
	Tomasz Duszynski <tdu@semihalf.com>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Rastislav Cernay <cernay@netcope.com>,
	Jan Remes <remes@netcope.com>,
	Alejandro Lucero <alejandro.lucero@netronome.com>,
	Jerin Jacob <jerinj@marvell.com>,
	Nithin Dabilpuram <ndabilpuram@marvell.com>,
	"Kiran Kumar K" <kirankumark@marvell.com>,
	Keith Wiles <keith.wiles@intel.com>,
	Maciej Czekaj <mczekaj@marvell.com>,
	Maxime Coquelin <maxime.coquelin@redhat.com>,
	Tiwei Bie <tiwei.bie@intel.com>,
	Zhihong Wang <zhihong.wang@intel.com>,
	Yong Wang <yongwang@vmware.com>,
	Thomas Monjalon <thomas@monjalon.net>,
	Ferruh Yigit <ferruh.yigit@intel.com>
Cc: <dev@dpdk.org>
Subject: [dpdk-dev] [PATCH v3 04/13] ethdev: change promiscuous callbacks to return status
Date: Sat, 14 Sep 2019 12:37:24 +0100
Message-ID: <1568461055-16472-5-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1568461055-16472-1-git-send-email-arybchenko@solarflare.com>

Enabling/disabling of promiscuous mode is not always successful and
it should be taken into account to be able to handle it properly.

When correct return status is unclear from driver code, -EAGAIN is used.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Matan Azrad <matan@mellanox.com>
Acked-by: Hyong Youb Kim <hyonkim@cisco.com>
---
 app/test/virtual_pmd.c                    | 12 ++++--
 drivers/net/af_packet/rte_eth_af_packet.c | 22 ++++++----
 drivers/net/af_xdp/rte_eth_af_xdp.c       | 22 ++++++----
 drivers/net/atlantic/atl_ethdev.c         | 12 ++++--
 drivers/net/avp/avp_ethdev.c              | 12 ++++--
 drivers/net/axgbe/axgbe_ethdev.c          | 12 ++++--
 drivers/net/bnx2x/bnx2x_ethdev.c          |  8 +++-
 drivers/net/bnxt/bnxt_ethdev.c            | 26 +++++++++---
 drivers/net/bonding/rte_eth_bond_pmd.c    | 42 +++++++++++++++---
 drivers/net/cxgbe/cxgbe_ethdev.c          | 12 +++---
 drivers/net/cxgbe/cxgbe_pfvf.h            |  4 +-
 drivers/net/dpaa/dpaa_ethdev.c            |  8 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c          | 12 ++++--
 drivers/net/e1000/em_ethdev.c             | 12 ++++--
 drivers/net/e1000/igb_ethdev.c            | 24 +++++++----
 drivers/net/enetc/enetc_ethdev.c          |  8 +++-
 drivers/net/enic/enic.h                   |  2 +-
 drivers/net/enic/enic_ethdev.c            | 22 +++++++---
 drivers/net/enic/enic_main.c              |  4 +-
 drivers/net/failsafe/failsafe_ops.c       |  8 +++-
 drivers/net/fm10k/fm10k_ethdev.c          | 24 +++++++----
 drivers/net/hinic/hinic_pmd_ethdev.c      | 16 ++++++-
 drivers/net/i40e/i40e_ethdev.c            | 35 +++++++++++----
 drivers/net/i40e/i40e_ethdev_vf.c         | 20 ++++++---
 drivers/net/i40e/i40e_vf_representor.c    |  8 ++--
 drivers/net/iavf/iavf_ethdev.c            | 20 ++++++---
 drivers/net/ice/ice_ethdev.c              | 27 +++++++++---
 drivers/net/ipn3ke/ipn3ke_ethdev.h        |  4 +-
 drivers/net/ipn3ke/ipn3ke_representor.c   |  8 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c          | 50 +++++++++++++++++-----
 drivers/net/liquidio/lio_ethdev.c         | 30 ++++++++-----
 drivers/net/mlx4/mlx4.h                   |  4 +-
 drivers/net/mlx4/mlx4_ethdev.c            | 28 +++++++++---
 drivers/net/mlx5/mlx5.h                   |  4 +-
 drivers/net/mlx5/mlx5_rxmode.c            | 38 ++++++++++++++---
 drivers/net/mvneta/mvneta_ethdev.c        | 22 +++++++---
 drivers/net/mvpp2/mrvl_ethdev.c           | 28 +++++++++---
 drivers/net/netvsc/hn_ethdev.c            |  8 ++--
 drivers/net/netvsc/hn_var.h               |  4 +-
 drivers/net/netvsc/hn_vf.c                | 22 ++++++++--
 drivers/net/nfb/nfb_rxmode.c              | 10 +++--
 drivers/net/nfb/nfb_rxmode.h              |  8 +++-
 drivers/net/nfp/nfp_net.c                 | 30 ++++++++-----
 drivers/net/octeontx/octeontx_ethdev.c    | 16 ++++---
 drivers/net/octeontx2/otx2_ethdev.h       |  4 +-
 drivers/net/octeontx2/otx2_ethdev_ops.c   |  8 +++-
 drivers/net/qede/qede_ethdev.c            | 16 ++++---
 drivers/net/sfc/sfc_ethdev.c              | 14 +++---
 drivers/net/szedata2/rte_eth_szedata2.c   |  6 ++-
 drivers/net/tap/rte_eth_tap.c             | 52 ++++++++++++++++++-----
 drivers/net/thunderx/nicvf_ethdev.c       |  3 +-
 drivers/net/virtio/virtio_ethdev.c        | 24 +++++++----
 drivers/net/vmxnet3/vmxnet3_ethdev.c      | 12 ++++--
 lib/librte_ethdev/rte_ethdev.c            | 18 +++++---
 lib/librte_ethdev/rte_ethdev_core.h       | 52 +++++++++++++++++++++--
 55 files changed, 692 insertions(+), 265 deletions(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index e295891c0..b34df416a 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 66131b53e..049572728 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 aa716f319..096815732 100644
--- a/drivers/net/af_xdp/rte_eth_af_xdp.c
+++ b/drivers/net/af_xdp/rte_eth_af_xdp.c
@@ -746,41 +746,47 @@ eth_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return (ret < 0) ? -errno : 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/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index b056f8229..5018529da 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 c5801f319..050901990 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 5a7da7512..c43b5bfb6 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 b7359514e..07168e9a8 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 b521a7296..7fff5d5b8 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 edf660db3..f9b7b595d 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 19c2a3c4d..be001a0d2 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 011ec1386..bfa07ba55 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 25deadb94..ad28c110d 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 879bbc120..d9cc2c351 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 885095790..8fe39176a 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 6172f9ac6..a9f6de5d5 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 dec42b976..1ec66d0ba 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 5a92508f0..72b1e7956 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 90fdeda90..6572815f5 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 -E_RTE_SECONDARY;
 
 	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 -E_RTE_SECONDARY;
 
 	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 40af3781b..f4e76a057 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 af2c216f3..ade5d1d75 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;
@@ -682,9 +682,11 @@ fs_promiscuous_enable(struct rte_eth_dev *dev)
 		}
 	}
 	fs_unlock(dev, 0);
+
+	return ret;
 }
 
-static void
+static int
 fs_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct sub_device *sdev;
@@ -712,6 +714,8 @@ fs_promiscuous_disable(struct rte_eth_dev *dev)
 		}
 	}
 	fs_unlock(dev, 0);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 8cb7337ea..f0f629008 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 17a3625d6..c50cdd9f8 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 390cb2196..79bd3a70c 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 95b774284..22e5e1409 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 652f0accc..7f69e27a2 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 99b1f43b8..22a88c88d 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 9d0e339a5..eecf9c86c 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 c7b336bbd..830e71797 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 476d5e52b..9079073c9 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 0108db890..023b267d7 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);
 
@@ -4181,7 +4181,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);
@@ -4190,9 +4190,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);
@@ -4205,6 +4207,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
@@ -8402,20 +8406,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 d97e357e3..e1eaf9eb8 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 7730b530a..21517d70a 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 623ebd88c..b5706bb78 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,11 +384,14 @@ 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);
+	return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_ON);
 }
 
 /**
@@ -388,11 +399,14 @@ 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);
+	return mlx4_rxmode_toggle(dev, RXMODE_TOGGLE_PROMISC_OFF);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 5482eb7b4..0887e6de2 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -760,8 +760,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 d5077db0d..56fc1b636 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,23 @@ 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)
+			return ret;
 	}
-	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));
+
+	/*
+	 * rte_eth_dev_promiscuous_enable() rollback
+	 * dev->data->promiscuous in the case of failure.
+	 */
+	return ret;
 }
 
 /**
@@ -56,20 +68,32 @@ 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)
+			return ret;
+	}
 	ret = mlx5_traffic_restart(dev);
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot disable promiscuous mode: %s",
 			dev->data->port_id, strerror(rte_errno));
+
+	/*
+	 * 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 3ba0ac76e..1090af03b 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 345c24404..7babc891a 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;
 }
 
 /**
@@ -1040,19 +1047,26 @@ 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
+static int
 mrvl_promiscuous_disable(struct rte_eth_dev *dev)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	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 7353211c1..d04a6c8ac 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 e0ebe4e1c..01f227648 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 d53d27bb7..d133438bb 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 97bfcb238..17708c84c 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 4c59651d6..1d5bafa98 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 3d5b99c94..a9858036a 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 1faa7b7c6..47cea4e9b 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 5de0a1d4d..8814622e4 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 024c295aa..5a97a090a 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 d2e3d36d6..4f324a6d5 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1380,33 +1380,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 013b6bbd6..5faf14b67 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 ca066a3d3..2f3811b67 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 f85458c3c..41612ce83 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 f3ba07ae3..edc956bb3 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 8fe9dcebd..1ba4aa37e 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 3ed34f825..bfe978c4a 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 b97dd8aa8..f2e6b4c83 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 diag;
 
 	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;
+	diag = (*dev->dev_ops->promiscuous_enable)(dev);
+	dev->data->promiscuous = (diag == 0) ? 1 : old_promiscuous;
 
-	return 0;
+	return eth_err(port_id, diag);
 }
 
 int
 rte_eth_promiscuous_disable(uint16_t port_id)
 {
 	struct rte_eth_dev *dev;
+	uint8_t old_promiscuous;
+	int diag;
 
 	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);
+	diag = (*dev->dev_ops->promiscuous_disable)(dev);
+	if (diag != 0)
+		dev->data->promiscuous = old_promiscuous;
 
-	return 0;
+	return eth_err(port_id, diag);
 }
 
 int
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2394b32c8..eacd56554 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -52,11 +52,55 @@ 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);
-/**< @internal Function used to enable the RX promiscuous mode of an Ethernet device. */
+/**
+ * @internal
+ * Function used to enable the Rx promiscuous mode of an Ethernet device.
+ *
+ * @param dev
+ *   ethdev handle of port.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ *
+ * @retval 0
+ *   Success, promiscuous mode is enabled.
+ * @retval -ENOTSUP
+ *   Promiscuous mode is not supported.
+ * @retval -ENODEV
+ *   Device is gone.
+ * @retval -E_RTE_SECONDARY
+ *   Function was called from a secondary process instance and not supported.
+ * @retval -ETIMEDOUT
+ *   Attempt to enable promiscuos mode failed because of timeout.
+ * @retval -EAGAIN
+ *   Failed to enable promiscuous mode.
+ */
+typedef int (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev);
 
-typedef void (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to disable the RX promiscuous mode of an Ethernet device. */
+/**
+ * @internal
+ * Function used to disable the R promiscuous mode of an Ethernet device.
+ *
+ * @param dev
+ *   ethdev handle of port.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ *
+ * @retval 0
+ *   Success, promiscuous mode is disabled.
+ * @retval -ENOTSUP
+ *   Promiscuous mode disabling is not supported.
+ * @retval -ENODEV
+ *   Device is gone.
+ * @retval -E_RTE_SECONDARY
+ *   Function was called from a secondary process instance and not supported.
+ * @retval -ETIMEDOUT
+ *   Attempt to disable promiscuos mode failed because of timeout.
+ * @retval -EAGAIN
+ *   Failed to disable promiscuous mode.
+ */
+typedef int (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
 
 typedef void (*eth_allmulticast_enable_t)(struct rte_eth_dev *dev);
 /**< @internal Enable the receipt of all multicast packets by an Ethernet device. */
-- 
2.17.1


  parent reply index

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-05 16:10 [dpdk-dev] [PATCH 00/13] ethdev: change promiscuous mode functions " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 02/13] net/failsafe: check code of promiscuous mode switch Andrew Rybchenko
2019-09-05 16:25   ` Gaëtan Rivet
2019-09-05 16:32     ` Andrew Rybchenko
2019-09-05 16:36   ` Stephen Hemminger
2019-09-05 16:38     ` Andrew Rybchenko
2019-09-06  9:24       ` Gaëtan Rivet
2019-09-06 10:08         ` Andrew Rybchenko
2019-09-05 16:40   ` Stephen Hemminger
2019-09-05 16:49     ` Andrew Rybchenko
2019-09-05 17:13       ` Stephen Hemminger
2019-09-05 16:10 ` [dpdk-dev] [PATCH 03/13] net/bonding: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 04/13] ethdev: change promiscuous callbacks to return status Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 05/13] ethdev: do nothing if promiscuous mode is applied again Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 06/13] app/pipeline: check code of promiscuous mode switch Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 07/13] app/testpmd: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 08/13] app/eventdev: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 09/13] app/pdump: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 10/13] app/test: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 11/13] kni: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 12/13] test/bonding: " Andrew Rybchenko
2019-09-05 16:10 ` [dpdk-dev] [PATCH 13/13] examples: take promiscuous mode switch result into account Andrew Rybchenko
2019-09-09 11:58 ` [dpdk-dev] [PATCH v2 00/13] ethdev: change promiscuous mode functions to return status Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-13 15:35     ` Ferruh Yigit
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 02/13] net/failsafe: check code of promiscuous mode switch Andrew Rybchenko
2019-09-09 12:48     ` Gaëtan Rivet
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 03/13] net/bonding: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 04/13] ethdev: change promiscuous callbacks to return status Andrew Rybchenko
2019-09-10  7:53     ` Matan Azrad
2019-09-13 21:05       ` Andrew Rybchenko
2019-09-11  8:46     ` Hyong Youb Kim (hyonkim)
2019-09-13 21:06       ` Andrew Rybchenko
2019-09-16  6:48         ` Hyong Youb Kim (hyonkim)
2019-09-13 15:34     ` Ferruh Yigit
2019-09-13 15:54       ` Andrew Rybchenko
2019-09-13 16:33         ` Ferruh Yigit
2019-09-13 15:39     ` Ferruh Yigit
2019-09-13 16:05       ` Andrew Rybchenko
2019-09-13 16:34         ` Ferruh Yigit
2019-09-13 19:57           ` Andrew Rybchenko
2019-09-16 13:22             ` Ferruh Yigit
2019-09-16 15:45               ` Andrew Rybchenko
2019-09-16 15:58                 ` Ferruh Yigit
2019-09-13 16:43     ` Ferruh Yigit
2019-09-13 20:33       ` Andrew Rybchenko
2019-09-13 16:56     ` Ferruh Yigit
2019-09-13 20:38       ` Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 05/13] ethdev: do nothing if promiscuous mode is applied again Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 06/13] app/pipeline: check code of promiscuous mode switch Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 07/13] app/testpmd: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 08/13] app/eventdev: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 09/13] app/pdump: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 10/13] app/test: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 11/13] kni: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 12/13] test/bonding: " Andrew Rybchenko
2019-09-09 11:58   ` [dpdk-dev] [PATCH v2 13/13] examples: take promiscuous mode switch result into account Andrew Rybchenko
2019-09-13 16:40     ` Ferruh Yigit
2019-09-13 18:30       ` Andrew Rybchenko
2019-09-13 16:37   ` [dpdk-dev] [PATCH v2 00/13] ethdev: change promiscuous mode functions to return status Ferruh Yigit
2019-09-14 11:37 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 01/13] ethdev: change promiscuous mode controllers to return errors Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 02/13] net/failsafe: check code of promiscuous mode switch Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 03/13] net/bonding: " Andrew Rybchenko
2019-09-14 11:37   ` Andrew Rybchenko [this message]
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 05/13] ethdev: do nothing if promiscuous mode is applied again Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 06/13] app/pipeline: check code of promiscuous mode switch Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 07/13] app/testpmd: " Andrew Rybchenko
2019-09-16 13:18     ` Iremonger, Bernard
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 08/13] app/eventdev: " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 09/13] app/pdump: " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 10/13] app/test: " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 11/13] kni: " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 12/13] test/bonding: " Andrew Rybchenko
2019-09-14 11:37   ` [dpdk-dev] [PATCH v3 13/13] examples: take promiscuous mode switch result into account Andrew Rybchenko
2019-09-24  7:31   ` [dpdk-dev] [PATCH v3 00/13] ethdev: change promiscuous mode functions to return status Ferruh Yigit

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1568461055-16472-5-git-send-email-arybchenko@solarflare.com \
    --to=arybchenko@solarflare.com \
    --cc=ajit.khaparde@broadcom.com \
    --cc=alejandro.lucero@netronome.com \
    --cc=allain.legacy@windriver.com \
    --cc=beilei.xing@intel.com \
    --cc=cernay@netcope.com \
    --cc=chas3@att.com \
    --cc=cloud.wangxiaoyun@huawei.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=g.singh@nxp.com \
    --cc=gaetan.rivet@6wind.com \
    --cc=haiyangz@microsoft.com \
    --cc=hemant.agrawal@nxp.com \
    --cc=hyonkim@cisco.com \
    --cc=igor.russkikh@aquantia.com \
    --cc=jerinj@marvell.com \
    --cc=jingjing.wu@intel.com \
    --cc=johndale@cisco.com \
    --cc=keith.wiles@intel.com \
    --cc=kirankumark@marvell.com \
    --cc=konstantin.ananyev@intel.com \
    --cc=kys@microsoft.com \
    --cc=linville@tuxdriver.com \
    --cc=lironh@marvell.com \
    --cc=matan@mellanox.com \
    --cc=matt.peters@windriver.com \
    --cc=maxime.coquelin@redhat.com \
    --cc=mczekaj@marvell.com \
    --cc=ndabilpuram@marvell.com \
    --cc=pavel.belous@aquantia.com \
    --cc=qi.z.zhang@intel.com \
    --cc=qiming.yang@intel.com \
    --cc=rahul.lakkireddy@chelsio.com \
    --cc=ravi1.kumar@amd.com \
    --cc=remes@netcope.com \
    --cc=rmody@marvell.com \
    --cc=rosen.xu@intel.com \
    --cc=sachin.saxena@nxp.com \
    --cc=shahafs@mellanox.com \
    --cc=shshaikh@marvell.com \
    --cc=somnath.kotur@broadcom.com \
    --cc=srinivasan@marvell.com \
    --cc=sthemmin@microsoft.com \
    --cc=sthotton@marvell.com \
    --cc=tdu@semihalf.com \
    --cc=thomas@monjalon.net \
    --cc=tiwei.bie@intel.com \
    --cc=viacheslavo@mellanox.com \
    --cc=wenzhuo.lu@intel.com \
    --cc=xiao.w.wang@intel.com \
    --cc=xiaolong.ye@intel.com \
    --cc=xuanziyang2@huawei.com \
    --cc=yongwang@vmware.com \
    --cc=zhihong.wang@intel.com \
    --cc=zhouguoyang@huawei.com \
    --cc=zr@semihalf.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

DPDK-dev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dpdk-dev/0 dpdk-dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dpdk-dev dpdk-dev/ https://lore.kernel.org/dpdk-dev \
		dev@dpdk.org dpdk-dev@archiver.kernel.org
	public-inbox-index dpdk-dev

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/ public-inbox