diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c index e295891c060..b34df416a2c 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 66131b53e7a..04957272814 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 aa716f3195c..096815732de 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 b056f8229a2..5018529da10 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 c5801f319ac..050901990c5 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 5a7da751269..c43b5bfb6f6 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 b7359514e53..07168e9a8a7 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 b521a72963a..7fff5d5b8fe 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 edf660db346..f9b7b595df8 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 19c2a3c4dbe..be001a0d243 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 011ec13860e..bfa07ba5554 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 25deadb9494..ad28c110d70 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 879bbc120d9..d9cc2c35106 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 8850957902a..8fe39176afc 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 6172f9ac644..a9f6de5d522 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 dec42b97638..1ec66d0baf7 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 5a92508f006..72b1e7956b4 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 90fdeda901f..6572815f58a 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 40af3781b38..f4e76a057a2 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 af2c216f336..ade5d1d75b2 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 8cb7337ea50..f0f62900896 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 17a3625d634..c50cdd9f81a 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 390cb21964c..79bd3a70c9b 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 95b77428486..22e5e1409d2 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 652f0acccac..7f69e27a246 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 99b1f43b826..22a88c88dd7 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 3214ed6017c..17867b9693a 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -67,8 +67,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, @@ -3103,7 +3103,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); @@ -3111,18 +3111,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); @@ -3130,13 +3138,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 c7b336bbd15..830e7179704 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 476d5e52bdb..9079073c953 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 0108db890b0..023b267d743 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 d97e357e3c3..e1eaf9eb8ad 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 7730b530afb..21517d70a21 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 623ebd88cbf..b5706bb78ea 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 5482eb7b49f..0887e6de22e 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 d5077db0dbb..56fc1b636de 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 3ba0ac76e20..1090af03b1e 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 345c24404de..7babc891ae4 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 7353211c129..d04a6c8acba 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 e0ebe4e1c8d..01f2276482d 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 d53d27bb731..d133438bbd7 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 97bfcb238d9..17708c84c62 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 4c59651d667..1d5bafa98a0 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 3d5b99c943e..a9858036a9b 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 1faa7b7c6ba..47cea4e9b24 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 5de0a1d4d10..8814622e438 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 024c295aa67..5a97a090ae5 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 d2e3d36d62d..4f324a6d5fb 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 013b6bbd63b..5faf14b6746 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 ca066a3d3d2..2f3811b67f6 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 f85458c3cdb..41612ce838c 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 f3ba07ae378..edc956bb3df 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 8fe9dcebdaf..1ba4aa37e82 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 3ed34f82582..bfe978c4a51 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 b97dd8aa85b..f2e6b4c83bc 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 2394b32c836..552da38c8ae 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 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 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. */