DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
@ 2018-02-27 15:11 Olivier Matz
  2018-03-05 10:29 ` Adrien Mazarguil
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Olivier Matz @ 2018-02-27 15:11 UTC (permalink / raw)
  To: dev; +Cc: Thomas Monjalon, Ferruh Yigit

Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
return code is added to notify the caller (librte_ether) if an error
occurred in the PMD.

The new default MAC address is now copied in dev->data->mac_addrs[0]
only if the operation is successful.

The patch also updates all the PMDs accordingly.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---

Hi,

This patch is the following of the discussion we had in this thread:
https://dpdk.org/dev/patchwork/patch/32284/

I did my best to keep the consistency inside the PMDs. The behavior
of eth_mac_addr_set() is inspired from other fonctions in the same
PMD, usually eth_mac_addr_add(). For instance:
- dpaa and dpaa2 return 0 on error.
- some PMDs (bnxt, mlx5, ...?) do not return a -errno code (-1 or
  positive values).
- some PMDs (avf, tap) check if the address is the same and return 0
  in that case. This could go in generic code?

I tried to use the following errors when relevant:
- -EPERM when a VF is not allowed to do a change
- -ENOTSUP if the function is not supported
- -EIO if this is an unknown error from lower layer (hw or sdk)
- -EINVAL for other unknown errors

Please, PMD maintainers, feel free to comment if you ahve specific
needs for your driver.

Thanks
Olivier


 doc/guides/rel_notes/deprecation.rst    |  8 --------
 drivers/net/ark/ark_ethdev.c            |  9 ++++++---
 drivers/net/avf/avf_ethdev.c            | 12 ++++++++----
 drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
 drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
 drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
 drivers/net/e1000/igb_ethdev.c          | 12 +++++++-----
 drivers/net/failsafe/failsafe_ops.c     | 16 +++++++++++++---
 drivers/net/i40e/i40e_ethdev.c          | 24 ++++++++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c       | 12 +++++++-----
 drivers/net/ixgbe/ixgbe_ethdev.c        | 13 ++++++++-----
 drivers/net/mlx4/mlx4.h                 |  2 +-
 drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
 drivers/net/mlx5/mlx5.h                 |  2 +-
 drivers/net/mlx5/mlx5_mac.c             |  7 +++++--
 drivers/net/mrvl/mrvl_ethdev.c          |  7 ++++++-
 drivers/net/null/rte_eth_null.c         |  3 ++-
 drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
 drivers/net/qede/qede_ethdev.c          |  7 +++----
 drivers/net/sfc/sfc_ethdev.c            | 14 +++++---------
 drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
 drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++------------
 drivers/net/virtio/virtio_ethdev.c      | 15 ++++++++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
 lib/librte_ether/rte_ethdev.c           |  7 +++++--
 lib/librte_ether/rte_ethdev_core.h      |  2 +-
 test/test/virtual_pmd.c                 |  3 ++-
 28 files changed, 159 insertions(+), 97 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 74c18ed7c..2bf360f0d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -134,14 +134,6 @@ Deprecation Notices
   between the VF representor and the VF or the parent PF. Those new fields
   are to be included in ``rte_eth_dev_info`` struct.
 
-* ethdev: The prototype and the behavior of
-  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
-  will be added to notify the caller if an error occurred in the PMD. In
-  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
-  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
-  successful. This modification will only impact the PMDs, not the
-  applications.
-
 * ethdev: functions add rx/tx callback will return named opaque type
   ``rte_eth_add_rx_callback()``, ``rte_eth_add_first_rx_callback()`` and
   ``rte_eth_add_tx_callback()`` functions currently return callback object as
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ff87c20e2..3fc40cd74 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
 				  struct rte_eth_stats *stats);
 static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
-static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
+static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
 			       struct ether_addr *mac_addr,
@@ -887,16 +887,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
 			      ark->user_data[dev->data->port_id]);
 }
 
-static void
+static int
 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
 	struct ark_adapter *ark =
 		(struct ark_adapter *)dev->data->dev_private;
 
-	if (ark->user_ext.mac_addr_set)
+	if (ark->user_ext.mac_addr_set) {
 		ark->user_ext.mac_addr_set(dev, mac_addr,
 			   ark->user_data[dev->data->port_id]);
+		return 0;
+	}
+	return -ENOTSUP;
 }
 
 static int
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index 4df661705..0866f0bed 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				     struct rte_eth_rss_conf *rss_conf);
 static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
 					uint16_t queue_id);
@@ -926,7 +926,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
@@ -940,11 +940,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
 	if (is_same_ether_addr(mac_addr, old_addr))
-		return;
+		return 0;
 
 	/* If the MAC address is configured by host, skip the setting */
 	if (is_valid_assigned_ether_addr(perm_addr))
-		return;
+		return -EPERM;
 
 	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
 	if (ret)
@@ -968,7 +968,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			    mac_addr->addr_bytes[4],
 			    mac_addr->addr_bytes[5]);
 
+	if (ret)
+		return -EIO;
+
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 21c46f833..8eb923ebb 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1398,7 +1398,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 	return 0;
 }
 
-static void
+static int
 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
@@ -1408,7 +1408,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 	int rc;
 
 	if (BNXT_VF(bp))
-		return;
+		return -EPERM;
 
 	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
 
@@ -1418,7 +1418,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			continue;
 		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
 		if (rc)
-			break;
+			return rc;
 		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
 		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
@@ -1427,10 +1427,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
-			break;
+			return rc;
 		filter->mac_index = 0;
 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index c34c3251f..979d8efcd 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2851,11 +2851,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
-	if (mac_address_set(dev, addr))
+	if (mac_address_set(dev, addr)) {
 		RTE_BOND_LOG(ERR, "Failed to update MAC address");
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct eth_dev_ops default_dev_ops = {
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9b69ef456..8227446e4 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 	fman_if_clear_mac_addr(dpaa_intf->fif, index);
 }
 
-static void
+static int
 dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
 	if (ret)
 		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+
+	return 0;
 }
 
 static struct eth_dev_ops dpaa_devops = {
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 09a11d65a..2d092e72c 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1074,7 +1074,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
 			"error: Removing the MAC ADDR failed: err = %d\n", ret);
 }
 
-static void
+static int
 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -1086,7 +1086,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	if (dpni == NULL) {
 		RTE_LOG(ERR, PMD, "dpni is NULL\n");
-		return;
+		return -EINVAL;
 	}
 
 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
@@ -1095,6 +1095,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 	if (ret)
 		RTE_LOG(ERR, PMD,
 			"error: Setting the MAC ADDR failed %d\n", ret);
+
+	return 0;
 }
 static
 int dpaa2_dev_stats_get(struct rte_eth_dev *dev,
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 3c5138dea..e5be0d4a8 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -146,7 +146,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
 			   struct ether_addr *mac_addr,
 			   uint32_t index, uint32_t pool);
 static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 
 static void igbvf_intr_disable(struct e1000_hw *hw);
@@ -171,7 +171,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
-static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
+static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 static int igbvf_get_reg_length(struct rte_eth_dev *dev);
 static int igbvf_get_regs(struct rte_eth_dev *dev,
@@ -3146,13 +3146,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *addr)
 {
 	eth_igb_rar_clear(dev, 0);
-
 	eth_igb_rar_set(dev, (void *)addr, 0, 0);
+
+	return 0;
 }
 /*
  * Virtual Function operations
@@ -3504,7 +3505,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
+static int
 igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct e1000_hw *hw =
@@ -3512,6 +3513,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 	/* index is not used by rar_set() */
 	hw->mac.ops.rar_set(hw, (void *)addr, 0);
+	return 0;
 }
 
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 057e435cf..d2f302ffb 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -997,16 +997,26 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
-	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
-		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+		if ((ret = fs_err(sdev, ret))) {
+			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %"
+			      PRIu8 " with error %d", i, ret);
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 508b4171c..455b1d0be 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
 static int i40e_get_eeprom(struct rte_eth_dev *dev,
 			   struct rte_dev_eeprom_info *eeprom);
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -11249,8 +11249,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-				      struct ether_addr *mac_addr)
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+				     struct ether_addr *mac_addr)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11261,7 +11261,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
@@ -11271,25 +11271,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (f == NULL) {
 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
-		return;
+		return -EIO;
 	}
 
 	mac_filter = f->mac_info;
 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
 
-	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
-				  mac_addr->addr_bytes, NULL);
+	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+					mac_addr->addr_bytes, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to change mac");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index fd003fe01..df9709f80 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 					struct rte_eth_rss_conf *rss_conf);
 static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 					struct ether_addr *mac_addr);
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
@@ -2658,7 +2658,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 			    struct ether_addr *mac_addr)
 {
@@ -2667,15 +2667,17 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-		return;
+		return -EPERM;
 
 	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
-	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
+		return -EIO;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 448325857..4167b57e9 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -228,7 +228,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			 uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -286,7 +286,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
 					     struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
 			struct rte_eth_syn_filter *filter);
@@ -4853,14 +4853,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
 	ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
 	ixgbe_remove_rar(dev, 0);
-
 	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+	return 0;
 }
 
 static bool
@@ -5983,12 +5984,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
 	}
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 19c8a223d..c107794ce 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 		      uint32_t index, uint32_t vmdq);
-void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 void mlx4_stats_reset(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 3bc692731..2442e16a6 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -701,11 +701,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 965c19f21..42e58d7f7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -241,7 +241,7 @@ int priv_get_mac(struct priv *, uint8_t (*)[ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *, uint32_t);
 int mlx5_mac_addr_add(struct rte_eth_dev *, struct ether_addr *, uint32_t,
 		      uint32_t);
-void mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
+int mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
 
 /* mlx5_rss.c */
 
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index e8a8d4594..0dc4bec46 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -118,10 +118,13 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success.
  */
-void
+int
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	DEBUG("%p: setting primary MAC address", (void *)dev);
-	mlx5_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
 }
diff --git a/drivers/net/mrvl/mrvl_ethdev.c b/drivers/net/mrvl/mrvl_ethdev.c
index 705c4bd8b..8e14e54e2 100644
--- a/drivers/net/mrvl/mrvl_ethdev.c
+++ b/drivers/net/mrvl/mrvl_ethdev.c
@@ -952,6 +952,9 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
 static void
 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
@@ -960,7 +963,7 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return -EPERM;
 
 	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
 	if (ret) {
@@ -968,6 +971,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ether_format_addr(buf, sizeof(buf), mac_addr);
 		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index d003b2839..3b659cd23 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -461,10 +461,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 		    __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index b739c0b39..fabf86aa5 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -594,7 +594,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
 	octeontx_port_stats_clr(nic);
 }
 
-static void
+static int
 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct ether_addr *addr)
 {
@@ -605,6 +605,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 	if (ret != 0)
 		octeontx_log_err("failed to set MAC address on port %d",
 				nic->port_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index a91f43683..e4cd89511 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1001,7 +1001,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1010,12 +1010,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
 					       mac_addr->addr_bytes)) {
 		DP_ERR(edev, "Setting MAC address is not allowed\n");
-		ether_addr_copy(&qdev->primary_mac,
-				&eth_dev->data->mac_addrs[0]);
-		return;
+		return -EPERM;
 	}
 
 	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+	return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 89a452907..b76d4bb2c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -920,7 +920,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	SFC_ASSERT(rc > 0);
 	return -rc;
 }
-static void
+static int
 sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
@@ -939,13 +939,14 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	if (port->isolated) {
 		sfc_err(sa, "isolated mode is active on the port");
 		sfc_err(sa, "will not set MAC address");
+		rc = ENOTSUP;
 		goto unlock;
 	}
 
 	if (sa->state != SFC_ADAPTER_STARTED) {
 		sfc_info(sa, "the port is not started");
 		sfc_info(sa, "the new MAC address will be set on port start");
-
+		rc = EINVAL;
 		goto unlock;
 	}
 
@@ -982,14 +983,9 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	}
 
 unlock:
-	/*
-	 * In the case of failure sa->port->default_mac_addr does not
-	 * need rollback since no error code is returned, and the upper
-	 * API will anyway update the external MAC address storage.
-	 * To be consistent with that new value it is better to keep
-	 * the device private value the same.
-	 */
 	sfc_adapter_unlock(sa);
+	SFC_ASSERT(rc >= 0);
+	return -rc;
 }
 
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index e53c738db..1a1e2356b 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1315,10 +1315,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 		struct ether_addr *mac_addr __rte_unused)
 {
+	return 0;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index f09db0ea9..ac99b233c 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -929,48 +929,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
 
-static void
+static int
 tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	enum ioctl_mode mode = LOCAL_ONLY;
 	struct ifreq ifr;
+	int ret;
 
 	if (is_zero_ether_addr(mac_addr)) {
 		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
 			dev->device->name);
-		return;
+		return -EINVAL;
 	}
 	/* Check the actual current MAC address on the tap netdevice */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
+	if (ret < 0)
+		return ret;
 	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
-		return;
+		return 0;
 	/* Check the current MAC address on the remote */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
+	if (ret < 0)
+		return ret;
 	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
 		mode = LOCAL_AND_REMOTE;
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
+	if (ret < 0)
+		return ret;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 	if (pmd->remote_if_index && !pmd->flow_isolate) {
 		/* Replace MAC redirection rule after a MAC change */
-		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't delete MAC redirection rule\n",
 				dev->device->name);
-			return;
+			return ret;
 		}
-		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't add MAC redirection rule\n",
 				dev->device->name);
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 884f74ad0..38a7a14f7 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -68,7 +68,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -1097,7 +1097,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 	virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1113,9 +1113,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
 		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-		virtio_send_command(hw->cvq, &ctrl, &len, 1);
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-		virtio_set_hwaddr(hw);
+		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	}
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+		return -ENOTSUP;
+
+	virtio_set_hwaddr(hw);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 4e68aae6b..13ee8f250 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -73,7 +73,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
+static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
 				 struct ether_addr *mac_addr);
 static void vmxnet3_interrupt_handler(void *param);
 
@@ -1117,13 +1117,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+static int
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
+	return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0590f0c10..6a7330d92 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3003,6 +3003,7 @@ int
 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3012,11 +3013,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
+	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+	if (ret < 0)
+		return ret;
+
 	/* Update default address in NIC data structure */
 	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
-	(*dev->dev_ops->mac_addr_set)(dev, addr);
-
 	return 0;
 }
 
diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
index e5681e466..55eb2b09e 100644
--- a/lib/librte_ether/rte_ethdev_core.h
+++ b/lib/librte_ether/rte_ethdev_core.h
@@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
 				  uint32_t vmdq);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
-typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 2f5b31dba..69b4ba034 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -216,10 +216,11 @@ static void
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
 {}
 
-static void
+static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 			       __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
-- 
2.11.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
@ 2018-03-05 10:29 ` Adrien Mazarguil
  2018-03-06  9:37 ` Tomasz Duszynski
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 21+ messages in thread
From: Adrien Mazarguil @ 2018-03-05 10:29 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev, Thomas Monjalon, Ferruh Yigit

On Tue, Feb 27, 2018 at 04:11:29PM +0100, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
> 
> Hi,
> 
> This patch is the following of the discussion we had in this thread:
> https://dpdk.org/dev/patchwork/patch/32284/
> 
> I did my best to keep the consistency inside the PMDs. The behavior
> of eth_mac_addr_set() is inspired from other fonctions in the same
> PMD, usually eth_mac_addr_add(). For instance:
> - dpaa and dpaa2 return 0 on error.
> - some PMDs (bnxt, mlx5, ...?) do not return a -errno code (-1 or
>   positive values).
> - some PMDs (avf, tap) check if the address is the same and return 0
>   in that case. This could go in generic code?
> 
> I tried to use the following errors when relevant:
> - -EPERM when a VF is not allowed to do a change
> - -ENOTSUP if the function is not supported
> - -EIO if this is an unknown error from lower layer (hw or sdk)

Keep in mind EIO is currently documented in ethdev as somewhat
hot-plug-related, as in "device is unresponsive and likely unplugged". The
reaction of a hot-plug-aware application to such an error code might be to
close the device, possibly for the wrong reason.

I just wanted to point it out, I don't think it's a problem for this patch
but can't speak for all PMDs.

> - -EINVAL for other unknown errors
> 
> Please, PMD maintainers, feel free to comment if you ahve specific
> needs for your driver.

OK with the API change and it's fine for mlx4 and mlx5, with a few comments
regarding the latter, please see below.

<snip>
> diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
> index 19c8a223d..c107794ce 100644
> --- a/drivers/net/mlx4/mlx4.h
> +++ b/drivers/net/mlx4/mlx4.h
> @@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
>  void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
>  int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
>  		      uint32_t index, uint32_t vmdq);
> -void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
> +int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
>  int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
>  int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
>  void mlx4_stats_reset(struct rte_eth_dev *dev);
> diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
> index 3bc692731..2442e16a6 100644
> --- a/drivers/net/mlx4/mlx4_ethdev.c
> +++ b/drivers/net/mlx4/mlx4_ethdev.c
> @@ -701,11 +701,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, negative errno value otherwise and rte_errno is set.
>   */
> -void
> +int
>  mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
> -	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
> +	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
>  }
>  
>  /**
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index 965c19f21..42e58d7f7 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -241,7 +241,7 @@ int priv_get_mac(struct priv *, uint8_t (*)[ETHER_ADDR_LEN]);
>  void mlx5_mac_addr_remove(struct rte_eth_dev *, uint32_t);
>  int mlx5_mac_addr_add(struct rte_eth_dev *, struct ether_addr *, uint32_t,
>  		      uint32_t);
> -void mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
> +int mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
>  
>  /* mlx5_rss.c */
>  
> diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> index e8a8d4594..0dc4bec46 100644
> --- a/drivers/net/mlx5/mlx5_mac.c
> +++ b/drivers/net/mlx5/mlx5_mac.c
> @@ -118,10 +118,13 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success.
>   */
> -void
> +int
>  mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	DEBUG("%p: setting primary MAC address", (void *)dev);
> -	mlx5_mac_addr_add(dev, mac_addr, 0, 0);
> +	return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
>  }

With Nelio's errno rework for mlx5 [1][2], this change should end up being
similar to mlx4.

[1] http://dpdk.org/ml/archives/dev/2018-February/091668.html
[2] http://dpdk.org/ml/archives/dev/2018-February/091678.html

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
  2018-03-05 10:29 ` Adrien Mazarguil
@ 2018-03-06  9:37 ` Tomasz Duszynski
  2018-03-16 15:41 ` Andrew Rybchenko
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 21+ messages in thread
From: Tomasz Duszynski @ 2018-03-06  9:37 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev, Thomas Monjalon, Ferruh Yigit

Hi,

Some comments inline.

On Tue, Feb 27, 2018 at 04:11:29PM +0100, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
>
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
>
> The patch also updates all the PMDs accordingly.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>
> Hi,
>
> This patch is the following of the discussion we had in this thread:
> https://dpdk.org/dev/patchwork/patch/32284/
>
> I did my best to keep the consistency inside the PMDs. The behavior
> of eth_mac_addr_set() is inspired from other fonctions in the same
> PMD, usually eth_mac_addr_add(). For instance:
> - dpaa and dpaa2 return 0 on error.
> - some PMDs (bnxt, mlx5, ...?) do not return a -errno code (-1 or
>   positive values).
> - some PMDs (avf, tap) check if the address is the same and return 0
>   in that case. This could go in generic code?
>
> I tried to use the following errors when relevant:
> - -EPERM when a VF is not allowed to do a change
> - -ENOTSUP if the function is not supported
> - -EIO if this is an unknown error from lower layer (hw or sdk)
> - -EINVAL for other unknown errors
>
> Please, PMD maintainers, feel free to comment if you ahve specific
> needs for your driver.
>
> Thanks
> Olivier
>
>
>  doc/guides/rel_notes/deprecation.rst    |  8 --------
>  drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>  drivers/net/avf/avf_ethdev.c            | 12 ++++++++----
>  drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>  drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>  drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>  drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>  drivers/net/e1000/igb_ethdev.c          | 12 +++++++-----
>  drivers/net/failsafe/failsafe_ops.c     | 16 +++++++++++++---
>  drivers/net/i40e/i40e_ethdev.c          | 24 ++++++++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c       | 12 +++++++-----
>  drivers/net/ixgbe/ixgbe_ethdev.c        | 13 ++++++++-----
>  drivers/net/mlx4/mlx4.h                 |  2 +-
>  drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>  drivers/net/mlx5/mlx5.h                 |  2 +-
>  drivers/net/mlx5/mlx5_mac.c             |  7 +++++--
>  drivers/net/mrvl/mrvl_ethdev.c          |  7 ++++++-
>  drivers/net/null/rte_eth_null.c         |  3 ++-
>  drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>  drivers/net/qede/qede_ethdev.c          |  7 +++----
>  drivers/net/sfc/sfc_ethdev.c            | 14 +++++---------
>  drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>  drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++------------
>  drivers/net/virtio/virtio_ethdev.c      | 15 ++++++++++-----
>  drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>  lib/librte_ether/rte_ethdev.c           |  7 +++++--
>  lib/librte_ether/rte_ethdev_core.h      |  2 +-
>  test/test/virtual_pmd.c                 |  3 ++-
>  28 files changed, 159 insertions(+), 97 deletions(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 74c18ed7c..2bf360f0d 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -134,14 +134,6 @@ Deprecation Notices
>    between the VF representor and the VF or the parent PF. Those new fields
>    are to be included in ``rte_eth_dev_info`` struct.
>
> -* ethdev: The prototype and the behavior of
> -  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
> -  will be added to notify the caller if an error occurred in the PMD. In
> -  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
> -  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
> -  successful. This modification will only impact the PMDs, not the
> -  applications.
> -
>  * ethdev: functions add rx/tx callback will return named opaque type
>    ``rte_eth_add_rx_callback()``, ``rte_eth_add_first_rx_callback()`` and
>    ``rte_eth_add_tx_callback()`` functions currently return callback object as
> diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
> index ff87c20e2..3fc40cd74 100644
> --- a/drivers/net/ark/ark_ethdev.c
> +++ b/drivers/net/ark/ark_ethdev.c
> @@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
>  static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
>  				  struct rte_eth_stats *stats);
>  static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
> -static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
>  					 struct ether_addr *mac_addr);
>  static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
>  			       struct ether_addr *mac_addr,
> @@ -887,16 +887,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
>  			      ark->user_data[dev->data->port_id]);
>  }
>
> -static void
> +static int
>  eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
>  			     struct ether_addr *mac_addr)
>  {
>  	struct ark_adapter *ark =
>  		(struct ark_adapter *)dev->data->dev_private;
>
> -	if (ark->user_ext.mac_addr_set)
> +	if (ark->user_ext.mac_addr_set) {
>  		ark->user_ext.mac_addr_set(dev, mac_addr,
>  			   ark->user_data[dev->data->port_id]);
> +		return 0;
> +	}
> +	return -ENOTSUP;
>  }
>
>  static int
> diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
> index 4df661705..0866f0bed 100644
> --- a/drivers/net/avf/avf_ethdev.c
> +++ b/drivers/net/avf/avf_ethdev.c
> @@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
>  static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
>  				     struct rte_eth_rss_conf *rss_conf);
>  static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
> -static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
>  					 struct ether_addr *mac_addr);
>  static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
>  					uint16_t queue_id);
> @@ -926,7 +926,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  	return ret;
>  }
>
> -static void
> +static int
>  avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
>  			     struct ether_addr *mac_addr)
>  {
> @@ -940,11 +940,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
>  	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
>
>  	if (is_same_ether_addr(mac_addr, old_addr))
> -		return;
> +		return 0;
>
>  	/* If the MAC address is configured by host, skip the setting */
>  	if (is_valid_assigned_ether_addr(perm_addr))
> -		return;
> +		return -EPERM;
>
>  	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
>  	if (ret)
> @@ -968,7 +968,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
>  			    mac_addr->addr_bytes[4],
>  			    mac_addr->addr_bytes[5]);
>
> +	if (ret)
> +		return -EIO;
> +
>  	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
> index 21c46f833..8eb923ebb 100644
> --- a/drivers/net/bnxt/bnxt_ethdev.c
> +++ b/drivers/net/bnxt/bnxt_ethdev.c
> @@ -1398,7 +1398,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
>  	return 0;
>  }
>
> -static void
> +static int
>  bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
>  {
>  	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
> @@ -1408,7 +1408,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
>  	int rc;
>
>  	if (BNXT_VF(bp))
> -		return;
> +		return -EPERM;
>
>  	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
>
> @@ -1418,7 +1418,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
>  			continue;
>  		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
>  		if (rc)
> -			break;
> +			return rc;
>  		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
>  		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
>  		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
> @@ -1427,10 +1427,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
>  			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
>  		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
>  		if (rc)
> -			break;
> +			return rc;
>  		filter->mac_index = 0;
>  		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
>  	}
> +
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index c34c3251f..979d8efcd 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -2851,11 +2851,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  	return 0;
>  }
>
> -static void
> +static int
>  bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
>  {
> -	if (mac_address_set(dev, addr))
> +	if (mac_address_set(dev, addr)) {
>  		RTE_BOND_LOG(ERR, "Failed to update MAC address");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
>  }
>
>  const struct eth_dev_ops default_dev_ops = {
> diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
> index 9b69ef456..8227446e4 100644
> --- a/drivers/net/dpaa/dpaa_ethdev.c
> +++ b/drivers/net/dpaa/dpaa_ethdev.c
> @@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
>  	fman_if_clear_mac_addr(dpaa_intf->fif, index);
>  }
>
> -static void
> +static int
>  dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
>  		       struct ether_addr *addr)
>  {
> @@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
>  	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
>  	if (ret)
>  		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
> +
> +	return 0;
>  }
>
>  static struct eth_dev_ops dpaa_devops = {
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 09a11d65a..2d092e72c 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -1074,7 +1074,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
>  			"error: Removing the MAC ADDR failed: err = %d\n", ret);
>  }
>
> -static void
> +static int
>  dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
>  		       struct ether_addr *addr)
>  {
> @@ -1086,7 +1086,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
>
>  	if (dpni == NULL) {
>  		RTE_LOG(ERR, PMD, "dpni is NULL\n");
> -		return;
> +		return -EINVAL;
>  	}
>
>  	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
> @@ -1095,6 +1095,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
>  	if (ret)
>  		RTE_LOG(ERR, PMD,
>  			"error: Setting the MAC ADDR failed %d\n", ret);
> +
> +	return 0;
>  }
>  static
>  int dpaa2_dev_stats_get(struct rte_eth_dev *dev,
> diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
> index 3c5138dea..e5be0d4a8 100644
> --- a/drivers/net/e1000/igb_ethdev.c
> +++ b/drivers/net/e1000/igb_ethdev.c
> @@ -146,7 +146,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
>  			   struct ether_addr *mac_addr,
>  			   uint32_t index, uint32_t pool);
>  static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
> -static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
> +static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
>  		struct ether_addr *addr);
>
>  static void igbvf_intr_disable(struct e1000_hw *hw);
> @@ -171,7 +171,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
>  		uint16_t vlan_id, int on);
>  static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
>  static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
> -static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
> +static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
>  		struct ether_addr *addr);
>  static int igbvf_get_reg_length(struct rte_eth_dev *dev);
>  static int igbvf_get_regs(struct rte_eth_dev *dev,
> @@ -3146,13 +3146,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
>  	e1000_rar_set(hw, addr, index);
>  }
>
> -static void
> +static int
>  eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
>  				struct ether_addr *addr)
>  {
>  	eth_igb_rar_clear(dev, 0);
> -
>  	eth_igb_rar_set(dev, (void *)addr, 0, 0);
> +
> +	return 0;
>  }
>  /*
>   * Virtual Function operations
> @@ -3504,7 +3505,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
>  	return 0;
>  }
>
> -static void
> +static int
>  igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
>  {
>  	struct e1000_hw *hw =
> @@ -3512,6 +3513,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
>
>  	/* index is not used by rar_set() */
>  	hw->mac.ops.rar_set(hw, (void *)addr, 0);
> +	return 0;
>  }
>
>
> diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
> index 057e435cf..d2f302ffb 100644
> --- a/drivers/net/failsafe/failsafe_ops.c
> +++ b/drivers/net/failsafe/failsafe_ops.c
> @@ -997,16 +997,26 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
>  	return 0;
>  }
>
> -static void
> +static int
>  fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct sub_device *sdev;
>  	uint8_t i;
> +	int ret;
>
>  	fs_lock(dev, 0);
> -	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
> -		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
> +	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
> +		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
> +		if ((ret = fs_err(sdev, ret))) {
> +			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %"
> +			      PRIu8 " with error %d", i, ret);
> +			fs_unlock(dev, 0);
> +			return ret;
> +		}
> +	}
>  	fs_unlock(dev, 0);
> +
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 508b4171c..455b1d0be 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
>  static int i40e_get_eeprom(struct rte_eth_dev *dev,
>  			   struct rte_dev_eeprom_info *eeprom);
>
> -static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
>  				      struct ether_addr *mac_addr);
>
>  static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
> @@ -11249,8 +11249,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
>  	return 0;
>  }
>
> -static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
> -				      struct ether_addr *mac_addr)
> +static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
> +				     struct ether_addr *mac_addr)
>  {
>  	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>  	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> @@ -11261,7 +11261,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
>
>  	if (!is_valid_assigned_ether_addr(mac_addr)) {
>  		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
> -		return;
> +		return -EINVAL;
>  	}
>
>  	TAILQ_FOREACH(f, &vsi->mac_list, next) {
> @@ -11271,25 +11271,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
>
>  	if (f == NULL) {
>  		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
> -		return;
> +		return -EIO;
>  	}
>
>  	mac_filter = f->mac_info;
>  	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
>  	if (ret != I40E_SUCCESS) {
>  		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
> -		return;
> +		return -EIO;
>  	}
>  	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
>  	ret = i40e_vsi_add_mac(vsi, &mac_filter);
>  	if (ret != I40E_SUCCESS) {
>  		PMD_DRV_LOG(ERR, "Failed to add mac filter");
> -		return;
> +		return -EIO;
>  	}
>  	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
>
> -	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
> -				  mac_addr->addr_bytes, NULL);
> +	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
> +					mac_addr->addr_bytes, NULL);
> +	if (ret != I40E_SUCCESS) {
> +		PMD_DRV_LOG(ERR, "Failed to change mac");
> +		return -EIO;
> +	}
> +
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
> index fd003fe01..df9709f80 100644
> --- a/drivers/net/i40e/i40e_ethdev_vf.c
> +++ b/drivers/net/i40e/i40e_ethdev_vf.c
> @@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
>  static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
>  					struct rte_eth_rss_conf *rss_conf);
>  static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
> -static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
>  					struct ether_addr *mac_addr);
>  static int
>  i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
> @@ -2658,7 +2658,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>  	return ret;
>  }
>
> -static void
> +static int
>  i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
>  			    struct ether_addr *mac_addr)
>  {
> @@ -2667,15 +2667,17 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
>
>  	if (!is_valid_assigned_ether_addr(mac_addr)) {
>  		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
> -		return;
> +		return -EINVAL;
>  	}
>
>  	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
> -		return;
> +		return -EPERM;
>
>  	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
>
> -	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
> +	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
> +		return -EIO;
>
>  	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
> +	return 0;
>  }
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 448325857..4167b57e9 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -228,7 +228,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
>  static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
>  			 uint32_t index, uint32_t pool);
>  static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
> -static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
>  					   struct ether_addr *mac_addr);
>  static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
>  static bool is_device_supported(struct rte_eth_dev *dev,
> @@ -286,7 +286,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
>  				struct ether_addr *mac_addr,
>  				uint32_t index, uint32_t pool);
>  static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
> -static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
> +static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
>  					     struct ether_addr *mac_addr);
>  static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
>  			struct rte_eth_syn_filter *filter);
> @@ -4853,14 +4853,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
>  	ixgbe_clear_rar(hw, index);
>  }
>
> -static void
> +static int
>  ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
>  {
>  	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
>
>  	ixgbe_remove_rar(dev, 0);
> -
>  	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
> +
> +	return 0;
>  }
>
>  static bool
> @@ -5983,12 +5984,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
>  	}
>  }
>
> -static void
> +static int
>  ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
>  {
>  	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>
>  	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
> +
> +	return 0;
>  }
>
>  int
> diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
> index 19c8a223d..c107794ce 100644
> --- a/drivers/net/mlx4/mlx4.h
> +++ b/drivers/net/mlx4/mlx4.h
> @@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
>  void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
>  int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
>  		      uint32_t index, uint32_t vmdq);
> -void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
> +int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
>  int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
>  int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
>  void mlx4_stats_reset(struct rte_eth_dev *dev);
> diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
> index 3bc692731..2442e16a6 100644
> --- a/drivers/net/mlx4/mlx4_ethdev.c
> +++ b/drivers/net/mlx4/mlx4_ethdev.c
> @@ -701,11 +701,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, negative errno value otherwise and rte_errno is set.
>   */
> -void
> +int
>  mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
> -	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
> +	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
>  }
>
>  /**
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index 965c19f21..42e58d7f7 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -241,7 +241,7 @@ int priv_get_mac(struct priv *, uint8_t (*)[ETHER_ADDR_LEN]);
>  void mlx5_mac_addr_remove(struct rte_eth_dev *, uint32_t);
>  int mlx5_mac_addr_add(struct rte_eth_dev *, struct ether_addr *, uint32_t,
>  		      uint32_t);
> -void mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
> +int mlx5_mac_addr_set(struct rte_eth_dev *, struct ether_addr *);
>
>  /* mlx5_rss.c */
>
> diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> index e8a8d4594..0dc4bec46 100644
> --- a/drivers/net/mlx5/mlx5_mac.c
> +++ b/drivers/net/mlx5/mlx5_mac.c
> @@ -118,10 +118,13 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success.
>   */
> -void
> +int
>  mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	DEBUG("%p: setting primary MAC address", (void *)dev);
> -	mlx5_mac_addr_add(dev, mac_addr, 0, 0);
> +	return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
>  }
> diff --git a/drivers/net/mrvl/mrvl_ethdev.c b/drivers/net/mrvl/mrvl_ethdev.c
> index 705c4bd8b..8e14e54e2 100644
> --- a/drivers/net/mrvl/mrvl_ethdev.c
> +++ b/drivers/net/mrvl/mrvl_ethdev.c
> @@ -952,6 +952,9 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, negative error value otherwise.
>   */
>  static void
>  mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
> @@ -960,7 +963,7 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  	int ret;
>
>  	if (!priv->ppio)
> -		return;
> +		return -EPERM;

0 should be returned here instead of EPERM. Returning success
will cause DPDK to save mac address internally and later on (once ppio is
actually intialized, i.e port is started) restore it via
rte_eth_dev_config_restore().

Have a look at the following commit for the details:

9f7d41e net/mrvl: allow adding MAC address before port init

>
>  	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
>  	if (ret) {
> @@ -968,6 +971,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  		ether_format_addr(buf, sizeof(buf), mac_addr);
>  		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
>  	}
> +
> +	return ret;
>  }
>
>  /**
> diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
> index d003b2839..3b659cd23 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -461,10 +461,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
>  	return 0;
>  }
>
> -static void
> +static int
>  eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
>  		    __rte_unused struct ether_addr *addr)
>  {
> +	return 0;
>  }
>
>  static const struct eth_dev_ops ops = {
> diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
> index b739c0b39..fabf86aa5 100644
> --- a/drivers/net/octeontx/octeontx_ethdev.c
> +++ b/drivers/net/octeontx/octeontx_ethdev.c
> @@ -594,7 +594,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
>  	octeontx_port_stats_clr(nic);
>  }
>
> -static void
> +static int
>  octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
>  					struct ether_addr *addr)
>  {
> @@ -605,6 +605,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
>  	if (ret != 0)
>  		octeontx_log_err("failed to set MAC address on port %d",
>  				nic->port_id);
> +
> +	return ret;
>  }
>
>  static void
> diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
> index a91f43683..e4cd89511 100644
> --- a/drivers/net/qede/qede_ethdev.c
> +++ b/drivers/net/qede/qede_ethdev.c
> @@ -1001,7 +1001,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
>  	ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
>  }
>
> -static void
> +static int
>  qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
>  {
>  	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
> @@ -1010,12 +1010,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
>  	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
>  					       mac_addr->addr_bytes)) {
>  		DP_ERR(edev, "Setting MAC address is not allowed\n");
> -		ether_addr_copy(&qdev->primary_mac,
> -				&eth_dev->data->mac_addrs[0]);
> -		return;
> +		return -EPERM;
>  	}
>
>  	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
> +	return 0;
>  }
>
>  static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
> diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
> index 89a452907..b76d4bb2c 100644
> --- a/drivers/net/sfc/sfc_ethdev.c
> +++ b/drivers/net/sfc/sfc_ethdev.c
> @@ -920,7 +920,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
>  	SFC_ASSERT(rc > 0);
>  	return -rc;
>  }
> -static void
> +static int
>  sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct sfc_adapter *sa = dev->data->dev_private;
> @@ -939,13 +939,14 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  	if (port->isolated) {
>  		sfc_err(sa, "isolated mode is active on the port");
>  		sfc_err(sa, "will not set MAC address");
> +		rc = ENOTSUP;
>  		goto unlock;
>  	}
>
>  	if (sa->state != SFC_ADAPTER_STARTED) {
>  		sfc_info(sa, "the port is not started");
>  		sfc_info(sa, "the new MAC address will be set on port start");
> -
> +		rc = EINVAL;
>  		goto unlock;
>  	}
>
> @@ -982,14 +983,9 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  	}
>
>  unlock:
> -	/*
> -	 * In the case of failure sa->port->default_mac_addr does not
> -	 * need rollback since no error code is returned, and the upper
> -	 * API will anyway update the external MAC address storage.
> -	 * To be consistent with that new value it is better to keep
> -	 * the device private value the same.
> -	 */
>  	sfc_adapter_unlock(sa);
> +	SFC_ASSERT(rc >= 0);
> +	return -rc;
>  }
>
>
> diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
> index e53c738db..1a1e2356b 100644
> --- a/drivers/net/szedata2/rte_eth_szedata2.c
> +++ b/drivers/net/szedata2/rte_eth_szedata2.c
> @@ -1315,10 +1315,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
>  	return 0;
>  }
>
> -static void
> +static int
>  eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
>  		struct ether_addr *mac_addr __rte_unused)
>  {
> +	return 0;
>  }
>
>  static void
> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
> index f09db0ea9..ac99b233c 100644
> --- a/drivers/net/tap/rte_eth_tap.c
> +++ b/drivers/net/tap/rte_eth_tap.c
> @@ -929,48 +929,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
>  		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
>  }
>
> -static void
> +static int
>  tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct pmd_internals *pmd = dev->data->dev_private;
>  	enum ioctl_mode mode = LOCAL_ONLY;
>  	struct ifreq ifr;
> +	int ret;
>
>  	if (is_zero_ether_addr(mac_addr)) {
>  		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
>  			dev->device->name);
> -		return;
> +		return -EINVAL;
>  	}
>  	/* Check the actual current MAC address on the tap netdevice */
> -	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
> -		return;
> +	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
> +	if (ret < 0)
> +		return ret;
>  	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
>  			       mac_addr))
> -		return;
> +		return 0;
>  	/* Check the current MAC address on the remote */
> -	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
> -		return;
> +	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
> +	if (ret < 0)
> +		return ret;
>  	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
>  			       mac_addr))
>  		mode = LOCAL_AND_REMOTE;
>  	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
>  	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
> -	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
> -		return;
> +	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
> +	if (ret < 0)
> +		return ret;
>  	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
>  	if (pmd->remote_if_index && !pmd->flow_isolate) {
>  		/* Replace MAC redirection rule after a MAC change */
> -		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
> +		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
> +		if (ret < 0) {
>  			RTE_LOG(ERR, PMD,
>  				"%s: Couldn't delete MAC redirection rule\n",
>  				dev->device->name);
> -			return;
> +			return ret;
>  		}
> -		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
> +		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
> +		if (ret < 0) {
>  			RTE_LOG(ERR, PMD,
>  				"%s: Couldn't add MAC redirection rule\n",
>  				dev->device->name);
> +			return ret;
> +		}
>  	}
> +
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 884f74ad0..38a7a14f7 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -68,7 +68,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
>  				struct ether_addr *mac_addr,
>  				uint32_t index, uint32_t vmdq);
>  static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
> -static void virtio_mac_addr_set(struct rte_eth_dev *dev,
> +static int virtio_mac_addr_set(struct rte_eth_dev *dev,
>  				struct ether_addr *mac_addr);
>
>  static int virtio_intr_enable(struct rte_eth_dev *dev);
> @@ -1097,7 +1097,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
>  	virtio_mac_table_set(hw, uc, mc);
>  }
>
> -static void
> +static int
>  virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct virtio_hw *hw = dev->data->dev_private;
> @@ -1113,9 +1113,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
>
>  		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
> -		virtio_send_command(hw->cvq, &ctrl, &len, 1);
> -	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
> -		virtio_set_hwaddr(hw);
> +		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
> +	}
> +
> +	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
> +		return -ENOTSUP;
> +
> +	virtio_set_hwaddr(hw);
> +	return 0;
>  }
>
>  static int
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> index 4e68aae6b..13ee8f250 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
> @@ -73,7 +73,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
>  static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
>  				       uint16_t vid, int on);
>  static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
> -static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
> +static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
>  				 struct ether_addr *mac_addr);
>  static void vmxnet3_interrupt_handler(void *param);
>
> @@ -1117,13 +1117,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
>  	return NULL;
>  }
>
> -static void
> +static int
>  vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct vmxnet3_hw *hw = dev->data->dev_private;
>
>  	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
>  	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
> +	return 0;
>  }
>
>  /* return 0 means link status changed, -1 means not changed */
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 0590f0c10..6a7330d92 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -3003,6 +3003,7 @@ int
>  rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
>  {
>  	struct rte_eth_dev *dev;
> +	int ret;
>
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>
> @@ -3012,11 +3013,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
>  	dev = &rte_eth_devices[port_id];
>  	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
>
> +	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
> +	if (ret < 0)
> +		return ret;
> +
>  	/* Update default address in NIC data structure */
>  	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
>
> -	(*dev->dev_ops->mac_addr_set)(dev, addr);
> -
>  	return 0;
>  }
>
> diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
> index e5681e466..55eb2b09e 100644
> --- a/lib/librte_ether/rte_ethdev_core.h
> +++ b/lib/librte_ether/rte_ethdev_core.h
> @@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
>  				  uint32_t vmdq);
>  /**< @internal Set a MAC address into Receive Address Address Register */
>
> -typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
> +typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
>  				  struct ether_addr *mac_addr);
>  /**< @internal Set a MAC address into Receive Address Address Register */
>
> diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
> index 2f5b31dba..69b4ba034 100644
> --- a/test/test/virtual_pmd.c
> +++ b/test/test/virtual_pmd.c
> @@ -216,10 +216,11 @@ static void
>  virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
>  {}
>
> -static void
> +static int
>  virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
>  			       __rte_unused struct ether_addr *addr)
>  {
> +	return 0;
>  }
>
>  static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
> --
> 2.11.0
>

--
- Tomasz Duszyński

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
  2018-03-05 10:29 ` Adrien Mazarguil
  2018-03-06  9:37 ` Tomasz Duszynski
@ 2018-03-16 15:41 ` Andrew Rybchenko
  2018-03-26 18:39 ` Ferruh Yigit
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
  4 siblings, 0 replies; 21+ messages in thread
From: Andrew Rybchenko @ 2018-03-16 15:41 UTC (permalink / raw)
  To: Olivier Matz, dev; +Cc: Thomas Monjalon, Ferruh Yigit, Ivan Malov

Hi Olivier,

On 02/27/2018 06:11 PM, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
>
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
>
> The patch also updates all the PMDs accordingly.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>
> Hi,
>
> This patch is the following of the discussion we had in this thread:
> https://dpdk.org/dev/patchwork/patch/32284/
>
> I did my best to keep the consistency inside the PMDs. The behavior
> of eth_mac_addr_set() is inspired from other fonctions in the same
> PMD, usually eth_mac_addr_add(). For instance:
> - dpaa and dpaa2 return 0 on error.
> - some PMDs (bnxt, mlx5, ...?) do not return a -errno code (-1 or
>    positive values).
> - some PMDs (avf, tap) check if the address is the same and return 0
>    in that case. This could go in generic code?
>
> I tried to use the following errors when relevant:
> - -EPERM when a VF is not allowed to do a change
> - -ENOTSUP if the function is not supported
> - -EIO if this is an unknown error from lower layer (hw or sdk)
> - -EINVAL for other unknown errors
>
> Please, PMD maintainers, feel free to comment if you ahve specific
> needs for your driver.
>
> Thanks
> Olivier
>
>
>   doc/guides/rel_notes/deprecation.rst    |  8 --------
>   drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>   drivers/net/avf/avf_ethdev.c            | 12 ++++++++----
>   drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>   drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>   drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>   drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>   drivers/net/e1000/igb_ethdev.c          | 12 +++++++-----
>   drivers/net/failsafe/failsafe_ops.c     | 16 +++++++++++++---
>   drivers/net/i40e/i40e_ethdev.c          | 24 ++++++++++++++---------
>   drivers/net/i40e/i40e_ethdev_vf.c       | 12 +++++++-----
>   drivers/net/ixgbe/ixgbe_ethdev.c        | 13 ++++++++-----
>   drivers/net/mlx4/mlx4.h                 |  2 +-
>   drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>   drivers/net/mlx5/mlx5.h                 |  2 +-
>   drivers/net/mlx5/mlx5_mac.c             |  7 +++++--
>   drivers/net/mrvl/mrvl_ethdev.c          |  7 ++++++-
>   drivers/net/null/rte_eth_null.c         |  3 ++-
>   drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>   drivers/net/qede/qede_ethdev.c          |  7 +++----
>   drivers/net/sfc/sfc_ethdev.c            | 14 +++++---------
>   drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>   drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++------------
>   drivers/net/virtio/virtio_ethdev.c      | 15 ++++++++++-----
>   drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>   lib/librte_ether/rte_ethdev.c           |  7 +++++--
>   lib/librte_ether/rte_ethdev_core.h      |  2 +-
>   test/test/virtual_pmd.c                 |  3 ++-
>   28 files changed, 159 insertions(+), 97 deletions(-)

<snip>

> diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
> index 89a452907..b76d4bb2c 100644
> --- a/drivers/net/sfc/sfc_ethdev.c
> +++ b/drivers/net/sfc/sfc_ethdev.c
> @@ -920,7 +920,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
>   	SFC_ASSERT(rc > 0);
>   	return -rc;
>   }
> -static void
> +static int
>   sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>   {
>   	struct sfc_adapter *sa = dev->data->dev_private;
> @@ -939,13 +939,14 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>   	if (port->isolated) {
>   		sfc_err(sa, "isolated mode is active on the port");
>   		sfc_err(sa, "will not set MAC address");
> +		rc = ENOTSUP;
>   		goto unlock;
>   	}
>   
>   	if (sa->state != SFC_ADAPTER_STARTED) {
>   		sfc_info(sa, "the port is not started");
>   		sfc_info(sa, "the new MAC address will be set on port start");
> -
> +		rc = EINVAL;
>   		goto unlock;
>   	}
>   
> @@ -982,14 +983,9 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>   	}
>   
>   unlock:
> -	/*
> -	 * In the case of failure sa->port->default_mac_addr does not
> -	 * need rollback since no error code is returned, and the upper
> -	 * API will anyway update the external MAC address storage.
> -	 * To be consistent with that new value it is better to keep
> -	 * the device private value the same.
> -	 */
>   	sfc_adapter_unlock(sa);
> +	SFC_ASSERT(rc >= 0);
> +	return -rc;
>   }
>   
>   

It is a bit more complicated for sfc. Please, find the patch from Ivan 
below:
  - it is not an error if isolated mode - we just need to save a new 
value locally
  - it requires careful rollback in the case of failure

===

diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 89a4529..f5670a9 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -920,13 +920,14 @@
         SFC_ASSERT(rc > 0);
         return -rc;
  }
-static void
+static int
  sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
  {
         struct sfc_adapter *sa = dev->data->dev_private;
         const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
         struct sfc_port *port = &sa->port;
-       int rc;
+       struct ether_addr *old_addr = &dev->data->mac_addrs[0];
+       int rc = 0;

         sfc_adapter_lock(sa);

@@ -936,9 +937,16 @@
          */
         ether_addr_copy(mac_addr, &port->default_mac_addr);

+       /*
+        * Neither of the two following checks can return
+        * an error. The new MAC address is preserved in
+        * the device private data and can be activated
+        * on the next port start if the user prevents
+        * isolated mode from being enabled.
+        */
         if (port->isolated) {
-               sfc_err(sa, "isolated mode is active on the port");
-               sfc_err(sa, "will not set MAC address");
+               sfc_warn(sa, "isolated mode is active on the port");
+               sfc_warn(sa, "will not set MAC address");
                 goto unlock;
         }

@@ -962,8 +970,13 @@
                  * we also need to update unicast filters
                  */
                 rc = sfc_set_rx_mode(sa);
-               if (rc != 0)
+               if (rc != 0) {
                         sfc_err(sa, "cannot set filter (rc = %u)", rc);
+
+                       /* Rollback the old address */
+                       (void)efx_mac_addr_set(sa->nic, 
old_addr->addr_bytes);
+                       (void)sfc_set_rx_mode(sa);
+               }
         } else {
                 sfc_warn(sa, "cannot set MAC address with filters 
installed");
                 sfc_warn(sa, "adapter will be restarted to pick the new 
MAC");
@@ -982,14 +995,13 @@
         }

  unlock:
-       /*
-        * In the case of failure sa->port->default_mac_addr does not
-        * need rollback since no error code is returned, and the upper
-        * API will anyway update the external MAC address storage.
-        * To be consistent with that new value it is better to keep
-        * the device private value the same.
-        */
+       if (rc != 0)
+               ether_addr_copy(old_addr, &port->default_mac_addr);
+
         sfc_adapter_unlock(sa);
+
+       SFC_ASSERT(rc >= 0);
+       return -rc;
  }


===

<snip>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
                   ` (2 preceding siblings ...)
  2018-03-16 15:41 ` Andrew Rybchenko
@ 2018-03-26 18:39 ` Ferruh Yigit
  2018-03-28  8:24   ` Olivier Matz
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
  4 siblings, 1 reply; 21+ messages in thread
From: Ferruh Yigit @ 2018-03-26 18:39 UTC (permalink / raw)
  To: Olivier Matz, dev; +Cc: Thomas Monjalon

On 2/27/2018 3:11 PM, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
> 
> Hi,
> 
> This patch is the following of the discussion we had in this thread:
> https://dpdk.org/dev/patchwork/patch/32284/
> 
> I did my best to keep the consistency inside the PMDs. The behavior
> of eth_mac_addr_set() is inspired from other fonctions in the same
> PMD, usually eth_mac_addr_add(). For instance:
> - dpaa and dpaa2 return 0 on error.
> - some PMDs (bnxt, mlx5, ...?) do not return a -errno code (-1 or
>   positive values).
> - some PMDs (avf, tap) check if the address is the same and return 0
>   in that case. This could go in generic code?
> 
> I tried to use the following errors when relevant:
> - -EPERM when a VF is not allowed to do a change
> - -ENOTSUP if the function is not supported
> - -EIO if this is an unknown error from lower layer (hw or sdk)
> - -EINVAL for other unknown errors
> 
> Please, PMD maintainers, feel free to comment if you ahve specific
> needs for your driver.
> 
> Thanks
> Olivier
> 
> 
>  doc/guides/rel_notes/deprecation.rst    |  8 --------
>  drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>  drivers/net/avf/avf_ethdev.c            | 12 ++++++++----
>  drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>  drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>  drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>  drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>  drivers/net/e1000/igb_ethdev.c          | 12 +++++++-----
>  drivers/net/failsafe/failsafe_ops.c     | 16 +++++++++++++---
>  drivers/net/i40e/i40e_ethdev.c          | 24 ++++++++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c       | 12 +++++++-----
>  drivers/net/ixgbe/ixgbe_ethdev.c        | 13 ++++++++-----
>  drivers/net/mlx4/mlx4.h                 |  2 +-
>  drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>  drivers/net/mlx5/mlx5.h                 |  2 +-
>  drivers/net/mlx5/mlx5_mac.c             |  7 +++++--
>  drivers/net/mrvl/mrvl_ethdev.c          |  7 ++++++-
>  drivers/net/null/rte_eth_null.c         |  3 ++-
>  drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>  drivers/net/qede/qede_ethdev.c          |  7 +++----
>  drivers/net/sfc/sfc_ethdev.c            | 14 +++++---------
>  drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>  drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++------------
>  drivers/net/virtio/virtio_ethdev.c      | 15 ++++++++++-----
>  drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>  lib/librte_ether/rte_ethdev.c           |  7 +++++--
>  lib/librte_ether/rte_ethdev_core.h      |  2 +-
>  test/test/virtual_pmd.c                 |  3 ++-
>  28 files changed, 159 insertions(+), 97 deletions(-)

ethdev part looks good to me.
Are you planning to have another version for mrvl and sfc comments?

PMD maintainers, please check and provide feedback for your PMD, otherwise the
patch will go in as it is.

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-03-26 18:39 ` Ferruh Yigit
@ 2018-03-28  8:24   ` Olivier Matz
  0 siblings, 0 replies; 21+ messages in thread
From: Olivier Matz @ 2018-03-28  8:24 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Thomas Monjalon

Hi Ferruh,

On Mon, Mar 26, 2018 at 07:39:00PM +0100, Ferruh Yigit wrote:
> On 2/27/2018 3:11 PM, Olivier Matz wrote:
> > Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> > return code is added to notify the caller (librte_ether) if an error
> > occurred in the PMD.
> > 
> > The new default MAC address is now copied in dev->data->mac_addrs[0]
> > only if the operation is successful.
> > 
> > The patch also updates all the PMDs accordingly.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

[...]

> ethdev part looks good to me.
> Are you planning to have another version for mrvl and sfc comments?
> 
> PMD maintainers, please check and provide feedback for your PMD, otherwise the
> patch will go in as it is.

Yes, I'll send a new version adressing the comments as soon as possible.

Thanks,
Olivier

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
                   ` (3 preceding siblings ...)
  2018-03-26 18:39 ` Ferruh Yigit
@ 2018-04-03 12:41 ` Olivier Matz
  2018-04-03 13:02   ` Andrew Rybchenko
                     ` (5 more replies)
  4 siblings, 6 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-03 12:41 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Adrien Mazarguil,
	Tomasz Duszynski, Andrew Rybchenko, Ivan Malov, Ivan Malov

Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
return code is added to notify the caller (librte_ether) if an error
occurred in the PMD.

The new default MAC address is now copied in dev->data->mac_addrs[0]
only if the operation is successful.

The patch also updates all the PMDs accordingly.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---

v2:
* add same change for net/cxgbe
* mrvl was renamed as mvpp2
* mvpp2: return success if no ppio as suggested by Tomasz
* mlx5: update comment as suggested by Adrien
* sfc: replace by Ivan's patch

 doc/guides/rel_notes/deprecation.rst    |  8 --------
 drivers/net/ark/ark_ethdev.c            |  9 ++++++---
 drivers/net/avf/avf_ethdev.c            | 12 +++++++----
 drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
 drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
 drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
 drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
 drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
 drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
 drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
 drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
 drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
 drivers/net/mlx4/mlx4.h                 |  2 +-
 drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
 drivers/net/mlx5/mlx5.h                 |  2 +-
 drivers/net/mlx5/mlx5_mac.c             |  7 ++++++-
 drivers/net/mvpp2/mrvl_ethdev.c         | 15 ++++++++++----
 drivers/net/null/rte_eth_null.c         |  3 ++-
 drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
 drivers/net/qede/qede_ethdev.c          |  7 +++----
 drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
 drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
 drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
 drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
 lib/librte_ether/rte_ethdev.c           |  7 +++++--
 lib/librte_ether/rte_ethdev_core.h      |  2 +-
 test/test/virtual_pmd.c                 |  3 ++-
 30 files changed, 188 insertions(+), 105 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0c696f743..40448961a 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -134,14 +134,6 @@ Deprecation Notices
   between the VF representor and the VF or the parent PF. Those new fields
   are to be included in ``rte_eth_dev_info`` struct.
 
-* ethdev: The prototype and the behavior of
-  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
-  will be added to notify the caller if an error occurred in the PMD. In
-  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
-  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
-  successful. This modification will only impact the PMDs, not the
-  applications.
-
 * i40e: The default flexible payload configuration which extracts the first 16
   bytes of the payload for RSS will be deprecated starting from 18.02. If
   required the previous behavior can be configured using existing flow
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ff87c20e2..3fc40cd74 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
 				  struct rte_eth_stats *stats);
 static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
-static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
+static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
 			       struct ether_addr *mac_addr,
@@ -887,16 +887,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
 			      ark->user_data[dev->data->port_id]);
 }
 
-static void
+static int
 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
 	struct ark_adapter *ark =
 		(struct ark_adapter *)dev->data->dev_private;
 
-	if (ark->user_ext.mac_addr_set)
+	if (ark->user_ext.mac_addr_set) {
 		ark->user_ext.mac_addr_set(dev, mac_addr,
 			   ark->user_data[dev->data->port_id]);
+		return 0;
+	}
+	return -ENOTSUP;
 }
 
 static int
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index 4442c3cd8..516da5554 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				     struct rte_eth_rss_conf *rss_conf);
 static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
 					uint16_t queue_id);
@@ -926,7 +926,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
@@ -940,11 +940,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
 	if (is_same_ether_addr(mac_addr, old_addr))
-		return;
+		return 0;
 
 	/* If the MAC address is configured by host, skip the setting */
 	if (is_valid_assigned_ether_addr(perm_addr))
-		return;
+		return -EPERM;
 
 	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
 	if (ret)
@@ -968,7 +968,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			    mac_addr->addr_bytes[4],
 			    mac_addr->addr_bytes[5]);
 
+	if (ret)
+		return -EIO;
+
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 0b2165326..fb41cbb79 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1398,7 +1398,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 	return 0;
 }
 
-static void
+static int
 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
@@ -1408,7 +1408,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 	int rc;
 
 	if (BNXT_VF(bp))
-		return;
+		return -EPERM;
 
 	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
 
@@ -1418,7 +1418,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			continue;
 		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
 		if (rc)
-			break;
+			return rc;
 		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
 		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
@@ -1427,10 +1427,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
-			break;
+			return rc;
 		filter->mac_index = 0;
 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index b59ba9f7c..7e75ebe36 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2859,11 +2859,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
-	if (mac_address_set(dev, addr))
+	if (mac_address_set(dev, addr)) {
 		RTE_BOND_LOG(ERR, "Failed to update MAC address");
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct eth_dev_ops default_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index feae01d6a..65e9ea42c 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1003,7 +1003,7 @@ static int cxgbe_get_regs(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -1014,9 +1014,10 @@ void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 	if (ret < 0) {
 		dev_err(adapter, "failed to set mac addr; err = %d\n",
 			ret);
-		return;
+		return ret;
 	}
 	pi->xact_addr_filt = ret;
+	return 0;
 }
 
 static const struct eth_dev_ops cxgbe_eth_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 0c1c17071..2bba97423 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -16,7 +16,7 @@ void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 void 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);
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
 int cxgbe_dev_configure(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx,
 			     uint16_t nb_desc, unsigned int socket_id,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index db493648a..2e4cb8267 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 	fman_if_clear_mac_addr(dpaa_intf->fif, index);
 }
 
-static void
+static int
 dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
 	if (ret)
 		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+
+	return 0;
 }
 
 static struct eth_dev_ops dpaa_devops = {
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 281483dfd..07d45a11e 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1019,7 +1019,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
 			"error: Removing the MAC ADDR failed: err = %d", ret);
 }
 
-static void
+static int
 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -1031,7 +1031,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -EINVAL;
 	}
 
 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
@@ -1040,6 +1040,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 	if (ret)
 		DPAA2_PMD_ERR(
 			"error: Setting the MAC ADDR failed %d", ret);
+
+	return 0;
 }
 
 static
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index d7eef9a6c..17c0a42f5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -145,7 +145,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
 			   struct ether_addr *mac_addr,
 			   uint32_t index, uint32_t pool);
 static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 
 static void igbvf_intr_disable(struct e1000_hw *hw);
@@ -170,7 +170,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
-static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
+static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 static int igbvf_get_reg_length(struct rte_eth_dev *dev);
 static int igbvf_get_regs(struct rte_eth_dev *dev,
@@ -3085,13 +3085,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *addr)
 {
 	eth_igb_rar_clear(dev, 0);
-
 	eth_igb_rar_set(dev, (void *)addr, 0, 0);
+
+	return 0;
 }
 /*
  * Virtual Function operations
@@ -3443,7 +3444,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
+static int
 igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct e1000_hw *hw =
@@ -3451,6 +3452,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 	/* index is not used by rar_set() */
 	hw->mac.ops.rar_set(hw, (void *)addr, 0);
+	return 0;
 }
 
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 057e435cf..8ca69abe4 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -997,16 +997,27 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
-	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
-		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+		ret = fs_err(sdev, ret);
+		if (ret) {
+			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %d with error %d",
+				i, ret);
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d0bf4e349..5166fc14d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
 static int i40e_get_eeprom(struct rte_eth_dev *dev,
 			   struct rte_dev_eeprom_info *eeprom);
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -11291,8 +11291,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-				      struct ether_addr *mac_addr)
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+				     struct ether_addr *mac_addr)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11303,7 +11303,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
@@ -11313,25 +11313,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (f == NULL) {
 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
-		return;
+		return -EIO;
 	}
 
 	mac_filter = f->mac_info;
 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
 
-	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
-				  mac_addr->addr_bytes, NULL);
+	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+					mac_addr->addr_bytes, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to change mac");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 750d84972..663d85b0e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 					struct rte_eth_rss_conf *rss_conf);
 static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 					struct ether_addr *mac_addr);
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
@@ -2661,7 +2661,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 			    struct ether_addr *mac_addr)
 {
@@ -2670,17 +2670,19 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-		return;
+		return -EPERM;
 
 	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
-	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
+		return -EIO;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4df5c75c3..f0802a64f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -227,7 +227,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			 uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -285,7 +285,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
 					     struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
 			struct rte_eth_syn_filter *filter);
@@ -4804,14 +4804,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
 	ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
 	ixgbe_remove_rar(dev, 0);
-
 	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+	return 0;
 }
 
 static bool
@@ -5934,12 +5935,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
 	}
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 19c8a223d..c107794ce 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 		      uint32_t index, uint32_t vmdq);
-void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 void mlx4_stats_reset(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index fbeef16c8..6145c8457 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -533,11 +533,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index faacfd9d6..738709854 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -195,7 +195,7 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
 		      uint32_t index, uint32_t vmdq);
-void mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 
 /* mlx5_rss.c */
 
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index 01c7ba17a..3bf76e38c 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	int ret;
@@ -137,4 +140,6 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot set mac address: %s",
 			dev->data->port_id, strerror(rte_errno));
+
+	return ret;
 }
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 6ab515ca9..87748f789 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -987,7 +987,7 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 		return;
 
 	if (priv->isolated)
-		return;
+		return -ENOTSUP;
 
 	ret = pp2_ppio_remove_mac_addr(priv->ppio,
 				       dev->data->mac_addrs[index].addr_bytes);
@@ -996,6 +996,8 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 				  &dev->data->mac_addrs[index]);
 		RTE_LOG(ERR, PMD, "Failed to remove mac %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
@@ -1061,18 +1063,21 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
-static void
+static int
 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	if (priv->isolated)
-		return;
+		return -ENOTSUP;
 
 	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
 	if (ret) {
@@ -1080,6 +1085,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ether_format_addr(buf, sizeof(buf), mac_addr);
 		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 73fe8b04a..74dde9521 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -459,10 +459,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 		    __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 90dd249a6..878dc1446 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -580,7 +580,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
 	octeontx_port_stats_clr(nic);
 }
 
-static void
+static int
 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct ether_addr *addr)
 {
@@ -591,6 +591,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 	if (ret != 0)
 		octeontx_log_err("failed to set MAC address on port %d",
 				nic->port_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index a4e9e753e..02db65e2f 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1041,7 +1041,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	qede_mac_int_ops(eth_dev, &ucast, false);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1050,12 +1050,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
 					       mac_addr->addr_bytes)) {
 		DP_ERR(edev, "Setting MAC address is not allowed\n");
-		ether_addr_copy(&qdev->primary_mac,
-				&eth_dev->data->mac_addrs[0]);
-		return;
+		return -EPERM;
 	}
 
 	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+	return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2af898e08..30cb22e8e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -915,13 +915,14 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	SFC_ASSERT(rc > 0);
 	return -rc;
 }
-static void
+static int
 sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_port *port = &sa->port;
-	int rc;
+	struct ether_addr *old_addr = &dev->data->mac_addrs[0];
+	int rc = 0;
 
 	sfc_adapter_lock(sa);
 
@@ -931,9 +932,16 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	 */
 	ether_addr_copy(mac_addr, &port->default_mac_addr);
 
+	/*
+	 * Neither of the two following checks can return
+	 * an error. The new MAC address is preserved in
+	 * the device private data and can be activated
+	 * on the next port start if the user prevents
+	 * isolated mode from being enabled.
+	 */
 	if (port->isolated) {
-		sfc_err(sa, "isolated mode is active on the port");
-		sfc_err(sa, "will not set MAC address");
+		sfc_warn(sa, "isolated mode is active on the port");
+		sfc_warn(sa, "will not set MAC address");
 		goto unlock;
 	}
 
@@ -957,8 +965,12 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		 * we also need to update unicast filters
 		 */
 		rc = sfc_set_rx_mode(sa);
-		if (rc != 0)
+		if (rc != 0) {
 			sfc_err(sa, "cannot set filter (rc = %u)", rc);
+			/* Rollback the old address */
+			(void)efx_mac_addr_set(sa->nic, old_addr->addr_bytes);
+			(void)sfc_set_rx_mode(sa);
+		}
 	} else {
 		sfc_warn(sa, "cannot set MAC address with filters installed");
 		sfc_warn(sa, "adapter will be restarted to pick the new MAC");
@@ -977,14 +989,13 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	}
 
 unlock:
-	/*
-	 * In the case of failure sa->port->default_mac_addr does not
-	 * need rollback since no error code is returned, and the upper
-	 * API will anyway update the external MAC address storage.
-	 * To be consistent with that new value it is better to keep
-	 * the device private value the same.
-	 */
+	if (rc != 0)
+		ether_addr_copy(old_addr, &port->default_mac_addr);
+
 	sfc_adapter_unlock(sa);
+
+	SFC_ASSERT(rc >= 0);
+	return -rc;
 }
 
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 1d02aee6f..28558ff78 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1312,10 +1312,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 		struct ether_addr *mac_addr __rte_unused)
 {
+	return 0;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 3e4f7a8e8..e921c2627 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -933,48 +933,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
 
-static void
+static int
 tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	enum ioctl_mode mode = LOCAL_ONLY;
 	struct ifreq ifr;
+	int ret;
 
 	if (is_zero_ether_addr(mac_addr)) {
 		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
 			dev->device->name);
-		return;
+		return -EINVAL;
 	}
 	/* Check the actual current MAC address on the tap netdevice */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
+	if (ret < 0)
+		return ret;
 	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
-		return;
+		return 0;
 	/* Check the current MAC address on the remote */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
+	if (ret < 0)
+		return ret;
 	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
 		mode = LOCAL_AND_REMOTE;
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
+	if (ret < 0)
+		return ret;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 	if (pmd->remote_if_index && !pmd->flow_isolate) {
 		/* Replace MAC redirection rule after a MAC change */
-		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't delete MAC redirection rule\n",
 				dev->device->name);
-			return;
+			return ret;
 		}
-		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't add MAC redirection rule\n",
 				dev->device->name);
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 2ef213d1a..f663e0bbe 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -67,7 +67,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -1056,7 +1056,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 	virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1072,9 +1072,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
 		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-		virtio_send_command(hw->cvq, &ctrl, &len, 1);
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-		virtio_set_hwaddr(hw);
+		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	}
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+		return -ENOTSUP;
+
+	virtio_set_hwaddr(hw);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 426008722..5cefa6664 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -72,7 +72,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
+static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
 				 struct ether_addr *mac_addr);
 static void vmxnet3_interrupt_handler(void *param);
 
@@ -1078,13 +1078,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+static int
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
+	return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 2c74f7e04..2aefe7ebf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3005,6 +3005,7 @@ int
 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3014,11 +3015,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
+	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+	if (ret < 0)
+		return ret;
+
 	/* Update default address in NIC data structure */
 	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
-	(*dev->dev_ops->mac_addr_set)(dev, addr);
-
 	return 0;
 }
 
diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
index e5681e466..55eb2b09e 100644
--- a/lib/librte_ether/rte_ethdev_core.h
+++ b/lib/librte_ether/rte_ethdev_core.h
@@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
 				  uint32_t vmdq);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
-typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 2f5b31dba..69b4ba034 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -216,10 +216,11 @@ static void
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
 {}
 
-static void
+static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 			       __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
-- 
2.11.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
@ 2018-04-03 13:02   ` Andrew Rybchenko
  2018-04-03 14:57   ` Adrien Mazarguil
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: Andrew Rybchenko @ 2018-04-03 13:02 UTC (permalink / raw)
  To: Olivier Matz, dev
  Cc: Thomas Monjalon, Ferruh Yigit, Adrien Mazarguil,
	Tomasz Duszynski, Ivan Malov

On 04/03/2018 03:41 PM, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
>
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
>
> The patch also updates all the PMDs accordingly.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---
>
> v2:
> * add same change for net/cxgbe
> * mrvl was renamed as mvpp2
> * mvpp2: return success if no ppio as suggested by Tomasz
> * mlx5: update comment as suggested by Adrien
> * sfc: replace by Ivan's patch
>
>   doc/guides/rel_notes/deprecation.rst    |  8 --------
>   drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>   drivers/net/avf/avf_ethdev.c            | 12 +++++++----
>   drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>   drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>   drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
>   drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
>   drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>   drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>   drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
>   drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
>   drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
>   drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
>   drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
>   drivers/net/mlx4/mlx4.h                 |  2 +-
>   drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>   drivers/net/mlx5/mlx5.h                 |  2 +-
>   drivers/net/mlx5/mlx5_mac.c             |  7 ++++++-
>   drivers/net/mvpp2/mrvl_ethdev.c         | 15 ++++++++++----
>   drivers/net/null/rte_eth_null.c         |  3 ++-
>   drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>   drivers/net/qede/qede_ethdev.c          |  7 +++----
>   drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
>   drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>   drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
>   drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
>   drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>   lib/librte_ether/rte_ethdev.c           |  7 +++++--
>   lib/librte_ether/rte_ethdev_core.h      |  2 +-
>   test/test/virtual_pmd.c                 |  3 ++-
>   30 files changed, 188 insertions(+), 105 deletions(-)

sfc part
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
  2018-04-03 13:02   ` Andrew Rybchenko
@ 2018-04-03 14:57   ` Adrien Mazarguil
  2018-04-03 16:26     ` Olivier Matz
  2018-04-03 16:19   ` Ferruh Yigit
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 21+ messages in thread
From: Adrien Mazarguil @ 2018-04-03 14:57 UTC (permalink / raw)
  To: Olivier Matz
  Cc: dev, Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Ivan Malov

On Tue, Apr 03, 2018 at 02:41:03PM +0200, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---
> 
> v2:
> * add same change for net/cxgbe
> * mrvl was renamed as mvpp2
> * mvpp2: return success if no ppio as suggested by Tomasz
> * mlx5: update comment as suggested by Adrien
> * sfc: replace by Ivan's patch

Just one remaining nit regarding mlx5, please see below. Otherwise for both
mlx4 and mlx5:

Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

<snip>
> diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> index 01c7ba17a..3bf76e38c 100644
> --- a/drivers/net/mlx5/mlx5_mac.c
> +++ b/drivers/net/mlx5/mlx5_mac.c
> @@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, a negative errno value otherwise and rte_errno is set.
>   */
> -void
> +int
>  mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	int ret;
> @@ -137,4 +140,6 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  	if (ret)
>  		DRV_LOG(ERR, "port %u cannot set mac address: %s",
>  			dev->data->port_id, strerror(rte_errno));
> +

This empty line is unnecessary (this follows the work done to remove
non-mandatory empty lines sprinkled everywhere in these PMDs for coding
style consistency).

> +	return ret;
<snip>

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
  2018-04-03 13:02   ` Andrew Rybchenko
  2018-04-03 14:57   ` Adrien Mazarguil
@ 2018-04-03 16:19   ` Ferruh Yigit
  2018-04-03 16:25     ` Olivier Matz
  2018-04-04  8:19   ` Shreyansh Jain
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 21+ messages in thread
From: Ferruh Yigit @ 2018-04-03 16:19 UTC (permalink / raw)
  To: Olivier Matz, dev
  Cc: Thomas Monjalon, Adrien Mazarguil, Tomasz Duszynski,
	Andrew Rybchenko, Ivan Malov

On 4/3/2018 1:41 PM, Olivier Matz wrote:
> diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
> index 6ab515ca9..87748f789 100644
> --- a/drivers/net/mvpp2/mrvl_ethdev.c
> +++ b/drivers/net/mvpp2/mrvl_ethdev.c
> @@ -987,7 +987,7 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
>  		return;
>  
>  	if (priv->isolated)
> -		return;
> +		return -ENOTSUP;
>  
>  	ret = pp2_ppio_remove_mac_addr(priv->ppio,
>  				       dev->data->mac_addrs[index].addr_bytes);
> @@ -996,6 +996,8 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
>  				  &dev->data->mac_addrs[index]);
>  		RTE_LOG(ERR, PMD, "Failed to remove mac %s\n", buf);
>  	}
> +
> +	return ret;
>  }

I guess mrvl_mac_addr_remove() updated by mistake?

>  
>  /**
> @@ -1061,18 +1063,21 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, negative error value otherwise.
>   */
> -static void
> +static int
>  mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	struct mrvl_priv *priv = dev->data->dev_private;
>  	int ret;
>  
>  	if (!priv->ppio)
> -		return;
> +		return 0;
>  
>  	if (priv->isolated)
> -		return;
> +		return -ENOTSUP;
>  
>  	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
>  	if (ret) {
> @@ -1080,6 +1085,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  		ether_format_addr(buf, sizeof(buf), mac_addr);
>  		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
>  	}
> +
> +	return ret;
>  }
>  
>  /**

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 16:19   ` Ferruh Yigit
@ 2018-04-03 16:25     ` Olivier Matz
  0 siblings, 0 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-03 16:25 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Thomas Monjalon, Adrien Mazarguil, Tomasz Duszynski,
	Andrew Rybchenko, Ivan Malov

On Tue, Apr 03, 2018 at 05:19:06PM +0100, Ferruh Yigit wrote:
> On 4/3/2018 1:41 PM, Olivier Matz wrote:
> > diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
> > index 6ab515ca9..87748f789 100644
> > --- a/drivers/net/mvpp2/mrvl_ethdev.c
> > +++ b/drivers/net/mvpp2/mrvl_ethdev.c
> > @@ -987,7 +987,7 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
> >  		return;
> >  
> >  	if (priv->isolated)
> > -		return;
> > +		return -ENOTSUP;
> >  
> >  	ret = pp2_ppio_remove_mac_addr(priv->ppio,
> >  				       dev->data->mac_addrs[index].addr_bytes);
> > @@ -996,6 +996,8 @@ mrvl_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
> >  				  &dev->data->mac_addrs[index]);
> >  		RTE_LOG(ERR, PMD, "Failed to remove mac %s\n", buf);
> >  	}
> > +
> > +	return ret;
> >  }
> 
> I guess mrvl_mac_addr_remove() updated by mistake?

erf... that explains why I had to do the modification twice :D
Thanks for spotting it, will send an update.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 14:57   ` Adrien Mazarguil
@ 2018-04-03 16:26     ` Olivier Matz
  0 siblings, 0 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-03 16:26 UTC (permalink / raw)
  To: Adrien Mazarguil
  Cc: dev, Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Ivan Malov

On Tue, Apr 03, 2018 at 04:57:24PM +0200, Adrien Mazarguil wrote:
> On Tue, Apr 03, 2018 at 02:41:03PM +0200, Olivier Matz wrote:
> > Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> > return code is added to notify the caller (librte_ether) if an error
> > occurred in the PMD.
> > 
> > The new default MAC address is now copied in dev->data->mac_addrs[0]
> > only if the operation is successful.
> > 
> > The patch also updates all the PMDs accordingly.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> > ---
> > 
> > v2:
> > * add same change for net/cxgbe
> > * mrvl was renamed as mvpp2
> > * mvpp2: return success if no ppio as suggested by Tomasz
> > * mlx5: update comment as suggested by Adrien
> > * sfc: replace by Ivan's patch
> 
> Just one remaining nit regarding mlx5, please see below. Otherwise for both
> mlx4 and mlx5:
> 
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> 
> <snip>
> > diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> > index 01c7ba17a..3bf76e38c 100644
> > --- a/drivers/net/mlx5/mlx5_mac.c
> > +++ b/drivers/net/mlx5/mlx5_mac.c
> > @@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
> >   *   Pointer to Ethernet device structure.
> >   * @param mac_addr
> >   *   MAC address to register.
> > + *
> > + * @return
> > + *   0 on success, a negative errno value otherwise and rte_errno is set.
> >   */
> > -void
> > +int
> >  mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
> >  {
> >  	int ret;
> > @@ -137,4 +140,6 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
> >  	if (ret)
> >  		DRV_LOG(ERR, "port %u cannot set mac address: %s",
> >  			dev->data->port_id, strerror(rte_errno));
> > +
> 
> This empty line is unnecessary (this follows the work done to remove
> non-mandatory empty lines sprinkled everywhere in these PMDs for coding
> style consistency).

Will fix in next version, thanks.

Olivier

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
                     ` (2 preceding siblings ...)
  2018-04-03 16:19   ` Ferruh Yigit
@ 2018-04-04  8:19   ` Shreyansh Jain
  2018-04-06 15:21   ` [dpdk-dev] [PATCH] " Olivier Matz
  2018-04-06 15:34   ` [dpdk-dev] [PATCH v3] " Olivier Matz
  5 siblings, 0 replies; 21+ messages in thread
From: Shreyansh Jain @ 2018-04-04  8:19 UTC (permalink / raw)
  To: Olivier Matz, dev
  Cc: Thomas Monjalon, Ferruh Yigit, Adrien Mazarguil,
	Tomasz Duszynski, Andrew Rybchenko, Ivan Malov, Ivan Malov

Hello Olivier,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> Sent: Tuesday, April 3, 2018 6:11 PM
> To: dev@dpdk.org
> Cc: Thomas Monjalon <thomas@monjalon.net>; Ferruh Yigit
> <ferruh.yigit@intel.com>; Adrien Mazarguil <adrien.mazarguil@6wind.com>;
> Tomasz Duszynski <tdu@semihalf.com>; Andrew Rybchenko
> <arybchenko@solarflare.com>; Ivan Malov <Ivan.Malov@oktetlabs.ru>; Ivan
> Malov <ivan.malov@oktetlabs.ru>
> Subject: [dpdk-dev] [PATCH v2] ethdev: return diagnostic when setting
> MAC address
> 
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> ---
> 
> v2:
> * add same change for net/cxgbe
> * mrvl was renamed as mvpp2
> * mvpp2: return success if no ppio as suggested by Tomasz
> * mlx5: update comment as suggested by Adrien
> * sfc: replace by Ivan's patch
> 
>  doc/guides/rel_notes/deprecation.rst    |  8 --------
>  drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>  drivers/net/avf/avf_ethdev.c            | 12 +++++++----
>  drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>  drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>  drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
>  drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
>  drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>  drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>  drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
>  drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
>  drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
>  drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
>  drivers/net/mlx4/mlx4.h                 |  2 +-
>  drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>  drivers/net/mlx5/mlx5.h                 |  2 +-
>  drivers/net/mlx5/mlx5_mac.c             |  7 ++++++-
>  drivers/net/mvpp2/mrvl_ethdev.c         | 15 ++++++++++----
>  drivers/net/null/rte_eth_null.c         |  3 ++-
>  drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>  drivers/net/qede/qede_ethdev.c          |  7 +++----
>  drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++----
> -------
>  drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>  drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----
> ------
>  drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
>  drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>  lib/librte_ether/rte_ethdev.c           |  7 +++++--
>  lib/librte_ether/rte_ethdev_core.h      |  2 +-
>  test/test/virtual_pmd.c                 |  3 ++-
>  30 files changed, 188 insertions(+), 105 deletions(-)
> 

[...]

> diff --git a/drivers/net/dpaa/dpaa_ethdev.c
> b/drivers/net/dpaa/dpaa_ethdev.c
> index db493648a..2e4cb8267 100644
> --- a/drivers/net/dpaa/dpaa_ethdev.c
> +++ b/drivers/net/dpaa/dpaa_ethdev.c
> @@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
>  	fman_if_clear_mac_addr(dpaa_intf->fif, index);
>  }
> 
> -static void
> +static int
>  dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
>  		       struct ether_addr *addr)
>  {
> @@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
>  	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
>  	if (ret)
>  		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d",
> ret);
> +
> +	return 0;

This should be 'return ret' as just above this line there is an error condition.

>  }
> 
>  static struct eth_dev_ops dpaa_devops = {
> diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c
> b/drivers/net/dpaa2/dpaa2_ethdev.c
> index 281483dfd..07d45a11e 100644
> --- a/drivers/net/dpaa2/dpaa2_ethdev.c
> +++ b/drivers/net/dpaa2/dpaa2_ethdev.c
> @@ -1019,7 +1019,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
>  			"error: Removing the MAC ADDR failed: err = %d", ret);
>  }
> 
> -static void
> +static int
>  dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
>  		       struct ether_addr *addr)
>  {
> @@ -1031,7 +1031,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
> 
>  	if (dpni == NULL) {
>  		DPAA2_PMD_ERR("dpni is NULL");
> -		return;
> +		return -EINVAL;
>  	}
> 
>  	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
> @@ -1040,6 +1040,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
>  	if (ret)
>  		DPAA2_PMD_ERR(
>  			"error: Setting the MAC ADDR failed %d", ret);
> +
> +	return 0;

Same is the case here - It should be 'return ret' as there is an error reported just above this line.

>  }
> 
>  static

[...]

For the v3 with the changes above, for dpaa/dpaa2 and generic part:

Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>


-
Shreyansh

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
                     ` (3 preceding siblings ...)
  2018-04-04  8:19   ` Shreyansh Jain
@ 2018-04-06 15:21   ` Olivier Matz
  2018-04-06 15:34     ` Olivier Matz
  2018-04-09  8:57     ` Nélio Laranjeiro
  2018-04-06 15:34   ` [dpdk-dev] [PATCH v3] " Olivier Matz
  5 siblings, 2 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-06 15:21 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Adrien Mazarguil, Shreyansh Jain, Ivan Malov

Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
return code is added to notify the caller (librte_ether) if an error
occurred in the PMD.

The new default MAC address is now copied in dev->data->mac_addrs[0]
only if the operation is successful.

The patch also updates all the PMDs accordingly.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---

v3:
* mlx5: remove empty line as suggested by Adrien
* mvpp2: remove wrong changes in mrvl_mac_addr_remove() as suggested
  by Ferruh
* dpaa/dpaa2: fix return value as suggested by Shreyansh

v2:
* add same change for net/cxgbe
* mrvl was renamed as mvpp2
* mvpp2: return success if no ppio as suggested by Tomasz
* mlx5: update comment as suggested by Adrien
* sfc: replace by Ivan's patch


 doc/guides/rel_notes/deprecation.rst    |  8 --------
 drivers/net/ark/ark_ethdev.c            |  9 ++++++---
 drivers/net/avf/avf_ethdev.c            | 12 +++++++----
 drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
 drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
 drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
 drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
 drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
 drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
 drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
 drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
 drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
 drivers/net/mlx4/mlx4.h                 |  2 +-
 drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
 drivers/net/mlx5/mlx5.h                 |  2 +-
 drivers/net/mlx5/mlx5_mac.c             |  6 +++++-
 drivers/net/mvpp2/mrvl_ethdev.c         | 11 ++++++++---
 drivers/net/null/rte_eth_null.c         |  3 ++-
 drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
 drivers/net/qede/qede_ethdev.c          |  7 +++----
 drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
 drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
 drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
 drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
 lib/librte_ether/rte_ethdev.c           |  7 +++++--
 lib/librte_ether/rte_ethdev_core.h      |  2 +-
 test/test/virtual_pmd.c                 |  3 ++-
 30 files changed, 184 insertions(+), 104 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ec70b5fa9..efef7cf6b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -131,14 +131,6 @@ Deprecation Notices
   between the VF representor and the VF or the parent PF. Those new fields
   are to be included in ``rte_eth_dev_info`` struct.
 
-* ethdev: The prototype and the behavior of
-  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
-  will be added to notify the caller if an error occurred in the PMD. In
-  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
-  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
-  successful. This modification will only impact the PMDs, not the
-  applications.
-
 * i40e: The default flexible payload configuration which extracts the first 16
   bytes of the payload for RSS will be deprecated starting from 18.02. If
   required the previous behavior can be configured using existing flow
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ff87c20e2..3fc40cd74 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
 				  struct rte_eth_stats *stats);
 static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
-static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
+static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
 			       struct ether_addr *mac_addr,
@@ -887,16 +887,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
 			      ark->user_data[dev->data->port_id]);
 }
 
-static void
+static int
 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
 	struct ark_adapter *ark =
 		(struct ark_adapter *)dev->data->dev_private;
 
-	if (ark->user_ext.mac_addr_set)
+	if (ark->user_ext.mac_addr_set) {
 		ark->user_ext.mac_addr_set(dev, mac_addr,
 			   ark->user_data[dev->data->port_id]);
+		return 0;
+	}
+	return -ENOTSUP;
 }
 
 static int
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index b59e3cf79..ab2e8107a 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				     struct rte_eth_rss_conf *rss_conf);
 static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
 					uint16_t queue_id);
@@ -926,7 +926,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
@@ -940,11 +940,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
 	if (is_same_ether_addr(mac_addr, old_addr))
-		return;
+		return 0;
 
 	/* If the MAC address is configured by host, skip the setting */
 	if (is_valid_assigned_ether_addr(perm_addr))
-		return;
+		return -EPERM;
 
 	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
 	if (ret)
@@ -968,7 +968,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			    mac_addr->addr_bytes[4],
 			    mac_addr->addr_bytes[5]);
 
+	if (ret)
+		return -EIO;
+
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7c007c8f9..5e50322f6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1370,7 +1370,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 	return 0;
 }
 
-static void
+static int
 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
@@ -1380,7 +1380,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 	int rc;
 
 	if (BNXT_VF(bp))
-		return;
+		return -EPERM;
 
 	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
 
@@ -1390,7 +1390,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			continue;
 		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
 		if (rc)
-			break;
+			return rc;
 		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
 		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
@@ -1399,10 +1399,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
-			break;
+			return rc;
 		filter->mac_index = 0;
 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 2ba1055e2..8847d20c2 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2872,11 +2872,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
-	if (mac_address_set(dev, addr))
+	if (mac_address_set(dev, addr)) {
 		RTE_BOND_LOG(ERR, "Failed to update MAC address");
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct eth_dev_ops default_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 581a1f33a..857a849e3 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1058,7 +1058,7 @@ static int cxgbe_get_regs(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -1069,9 +1069,10 @@ void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 	if (ret < 0) {
 		dev_err(adapter, "failed to set mac addr; err = %d\n",
 			ret);
-		return;
+		return ret;
 	}
 	pi->xact_addr_filt = ret;
+	return 0;
 }
 
 static const struct eth_dev_ops cxgbe_eth_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 0c1c17071..2bba97423 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -16,7 +16,7 @@ void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 void 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);
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
 int cxgbe_dev_configure(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx,
 			     uint16_t nb_desc, unsigned int socket_id,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index db493648a..367b0d2b2 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 	fman_if_clear_mac_addr(dpaa_intf->fif, index);
 }
 
-static void
+static int
 dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
 	if (ret)
 		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static struct eth_dev_ops dpaa_devops = {
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 281483dfd..852bd10eb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1019,7 +1019,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
 			"error: Removing the MAC ADDR failed: err = %d", ret);
 }
 
-static void
+static int
 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -1031,7 +1031,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -EINVAL;
 	}
 
 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
@@ -1040,6 +1040,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 	if (ret)
 		DPAA2_PMD_ERR(
 			"error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 8d4226676..b706446c5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -145,7 +145,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
 			   struct ether_addr *mac_addr,
 			   uint32_t index, uint32_t pool);
 static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 
 static void igbvf_intr_disable(struct e1000_hw *hw);
@@ -170,7 +170,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
-static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
+static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 static int igbvf_get_reg_length(struct rte_eth_dev *dev);
 static int igbvf_get_regs(struct rte_eth_dev *dev,
@@ -3089,13 +3089,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *addr)
 {
 	eth_igb_rar_clear(dev, 0);
-
 	eth_igb_rar_set(dev, (void *)addr, 0, 0);
+
+	return 0;
 }
 /*
  * Virtual Function operations
@@ -3447,7 +3448,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
+static int
 igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct e1000_hw *hw =
@@ -3455,6 +3456,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 	/* index is not used by rar_set() */
 	hw->mac.ops.rar_set(hw, (void *)addr, 0);
+	return 0;
 }
 
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 057e435cf..8ca69abe4 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -997,16 +997,27 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
-	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
-		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+		ret = fs_err(sdev, ret);
+		if (ret) {
+			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %d with error %d",
+				i, ret);
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6e06f8a2b..96c336893 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
 static int i40e_get_eeprom(struct rte_eth_dev *dev,
 			   struct rte_dev_eeprom_info *eeprom);
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -11301,8 +11301,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-				      struct ether_addr *mac_addr)
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+				     struct ether_addr *mac_addr)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11313,7 +11313,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
@@ -11323,25 +11323,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (f == NULL) {
 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
-		return;
+		return -EIO;
 	}
 
 	mac_filter = f->mac_info;
 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
 
-	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
-				  mac_addr->addr_bytes, NULL);
+	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+					mac_addr->addr_bytes, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to change mac");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 2908c87e0..65d1043d9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 					struct rte_eth_rss_conf *rss_conf);
 static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 					struct ether_addr *mac_addr);
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
@@ -2667,7 +2667,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 			    struct ether_addr *mac_addr)
 {
@@ -2676,17 +2676,19 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-		return;
+		return -EPERM;
 
 	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
-	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
+		return -EIO;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fbc048f7d..30c597e3c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -227,7 +227,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			 uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -285,7 +285,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
 					     struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
 			struct rte_eth_syn_filter *filter);
@@ -4768,14 +4768,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
 	ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
 	ixgbe_remove_rar(dev, 0);
-
 	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+	return 0;
 }
 
 static bool
@@ -5922,12 +5923,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
 	}
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 19c8a223d..c107794ce 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 		      uint32_t index, uint32_t vmdq);
-void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 void mlx4_stats_reset(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 5f731e023..c43ed8234 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -534,11 +534,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index faacfd9d6..738709854 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -195,7 +195,7 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
 		      uint32_t index, uint32_t vmdq);
-void mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 
 /* mlx5_rss.c */
 
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index 01c7ba17a..6ca1cc4a1 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	int ret;
@@ -137,4 +140,5 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot set mac address: %s",
 			dev->data->port_id, strerror(rte_errno));
+	return ret;
 }
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 6ab515ca9..d787154cc 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -1061,18 +1061,21 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
-static void
+static int
 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	if (priv->isolated)
-		return;
+		return -ENOTSUP;
 
 	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
 	if (ret) {
@@ -1080,6 +1083,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ether_format_addr(buf, sizeof(buf), mac_addr);
 		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 73fe8b04a..74dde9521 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -459,10 +459,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 		    __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 1406e4e19..ffd40a4cb 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -586,7 +586,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
 	octeontx_port_stats_clr(nic);
 }
 
-static void
+static int
 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct ether_addr *addr)
 {
@@ -597,6 +597,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 	if (ret != 0)
 		octeontx_log_err("failed to set MAC address on port %d",
 				nic->port_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index a4e9e753e..02db65e2f 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1041,7 +1041,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	qede_mac_int_ops(eth_dev, &ucast, false);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1050,12 +1050,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
 					       mac_addr->addr_bytes)) {
 		DP_ERR(edev, "Setting MAC address is not allowed\n");
-		ether_addr_copy(&qdev->primary_mac,
-				&eth_dev->data->mac_addrs[0]);
-		return;
+		return -EPERM;
 	}
 
 	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+	return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2af898e08..30cb22e8e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -915,13 +915,14 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	SFC_ASSERT(rc > 0);
 	return -rc;
 }
-static void
+static int
 sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_port *port = &sa->port;
-	int rc;
+	struct ether_addr *old_addr = &dev->data->mac_addrs[0];
+	int rc = 0;
 
 	sfc_adapter_lock(sa);
 
@@ -931,9 +932,16 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	 */
 	ether_addr_copy(mac_addr, &port->default_mac_addr);
 
+	/*
+	 * Neither of the two following checks can return
+	 * an error. The new MAC address is preserved in
+	 * the device private data and can be activated
+	 * on the next port start if the user prevents
+	 * isolated mode from being enabled.
+	 */
 	if (port->isolated) {
-		sfc_err(sa, "isolated mode is active on the port");
-		sfc_err(sa, "will not set MAC address");
+		sfc_warn(sa, "isolated mode is active on the port");
+		sfc_warn(sa, "will not set MAC address");
 		goto unlock;
 	}
 
@@ -957,8 +965,12 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		 * we also need to update unicast filters
 		 */
 		rc = sfc_set_rx_mode(sa);
-		if (rc != 0)
+		if (rc != 0) {
 			sfc_err(sa, "cannot set filter (rc = %u)", rc);
+			/* Rollback the old address */
+			(void)efx_mac_addr_set(sa->nic, old_addr->addr_bytes);
+			(void)sfc_set_rx_mode(sa);
+		}
 	} else {
 		sfc_warn(sa, "cannot set MAC address with filters installed");
 		sfc_warn(sa, "adapter will be restarted to pick the new MAC");
@@ -977,14 +989,13 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	}
 
 unlock:
-	/*
-	 * In the case of failure sa->port->default_mac_addr does not
-	 * need rollback since no error code is returned, and the upper
-	 * API will anyway update the external MAC address storage.
-	 * To be consistent with that new value it is better to keep
-	 * the device private value the same.
-	 */
+	if (rc != 0)
+		ether_addr_copy(old_addr, &port->default_mac_addr);
+
 	sfc_adapter_unlock(sa);
+
+	SFC_ASSERT(rc >= 0);
+	return -rc;
 }
 
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index fb9aac04b..02682576d 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1361,10 +1361,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 		struct ether_addr *mac_addr __rte_unused)
 {
+	return 0;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index ed6d7380e..6cd1da418 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -934,48 +934,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
 
-static void
+static int
 tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	enum ioctl_mode mode = LOCAL_ONLY;
 	struct ifreq ifr;
+	int ret;
 
 	if (is_zero_ether_addr(mac_addr)) {
 		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
 			dev->device->name);
-		return;
+		return -EINVAL;
 	}
 	/* Check the actual current MAC address on the tap netdevice */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
+	if (ret < 0)
+		return ret;
 	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
-		return;
+		return 0;
 	/* Check the current MAC address on the remote */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
+	if (ret < 0)
+		return ret;
 	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
 		mode = LOCAL_AND_REMOTE;
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
+	if (ret < 0)
+		return ret;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 	if (pmd->remote_if_index && !pmd->flow_isolate) {
 		/* Replace MAC redirection rule after a MAC change */
-		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't delete MAC redirection rule\n",
 				dev->device->name);
-			return;
+			return ret;
 		}
-		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't add MAC redirection rule\n",
 				dev->device->name);
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 11f758929..31cdfd6f5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -67,7 +67,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -1056,7 +1056,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 	virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1072,9 +1072,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
 		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-		virtio_send_command(hw->cvq, &ctrl, &len, 1);
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-		virtio_set_hwaddr(hw);
+		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	}
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+		return -ENOTSUP;
+
+	virtio_set_hwaddr(hw);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 426008722..5cefa6664 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -72,7 +72,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
+static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
 				 struct ether_addr *mac_addr);
 static void vmxnet3_interrupt_handler(void *param);
 
@@ -1078,13 +1078,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+static int
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
+	return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 2c74f7e04..2aefe7ebf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3005,6 +3005,7 @@ int
 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3014,11 +3015,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
+	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+	if (ret < 0)
+		return ret;
+
 	/* Update default address in NIC data structure */
 	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
-	(*dev->dev_ops->mac_addr_set)(dev, addr);
-
 	return 0;
 }
 
diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
index e5681e466..55eb2b09e 100644
--- a/lib/librte_ether/rte_ethdev_core.h
+++ b/lib/librte_ether/rte_ethdev_core.h
@@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
 				  uint32_t vmdq);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
-typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 2f5b31dba..69b4ba034 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -216,10 +216,11 @@ static void
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
 {}
 
-static void
+static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 			       __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
-- 
2.11.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [dpdk-dev] [PATCH v3] ethdev: return diagnostic when setting MAC address
  2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
                     ` (4 preceding siblings ...)
  2018-04-06 15:21   ` [dpdk-dev] [PATCH] " Olivier Matz
@ 2018-04-06 15:34   ` Olivier Matz
  2018-04-06 16:03     ` Ferruh Yigit
  2018-04-11 16:32     ` [dpdk-dev] [PATCH v4] " Olivier Matz
  5 siblings, 2 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-06 15:34 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Adrien Mazarguil, Shreyansh Jain, Ivan Malov

Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
return code is added to notify the caller (librte_ether) if an error
occurred in the PMD.

The new default MAC address is now copied in dev->data->mac_addrs[0]
only if the operation is successful.

The patch also updates all the PMDs accordingly.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---

v3:
* mlx5: remove empty line as suggested by Adrien
* mvpp2: remove wrong changes in mrvl_mac_addr_remove() as suggested
  by Ferruh
* dpaa/dpaa2: fix return value as suggested by Shreyansh

v2:
* add same change for net/cxgbe
* mrvl was renamed as mvpp2
* mvpp2: return success if no ppio as suggested by Tomasz
* mlx5: update comment as suggested by Adrien
* sfc: replace by Ivan's patch

 doc/guides/rel_notes/deprecation.rst    |  8 --------
 drivers/net/ark/ark_ethdev.c            |  9 ++++++---
 drivers/net/avf/avf_ethdev.c            | 12 +++++++----
 drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
 drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
 drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
 drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
 drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
 drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
 drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
 drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
 drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
 drivers/net/mlx4/mlx4.h                 |  2 +-
 drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
 drivers/net/mlx5/mlx5.h                 |  2 +-
 drivers/net/mlx5/mlx5_mac.c             |  6 +++++-
 drivers/net/mvpp2/mrvl_ethdev.c         | 11 ++++++++---
 drivers/net/null/rte_eth_null.c         |  3 ++-
 drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
 drivers/net/qede/qede_ethdev.c          |  7 +++----
 drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
 drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
 drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
 drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
 lib/librte_ether/rte_ethdev.c           |  7 +++++--
 lib/librte_ether/rte_ethdev_core.h      |  2 +-
 test/test/virtual_pmd.c                 |  3 ++-
 30 files changed, 184 insertions(+), 104 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index ec70b5fa9..efef7cf6b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -131,14 +131,6 @@ Deprecation Notices
   between the VF representor and the VF or the parent PF. Those new fields
   are to be included in ``rte_eth_dev_info`` struct.
 
-* ethdev: The prototype and the behavior of
-  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
-  will be added to notify the caller if an error occurred in the PMD. In
-  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
-  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
-  successful. This modification will only impact the PMDs, not the
-  applications.
-
 * i40e: The default flexible payload configuration which extracts the first 16
   bytes of the payload for RSS will be deprecated starting from 18.02. If
   required the previous behavior can be configured using existing flow
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ff87c20e2..3fc40cd74 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
 				  struct rte_eth_stats *stats);
 static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
-static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
+static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
 			       struct ether_addr *mac_addr,
@@ -887,16 +887,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
 			      ark->user_data[dev->data->port_id]);
 }
 
-static void
+static int
 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
 	struct ark_adapter *ark =
 		(struct ark_adapter *)dev->data->dev_private;
 
-	if (ark->user_ext.mac_addr_set)
+	if (ark->user_ext.mac_addr_set) {
 		ark->user_ext.mac_addr_set(dev, mac_addr,
 			   ark->user_data[dev->data->port_id]);
+		return 0;
+	}
+	return -ENOTSUP;
 }
 
 static int
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index b59e3cf79..ab2e8107a 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				     struct rte_eth_rss_conf *rss_conf);
 static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
 					uint16_t queue_id);
@@ -926,7 +926,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
@@ -940,11 +940,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
 	if (is_same_ether_addr(mac_addr, old_addr))
-		return;
+		return 0;
 
 	/* If the MAC address is configured by host, skip the setting */
 	if (is_valid_assigned_ether_addr(perm_addr))
-		return;
+		return -EPERM;
 
 	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
 	if (ret)
@@ -968,7 +968,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			    mac_addr->addr_bytes[4],
 			    mac_addr->addr_bytes[5]);
 
+	if (ret)
+		return -EIO;
+
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7c007c8f9..5e50322f6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1370,7 +1370,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 	return 0;
 }
 
-static void
+static int
 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
@@ -1380,7 +1380,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 	int rc;
 
 	if (BNXT_VF(bp))
-		return;
+		return -EPERM;
 
 	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
 
@@ -1390,7 +1390,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			continue;
 		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
 		if (rc)
-			break;
+			return rc;
 		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
 		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
@@ -1399,10 +1399,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
-			break;
+			return rc;
 		filter->mac_index = 0;
 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 2ba1055e2..8847d20c2 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2872,11 +2872,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
-	if (mac_address_set(dev, addr))
+	if (mac_address_set(dev, addr)) {
 		RTE_BOND_LOG(ERR, "Failed to update MAC address");
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct eth_dev_ops default_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 581a1f33a..857a849e3 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1058,7 +1058,7 @@ static int cxgbe_get_regs(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -1069,9 +1069,10 @@ void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 	if (ret < 0) {
 		dev_err(adapter, "failed to set mac addr; err = %d\n",
 			ret);
-		return;
+		return ret;
 	}
 	pi->xact_addr_filt = ret;
+	return 0;
 }
 
 static const struct eth_dev_ops cxgbe_eth_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 0c1c17071..2bba97423 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -16,7 +16,7 @@ void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 void 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);
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
 int cxgbe_dev_configure(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx,
 			     uint16_t nb_desc, unsigned int socket_id,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index db493648a..367b0d2b2 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 	fman_if_clear_mac_addr(dpaa_intf->fif, index);
 }
 
-static void
+static int
 dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
 	if (ret)
 		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static struct eth_dev_ops dpaa_devops = {
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 281483dfd..852bd10eb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1019,7 +1019,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
 			"error: Removing the MAC ADDR failed: err = %d", ret);
 }
 
-static void
+static int
 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -1031,7 +1031,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -EINVAL;
 	}
 
 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
@@ -1040,6 +1040,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 	if (ret)
 		DPAA2_PMD_ERR(
 			"error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 8d4226676..b706446c5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -145,7 +145,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
 			   struct ether_addr *mac_addr,
 			   uint32_t index, uint32_t pool);
 static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 
 static void igbvf_intr_disable(struct e1000_hw *hw);
@@ -170,7 +170,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
-static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
+static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 static int igbvf_get_reg_length(struct rte_eth_dev *dev);
 static int igbvf_get_regs(struct rte_eth_dev *dev,
@@ -3089,13 +3089,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *addr)
 {
 	eth_igb_rar_clear(dev, 0);
-
 	eth_igb_rar_set(dev, (void *)addr, 0, 0);
+
+	return 0;
 }
 /*
  * Virtual Function operations
@@ -3447,7 +3448,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
+static int
 igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct e1000_hw *hw =
@@ -3455,6 +3456,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 	/* index is not used by rar_set() */
 	hw->mac.ops.rar_set(hw, (void *)addr, 0);
+	return 0;
 }
 
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 057e435cf..8ca69abe4 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -997,16 +997,27 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
-	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
-		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+		ret = fs_err(sdev, ret);
+		if (ret) {
+			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %d with error %d",
+				i, ret);
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 6e06f8a2b..96c336893 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
 static int i40e_get_eeprom(struct rte_eth_dev *dev,
 			   struct rte_dev_eeprom_info *eeprom);
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -11301,8 +11301,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-				      struct ether_addr *mac_addr)
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+				     struct ether_addr *mac_addr)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11313,7 +11313,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
@@ -11323,25 +11323,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (f == NULL) {
 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
-		return;
+		return -EIO;
 	}
 
 	mac_filter = f->mac_info;
 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
 
-	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
-				  mac_addr->addr_bytes, NULL);
+	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+					mac_addr->addr_bytes, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to change mac");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 2908c87e0..65d1043d9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 					struct rte_eth_rss_conf *rss_conf);
 static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 					struct ether_addr *mac_addr);
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
@@ -2667,7 +2667,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 			    struct ether_addr *mac_addr)
 {
@@ -2676,17 +2676,19 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-		return;
+		return -EPERM;
 
 	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
-	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
+		return -EIO;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index fbc048f7d..30c597e3c 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -227,7 +227,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			 uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -285,7 +285,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
 					     struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
 			struct rte_eth_syn_filter *filter);
@@ -4768,14 +4768,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
 	ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
 	ixgbe_remove_rar(dev, 0);
-
 	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+	return 0;
 }
 
 static bool
@@ -5922,12 +5923,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
 	}
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 19c8a223d..c107794ce 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 		      uint32_t index, uint32_t vmdq);
-void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 void mlx4_stats_reset(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 5f731e023..c43ed8234 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -534,11 +534,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index faacfd9d6..738709854 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -195,7 +195,7 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
 		      uint32_t index, uint32_t vmdq);
-void mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 
 /* mlx5_rss.c */
 
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index 01c7ba17a..6ca1cc4a1 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	int ret;
@@ -137,4 +140,5 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	if (ret)
 		DRV_LOG(ERR, "port %u cannot set mac address: %s",
 			dev->data->port_id, strerror(rte_errno));
+	return ret;
 }
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 6ab515ca9..d787154cc 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -1061,18 +1061,21 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
-static void
+static int
 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	if (priv->isolated)
-		return;
+		return -ENOTSUP;
 
 	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
 	if (ret) {
@@ -1080,6 +1083,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ether_format_addr(buf, sizeof(buf), mac_addr);
 		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 73fe8b04a..74dde9521 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -459,10 +459,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 		    __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index 1406e4e19..ffd40a4cb 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -586,7 +586,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
 	octeontx_port_stats_clr(nic);
 }
 
-static void
+static int
 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct ether_addr *addr)
 {
@@ -597,6 +597,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 	if (ret != 0)
 		octeontx_log_err("failed to set MAC address on port %d",
 				nic->port_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index a4e9e753e..02db65e2f 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1041,7 +1041,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	qede_mac_int_ops(eth_dev, &ucast, false);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1050,12 +1050,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
 					       mac_addr->addr_bytes)) {
 		DP_ERR(edev, "Setting MAC address is not allowed\n");
-		ether_addr_copy(&qdev->primary_mac,
-				&eth_dev->data->mac_addrs[0]);
-		return;
+		return -EPERM;
 	}
 
 	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+	return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2af898e08..30cb22e8e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -915,13 +915,14 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	SFC_ASSERT(rc > 0);
 	return -rc;
 }
-static void
+static int
 sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_port *port = &sa->port;
-	int rc;
+	struct ether_addr *old_addr = &dev->data->mac_addrs[0];
+	int rc = 0;
 
 	sfc_adapter_lock(sa);
 
@@ -931,9 +932,16 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	 */
 	ether_addr_copy(mac_addr, &port->default_mac_addr);
 
+	/*
+	 * Neither of the two following checks can return
+	 * an error. The new MAC address is preserved in
+	 * the device private data and can be activated
+	 * on the next port start if the user prevents
+	 * isolated mode from being enabled.
+	 */
 	if (port->isolated) {
-		sfc_err(sa, "isolated mode is active on the port");
-		sfc_err(sa, "will not set MAC address");
+		sfc_warn(sa, "isolated mode is active on the port");
+		sfc_warn(sa, "will not set MAC address");
 		goto unlock;
 	}
 
@@ -957,8 +965,12 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		 * we also need to update unicast filters
 		 */
 		rc = sfc_set_rx_mode(sa);
-		if (rc != 0)
+		if (rc != 0) {
 			sfc_err(sa, "cannot set filter (rc = %u)", rc);
+			/* Rollback the old address */
+			(void)efx_mac_addr_set(sa->nic, old_addr->addr_bytes);
+			(void)sfc_set_rx_mode(sa);
+		}
 	} else {
 		sfc_warn(sa, "cannot set MAC address with filters installed");
 		sfc_warn(sa, "adapter will be restarted to pick the new MAC");
@@ -977,14 +989,13 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	}
 
 unlock:
-	/*
-	 * In the case of failure sa->port->default_mac_addr does not
-	 * need rollback since no error code is returned, and the upper
-	 * API will anyway update the external MAC address storage.
-	 * To be consistent with that new value it is better to keep
-	 * the device private value the same.
-	 */
+	if (rc != 0)
+		ether_addr_copy(old_addr, &port->default_mac_addr);
+
 	sfc_adapter_unlock(sa);
+
+	SFC_ASSERT(rc >= 0);
+	return -rc;
 }
 
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index fb9aac04b..02682576d 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1361,10 +1361,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 		struct ether_addr *mac_addr __rte_unused)
 {
+	return 0;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index ed6d7380e..6cd1da418 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -934,48 +934,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
 
-static void
+static int
 tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	enum ioctl_mode mode = LOCAL_ONLY;
 	struct ifreq ifr;
+	int ret;
 
 	if (is_zero_ether_addr(mac_addr)) {
 		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
 			dev->device->name);
-		return;
+		return -EINVAL;
 	}
 	/* Check the actual current MAC address on the tap netdevice */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
+	if (ret < 0)
+		return ret;
 	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
-		return;
+		return 0;
 	/* Check the current MAC address on the remote */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
+	if (ret < 0)
+		return ret;
 	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
 		mode = LOCAL_AND_REMOTE;
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
+	if (ret < 0)
+		return ret;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 	if (pmd->remote_if_index && !pmd->flow_isolate) {
 		/* Replace MAC redirection rule after a MAC change */
-		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't delete MAC redirection rule\n",
 				dev->device->name);
-			return;
+			return ret;
 		}
-		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't add MAC redirection rule\n",
 				dev->device->name);
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 11f758929..31cdfd6f5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -67,7 +67,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -1056,7 +1056,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 	virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1072,9 +1072,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
 		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-		virtio_send_command(hw->cvq, &ctrl, &len, 1);
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-		virtio_set_hwaddr(hw);
+		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	}
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+		return -ENOTSUP;
+
+	virtio_set_hwaddr(hw);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 426008722..5cefa6664 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -72,7 +72,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
+static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
 				 struct ether_addr *mac_addr);
 static void vmxnet3_interrupt_handler(void *param);
 
@@ -1078,13 +1078,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+static int
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
+	return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 2c74f7e04..2aefe7ebf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3005,6 +3005,7 @@ int
 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3014,11 +3015,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
+	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+	if (ret < 0)
+		return ret;
+
 	/* Update default address in NIC data structure */
 	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
-	(*dev->dev_ops->mac_addr_set)(dev, addr);
-
 	return 0;
 }
 
diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
index e5681e466..55eb2b09e 100644
--- a/lib/librte_ether/rte_ethdev_core.h
+++ b/lib/librte_ether/rte_ethdev_core.h
@@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
 				  uint32_t vmdq);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
-typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 2f5b31dba..69b4ba034 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -216,10 +216,11 @@ static void
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
 {}
 
-static void
+static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 			       __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
-- 
2.11.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-04-06 15:21   ` [dpdk-dev] [PATCH] " Olivier Matz
@ 2018-04-06 15:34     ` Olivier Matz
  2018-04-09  8:57     ` Nélio Laranjeiro
  1 sibling, 0 replies; 21+ messages in thread
From: Olivier Matz @ 2018-04-06 15:34 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Adrien Mazarguil, Shreyansh Jain, Ivan Malov


On Fri, Apr 06, 2018 at 05:21:48PM +0200, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>

Sorry, "v3" is missing in the subject.
Please ignore, I'm sending it again with the proper title.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v3] ethdev: return diagnostic when setting MAC address
  2018-04-06 15:34   ` [dpdk-dev] [PATCH v3] " Olivier Matz
@ 2018-04-06 16:03     ` Ferruh Yigit
  2018-04-10 13:19       ` Thomas Monjalon
  2018-04-11 16:32     ` [dpdk-dev] [PATCH v4] " Olivier Matz
  1 sibling, 1 reply; 21+ messages in thread
From: Ferruh Yigit @ 2018-04-06 16:03 UTC (permalink / raw)
  To: Olivier Matz, dev
  Cc: Thomas Monjalon, Tomasz Duszynski, Andrew Rybchenko,
	Adrien Mazarguil, Shreyansh Jain, Ivan Malov

On 4/6/2018 4:34 PM, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>

Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address
  2018-04-06 15:21   ` [dpdk-dev] [PATCH] " Olivier Matz
  2018-04-06 15:34     ` Olivier Matz
@ 2018-04-09  8:57     ` Nélio Laranjeiro
  1 sibling, 0 replies; 21+ messages in thread
From: Nélio Laranjeiro @ 2018-04-09  8:57 UTC (permalink / raw)
  To: Olivier Matz
  Cc: dev, Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Adrien Mazarguil, Shreyansh Jain, Ivan Malov

On Fri, Apr 06, 2018 at 05:21:48PM +0200, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
> 
> v3:
> * mlx5: remove empty line as suggested by Adrien
> * mvpp2: remove wrong changes in mrvl_mac_addr_remove() as suggested
>   by Ferruh
> * dpaa/dpaa2: fix return value as suggested by Shreyansh
> 
> v2:
> * add same change for net/cxgbe
> * mrvl was renamed as mvpp2
> * mvpp2: return success if no ppio as suggested by Tomasz
> * mlx5: update comment as suggested by Adrien
> * sfc: replace by Ivan's patch
> 
> 
>  doc/guides/rel_notes/deprecation.rst    |  8 --------
>  drivers/net/ark/ark_ethdev.c            |  9 ++++++---
>  drivers/net/avf/avf_ethdev.c            | 12 +++++++----
>  drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
>  drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
>  drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
>  drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
>  drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
>  drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
>  drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
>  drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
>  drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
>  drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
>  drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
>  drivers/net/mlx4/mlx4.h                 |  2 +-
>  drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
>  drivers/net/mlx5/mlx5.h                 |  2 +-
>  drivers/net/mlx5/mlx5_mac.c             |  6 +++++-
>  drivers/net/mvpp2/mrvl_ethdev.c         | 11 ++++++++---
>  drivers/net/null/rte_eth_null.c         |  3 ++-
>  drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
>  drivers/net/qede/qede_ethdev.c          |  7 +++----
>  drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
>  drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
>  drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
>  drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
>  drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
>  lib/librte_ether/rte_ethdev.c           |  7 +++++--
>  lib/librte_ether/rte_ethdev_core.h      |  2 +-
>  test/test/virtual_pmd.c                 |  3 ++-
>  30 files changed, 184 insertions(+), 104 deletions(-)
> 
</snip>
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index faacfd9d6..738709854 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -195,7 +195,7 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[ETHER_ADDR_LEN]);
>  void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
>  int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
>  		      uint32_t index, uint32_t vmdq);
> -void mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
> +int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
>  
>  /* mlx5_rss.c */
>  
> diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
> index 01c7ba17a..6ca1cc4a1 100644
> --- a/drivers/net/mlx5/mlx5_mac.c
> +++ b/drivers/net/mlx5/mlx5_mac.c
> @@ -124,8 +124,11 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
>   *   Pointer to Ethernet device structure.
>   * @param mac_addr
>   *   MAC address to register.
> + *
> + * @return
> + *   0 on success, a negative errno value otherwise and rte_errno is set.
>   */
> -void
> +int
>  mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  {
>  	int ret;
> @@ -137,4 +140,5 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
>  	if (ret)
>  		DRV_LOG(ERR, "port %u cannot set mac address: %s",
>  			dev->data->port_id, strerror(rte_errno));
> +	return ret;
>  }

You should also remove the DRV_LOG which become useless, it has been
added as the function did not return anything, now has it returns an
error, the application can fully handle it.

Unless that, for MLX5

Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v3] ethdev: return diagnostic when setting MAC address
  2018-04-06 16:03     ` Ferruh Yigit
@ 2018-04-10 13:19       ` Thomas Monjalon
  0 siblings, 0 replies; 21+ messages in thread
From: Thomas Monjalon @ 2018-04-10 13:19 UTC (permalink / raw)
  To: Olivier Matz
  Cc: dev, Ferruh Yigit, Tomasz Duszynski, Andrew Rybchenko,
	Adrien Mazarguil, Shreyansh Jain, Ivan Malov

06/04/2018 18:03, Ferruh Yigit:
> On 4/6/2018 4:34 PM, Olivier Matz wrote:
> > Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> > return code is added to notify the caller (librte_ether) if an error
> > occurred in the PMD.
> > 
> > The new default MAC address is now copied in dev->data->mac_addrs[0]
> > only if the operation is successful.
> > 
> > The patch also updates all the PMDs accordingly.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> > Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> 
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Acked-by: Thomas Monjalon <thomas@monjalon.net>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [dpdk-dev] [PATCH v4] ethdev: return diagnostic when setting MAC address
  2018-04-06 15:34   ` [dpdk-dev] [PATCH v3] " Olivier Matz
  2018-04-06 16:03     ` Ferruh Yigit
@ 2018-04-11 16:32     ` Olivier Matz
  2018-04-11 19:30       ` Ferruh Yigit
  1 sibling, 1 reply; 21+ messages in thread
From: Olivier Matz @ 2018-04-11 16:32 UTC (permalink / raw)
  To: dev
  Cc: Thomas Monjalon, Ferruh Yigit, Tomasz Duszynski,
	Andrew Rybchenko, Adrien Mazarguil, Shreyansh Jain,
	Nelio Laranjeiro, Ivan Malov

Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
return code is added to notify the caller (librte_ether) if an error
occurred in the PMD.

The new default MAC address is now copied in dev->data->mac_addrs[0]
only if the operation is successful.

The patch also updates all the PMDs accordingly.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---

v4:
* mlx5: remove uneeded log
* em: add same change after b379efe1b0f2 ("net/e1000: add MAC
  address set to em")

v3:
* mlx5: remove empty line as suggested by Adrien
* mvpp2: remove wrong changes in mrvl_mac_addr_remove() as suggested
  by Ferruh
* dpaa/dpaa2: fix return value as suggested by Shreyansh

v2:
* add same change for net/cxgbe
* mrvl was renamed as mvpp2
* mvpp2: return success if no ppio as suggested by Tomasz
* mlx5: update comment as suggested by Adrien
* sfc: replace by Ivan's patch

 doc/guides/rel_notes/deprecation.rst    |  8 --------
 drivers/net/ark/ark_ethdev.c            |  9 ++++++---
 drivers/net/avf/avf_ethdev.c            | 12 +++++++----
 drivers/net/bnxt/bnxt_ethdev.c          | 10 ++++++----
 drivers/net/bonding/rte_eth_bond_pmd.c  |  8 ++++++--
 drivers/net/cxgbe/cxgbe_ethdev.c        |  5 +++--
 drivers/net/cxgbe/cxgbe_pfvf.h          |  2 +-
 drivers/net/dpaa/dpaa_ethdev.c          |  4 +++-
 drivers/net/dpaa2/dpaa2_ethdev.c        |  6 ++++--
 drivers/net/e1000/em_ethdev.c           |  6 +++---
 drivers/net/e1000/igb_ethdev.c          | 12 ++++++-----
 drivers/net/failsafe/failsafe_ops.c     | 17 +++++++++++++---
 drivers/net/i40e/i40e_ethdev.c          | 24 +++++++++++++---------
 drivers/net/i40e/i40e_ethdev_vf.c       | 12 ++++++-----
 drivers/net/ixgbe/ixgbe_ethdev.c        | 13 +++++++-----
 drivers/net/mlx4/mlx4.h                 |  2 +-
 drivers/net/mlx4/mlx4_ethdev.c          |  7 +++++--
 drivers/net/mlx5/mlx5.h                 |  2 +-
 drivers/net/mlx5/mlx5_mac.c             | 13 +++++-------
 drivers/net/mvpp2/mrvl_ethdev.c         | 11 ++++++++---
 drivers/net/null/rte_eth_null.c         |  3 ++-
 drivers/net/octeontx/octeontx_ethdev.c  |  4 +++-
 drivers/net/qede/qede_ethdev.c          |  7 +++----
 drivers/net/sfc/sfc_ethdev.c            | 35 ++++++++++++++++++++++-----------
 drivers/net/szedata2/rte_eth_szedata2.c |  3 ++-
 drivers/net/tap/rte_eth_tap.c           | 34 +++++++++++++++++++++-----------
 drivers/net/virtio/virtio_ethdev.c      | 15 +++++++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  5 +++--
 lib/librte_ether/rte_ethdev.c           |  7 +++++--
 lib/librte_ether/rte_ethdev_core.h      |  2 +-
 test/test/virtual_pmd.c                 |  3 ++-
 31 files changed, 187 insertions(+), 114 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index d13077d31..97ea9d656 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -118,14 +118,6 @@ Deprecation Notices
   between the VF representor and the VF or the parent PF. Those new fields
   are to be included in ``rte_eth_dev_info`` struct.
 
-* ethdev: The prototype and the behavior of
-  ``dev_ops->eth_mac_addr_set()`` will change in v18.05. A return code
-  will be added to notify the caller if an error occurred in the PMD. In
-  ``rte_eth_dev_default_mac_addr_set()``, the new default MAC address
-  will be copied in ``dev->data->mac_addrs[0]`` only if the operation is
-  successful. This modification will only impact the PMDs, not the
-  applications.
-
 * i40e: The default flexible payload configuration which extracts the first 16
   bytes of the payload for RSS will be deprecated starting from 18.02. If
   required the previous behavior can be configured using existing flow
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index c9d541921..d275ab7e8 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -69,7 +69,7 @@ static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev);
 static int eth_ark_dev_stats_get(struct rte_eth_dev *dev,
 				  struct rte_eth_stats *stats);
 static void eth_ark_dev_stats_reset(struct rte_eth_dev *dev);
-static void eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
+static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int eth_ark_macaddr_add(struct rte_eth_dev *dev,
 			       struct ether_addr *mac_addr,
@@ -886,16 +886,19 @@ eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
 			      ark->user_data[dev->data->port_id]);
 }
 
-static void
+static int
 eth_ark_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
 	struct ark_adapter *ark =
 		(struct ark_adapter *)dev->data->dev_private;
 
-	if (ark->user_ext.mac_addr_set)
+	if (ark->user_ext.mac_addr_set) {
 		ark->user_ext.mac_addr_set(dev, mac_addr,
 			   ark->user_data[dev->data->port_id]);
+		return 0;
+	}
+	return -ENOTSUP;
 }
 
 static int
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
index 8e2a1b066..e1305359e 100644
--- a/drivers/net/avf/avf_ethdev.c
+++ b/drivers/net/avf/avf_ethdev.c
@@ -65,7 +65,7 @@ static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 				     struct rte_eth_rss_conf *rss_conf);
 static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 					 struct ether_addr *mac_addr);
 static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
 					uint16_t queue_id);
@@ -925,7 +925,7 @@ avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *mac_addr)
 {
@@ -939,11 +939,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 	perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
 	if (is_same_ether_addr(mac_addr, old_addr))
-		return;
+		return 0;
 
 	/* If the MAC address is configured by host, skip the setting */
 	if (is_valid_assigned_ether_addr(perm_addr))
-		return;
+		return -EPERM;
 
 	ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
 	if (ret)
@@ -967,7 +967,11 @@ avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
 			    mac_addr->addr_bytes[4],
 			    mac_addr->addr_bytes[5]);
 
+	if (ret)
+		return -EIO;
+
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 9f77e9a05..e6c9aa770 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1403,7 +1403,7 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 	return 0;
 }
 
-static void
+static int
 bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
@@ -1413,7 +1413,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 	int rc;
 
 	if (BNXT_VF(bp))
-		return;
+		return -EPERM;
 
 	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
 
@@ -1423,7 +1423,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			continue;
 		rc = bnxt_hwrm_clear_l2_filter(bp, filter);
 		if (rc)
-			break;
+			return rc;
 		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
 		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
 		filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
@@ -1432,10 +1432,12 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
 		rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
-			break;
+			return rc;
 		filter->mac_index = 0;
 		PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 2ba1055e2..8847d20c2 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2872,11 +2872,15 @@ bond_ethdev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
-static void
+static int
 bond_ethdev_mac_address_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
-	if (mac_address_set(dev, addr))
+	if (mac_address_set(dev, addr)) {
 		RTE_BOND_LOG(ERR, "Failed to update MAC address");
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct eth_dev_ops default_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 24c9a9323..3df51b5be 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1056,7 +1056,7 @@ static int cxgbe_get_regs(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
 	struct adapter *adapter = pi->adapter;
@@ -1067,9 +1067,10 @@ void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 	if (ret < 0) {
 		dev_err(adapter, "failed to set mac addr; err = %d\n",
 			ret);
-		return;
+		return ret;
 	}
 	pi->xact_addr_filt = ret;
+	return 0;
 }
 
 static const struct eth_dev_ops cxgbe_eth_dev_ops = {
diff --git a/drivers/net/cxgbe/cxgbe_pfvf.h b/drivers/net/cxgbe/cxgbe_pfvf.h
index 0c1c17071..2bba97423 100644
--- a/drivers/net/cxgbe/cxgbe_pfvf.h
+++ b/drivers/net/cxgbe/cxgbe_pfvf.h
@@ -16,7 +16,7 @@ void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 void 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);
-void cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
+int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr);
 int cxgbe_dev_configure(struct rte_eth_dev *eth_dev);
 int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx,
 			     uint16_t nb_desc, unsigned int socket_id,
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index db493648a..367b0d2b2 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -813,7 +813,7 @@ dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 	fman_if_clear_mac_addr(dpaa_intf->fif, index);
 }
 
-static void
+static int
 dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -825,6 +825,8 @@ dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 	ret = fman_if_add_mac_addr(dpaa_intf->fif, addr->addr_bytes, 0);
 	if (ret)
 		RTE_LOG(ERR, PMD, "error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static struct eth_dev_ops dpaa_devops = {
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 281483dfd..852bd10eb 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -1019,7 +1019,7 @@ dpaa2_dev_remove_mac_addr(struct rte_eth_dev *dev,
 			"error: Removing the MAC ADDR failed: err = %d", ret);
 }
 
-static void
+static int
 dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 		       struct ether_addr *addr)
 {
@@ -1031,7 +1031,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	if (dpni == NULL) {
 		DPAA2_PMD_ERR("dpni is NULL");
-		return;
+		return -EINVAL;
 	}
 
 	ret = dpni_set_primary_mac_addr(dpni, CMD_PRI_LOW,
@@ -1040,6 +1040,8 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
 	if (ret)
 		DPAA2_PMD_ERR(
 			"error: Setting the MAC ADDR failed %d", ret);
+
+	return ret;
 }
 
 static
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 9d089cfe9..de7db2650 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -93,7 +93,7 @@ static int em_get_rx_buffer_size(struct e1000_hw *hw);
 static int eth_em_rar_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			  uint32_t index, uint32_t pool);
 static void eth_em_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_em_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_em_default_mac_addr_set(struct rte_eth_dev *dev,
 					 struct ether_addr *addr);
 
 static int eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
@@ -1779,13 +1779,13 @@ eth_em_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_em_default_mac_addr_set(struct rte_eth_dev *dev,
 			    struct ether_addr *addr)
 {
 	eth_em_rar_clear(dev, 0);
 
-	eth_em_rar_set(dev, (void *)addr, 0, 0);
+	return eth_em_rar_set(dev, (void *)addr, 0, 0);
 }
 
 static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 872357146..9b808a982 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -145,7 +145,7 @@ static int eth_igb_rar_set(struct rte_eth_dev *dev,
 			   struct ether_addr *mac_addr,
 			   uint32_t index, uint32_t pool);
 static void eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index);
-static void eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
+static int eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 
 static void igbvf_intr_disable(struct e1000_hw *hw);
@@ -170,7 +170,7 @@ static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
-static void igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
+static int igbvf_default_mac_addr_set(struct rte_eth_dev *dev,
 		struct ether_addr *addr);
 static int igbvf_get_reg_length(struct rte_eth_dev *dev);
 static int igbvf_get_regs(struct rte_eth_dev *dev,
@@ -3087,13 +3087,14 @@ eth_igb_rar_clear(struct rte_eth_dev *dev, uint32_t index)
 	e1000_rar_set(hw, addr, index);
 }
 
-static void
+static int
 eth_igb_default_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *addr)
 {
 	eth_igb_rar_clear(dev, 0);
-
 	eth_igb_rar_set(dev, (void *)addr, 0, 0);
+
+	return 0;
 }
 /*
  * Virtual Function operations
@@ -3445,7 +3446,7 @@ igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-static void
+static int
 igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct e1000_hw *hw =
@@ -3453,6 +3454,7 @@ igbvf_default_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 	/* index is not used by rar_set() */
 	hw->mac.ops.rar_set(hw, (void *)addr, 0);
+	return 0;
 }
 
 
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 057e435cf..8ca69abe4 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -997,16 +997,27 @@ fs_mac_addr_add(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 fs_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sub_device *sdev;
 	uint8_t i;
+	int ret;
 
 	fs_lock(dev, 0);
-	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE)
-		rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+	FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_ACTIVE) {
+		ret = rte_eth_dev_default_mac_addr_set(PORT_ID(sdev), mac_addr);
+		ret = fs_err(sdev, ret);
+		if (ret) {
+			ERROR("Operation rte_eth_dev_mac_addr_set failed for sub_device %d with error %d",
+				i, ret);
+			fs_unlock(dev, 0);
+			return ret;
+		}
+	}
 	fs_unlock(dev, 0);
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7675ac5d9..8a3c1267c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -369,7 +369,7 @@ static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
 static int i40e_get_eeprom(struct rte_eth_dev *dev,
 			   struct rte_dev_eeprom_info *eeprom);
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -11327,8 +11327,8 @@ static int i40e_get_eeprom(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
-				      struct ether_addr *mac_addr)
+static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
+				     struct ether_addr *mac_addr)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -11339,7 +11339,7 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
@@ -11349,25 +11349,31 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (f == NULL) {
 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
-		return;
+		return -EIO;
 	}
 
 	mac_filter = f->mac_info;
 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
 	if (ret != I40E_SUCCESS) {
 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
-		return;
+		return -EIO;
 	}
 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
 
-	i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
-				  mac_addr->addr_bytes, NULL);
+	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
+					mac_addr->addr_bytes, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to change mac");
+		return -EIO;
+	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index f6d7f40b1..031c70680 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -120,7 +120,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
 static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 					struct rte_eth_rss_conf *rss_conf);
 static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
-static void i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 					struct ether_addr *mac_addr);
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
@@ -2666,7 +2666,7 @@ i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return ret;
 }
 
-static void
+static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 			    struct ether_addr *mac_addr)
 {
@@ -2675,17 +2675,19 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	if (!is_valid_assigned_ether_addr(mac_addr)) {
 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
-		return;
+		return -EINVAL;
 	}
 
 	if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-		return;
+		return -EPERM;
 
 	i40evf_del_mac_addr_by_addr(dev, (struct ether_addr *)hw->mac.addr);
 
-	i40evf_add_mac_addr(dev, mac_addr, 0, 0);
+	if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)
+		return -EIO;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 0b7760717..2e13caed1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -227,7 +227,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 			 uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
 					   struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -285,7 +285,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
 					     struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
 			struct rte_eth_syn_filter *filter);
@@ -4768,14 +4768,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
 	ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
 	ixgbe_remove_rar(dev, 0);
-
 	ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+	return 0;
 }
 
 static bool
@@ -5924,12 +5925,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
 	}
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
 	hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+	return 0;
 }
 
 int
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 19c8a223d..c107794ce 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -131,7 +131,7 @@ void mlx4_allmulticast_disable(struct rte_eth_dev *dev);
 void mlx4_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx4_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 		      uint32_t index, uint32_t vmdq);
-void mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 int mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 int mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 void mlx4_stats_reset(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index 636100b23..0dfcf6ef6 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -534,11 +534,14 @@ mlx4_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx4_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	mlx4_mac_addr_add(dev, mac_addr, 0, 0);
+	return mlx4_mac_addr_add(dev, mac_addr, 0, 0);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 63b24e6bb..2b1e6934a 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -202,7 +202,7 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
 		      uint32_t index, uint32_t vmdq);
-void mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
+int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr);
 
 /* mlx5_rss.c */
 
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index e859fca6a..bd5bdedf7 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -138,17 +138,14 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-void
+int
 mlx5_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-	int ret;
-
 	DRV_LOG(DEBUG, "port %u setting primary MAC address",
 		dev->data->port_id);
-
-	ret = mlx5_mac_addr_add(dev, mac_addr, 0, 0);
-	if (ret)
-		DRV_LOG(ERR, "port %u cannot set mac address: %s",
-			dev->data->port_id, strerror(rte_errno));
+	return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
 }
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 6ab515ca9..d787154cc 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -1061,18 +1061,21 @@ mrvl_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
  *   Pointer to Ethernet device structure.
  * @param mac_addr
  *   MAC address to register.
+ *
+ * @return
+ *   0 on success, negative error value otherwise.
  */
-static void
+static int
 mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct mrvl_priv *priv = dev->data->dev_private;
 	int ret;
 
 	if (!priv->ppio)
-		return;
+		return 0;
 
 	if (priv->isolated)
-		return;
+		return -ENOTSUP;
 
 	ret = pp2_ppio_set_mac_addr(priv->ppio, mac_addr->addr_bytes);
 	if (ret) {
@@ -1080,6 +1083,8 @@ mrvl_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ether_format_addr(buf, sizeof(buf), mac_addr);
 		RTE_LOG(ERR, PMD, "Failed to set mac to %s\n", buf);
 	}
+
+	return ret;
 }
 
 /**
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 73fe8b04a..74dde9521 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -459,10 +459,11 @@ eth_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 		    __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops ops = {
diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index f829e0ca9..6d67d257c 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -586,7 +586,7 @@ octeontx_dev_stats_reset(struct rte_eth_dev *dev)
 	octeontx_port_stats_clr(nic);
 }
 
-static void
+static int
 octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 					struct ether_addr *addr)
 {
@@ -597,6 +597,8 @@ octeontx_dev_default_mac_addr_set(struct rte_eth_dev *dev,
 	if (ret != 0)
 		octeontx_log_err("failed to set MAC address on port %d",
 				nic->port_id);
+
+	return ret;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 13c2a3b87..12023002e 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1041,7 +1041,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	qede_mac_int_ops(eth_dev, &ucast, false);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1050,12 +1050,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
 					       mac_addr->addr_bytes)) {
 		DP_ERR(edev, "Setting MAC address is not allowed\n");
-		ether_addr_copy(&qdev->primary_mac,
-				&eth_dev->data->mac_addrs[0]);
-		return;
+		return -EPERM;
 	}
 
 	qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+	return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6631c5a7e..47d7a8609 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -914,13 +914,14 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	SFC_ASSERT(rc > 0);
 	return -rc;
 }
-static void
+static int
 sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct sfc_port *port = &sa->port;
-	int rc;
+	struct ether_addr *old_addr = &dev->data->mac_addrs[0];
+	int rc = 0;
 
 	sfc_adapter_lock(sa);
 
@@ -930,9 +931,16 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	 */
 	ether_addr_copy(mac_addr, &port->default_mac_addr);
 
+	/*
+	 * Neither of the two following checks can return
+	 * an error. The new MAC address is preserved in
+	 * the device private data and can be activated
+	 * on the next port start if the user prevents
+	 * isolated mode from being enabled.
+	 */
 	if (port->isolated) {
-		sfc_err(sa, "isolated mode is active on the port");
-		sfc_err(sa, "will not set MAC address");
+		sfc_warn(sa, "isolated mode is active on the port");
+		sfc_warn(sa, "will not set MAC address");
 		goto unlock;
 	}
 
@@ -956,8 +964,12 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		 * we also need to update unicast filters
 		 */
 		rc = sfc_set_rx_mode(sa);
-		if (rc != 0)
+		if (rc != 0) {
 			sfc_err(sa, "cannot set filter (rc = %u)", rc);
+			/* Rollback the old address */
+			(void)efx_mac_addr_set(sa->nic, old_addr->addr_bytes);
+			(void)sfc_set_rx_mode(sa);
+		}
 	} else {
 		sfc_warn(sa, "cannot set MAC address with filters installed");
 		sfc_warn(sa, "adapter will be restarted to pick the new MAC");
@@ -976,14 +988,13 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 	}
 
 unlock:
-	/*
-	 * In the case of failure sa->port->default_mac_addr does not
-	 * need rollback since no error code is returned, and the upper
-	 * API will anyway update the external MAC address storage.
-	 * To be consistent with that new value it is better to keep
-	 * the device private value the same.
-	 */
+	if (rc != 0)
+		ether_addr_copy(old_addr, &port->default_mac_addr);
+
 	sfc_adapter_unlock(sa);
+
+	SFC_ASSERT(rc >= 0);
+	return -rc;
 }
 
 
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 41a6fb427..824debb22 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1360,10 +1360,11 @@ eth_tx_queue_setup(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static void
+static int
 eth_mac_addr_set(struct rte_eth_dev *dev __rte_unused,
 		struct ether_addr *mac_addr __rte_unused)
 {
+	return 0;
 }
 
 static void
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 54c7c2b0f..915d9373f 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -956,48 +956,58 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
 
-static void
+static int
 tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct pmd_internals *pmd = dev->data->dev_private;
 	enum ioctl_mode mode = LOCAL_ONLY;
 	struct ifreq ifr;
+	int ret;
 
 	if (is_zero_ether_addr(mac_addr)) {
 		RTE_LOG(ERR, PMD, "%s: can't set an empty MAC address\n",
 			dev->device->name);
-		return;
+		return -EINVAL;
 	}
 	/* Check the actual current MAC address on the tap netdevice */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY);
+	if (ret < 0)
+		return ret;
 	if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
-		return;
+		return 0;
 	/* Check the current MAC address on the remote */
-	if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY);
+	if (ret < 0)
+		return ret;
 	if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
 			       mac_addr))
 		mode = LOCAL_AND_REMOTE;
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode) < 0)
-		return;
+	ret = tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, mode);
+	if (ret < 0)
+		return ret;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 	if (pmd->remote_if_index && !pmd->flow_isolate) {
 		/* Replace MAC redirection rule after a MAC change */
-		if (tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC) < 0) {
+		ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't delete MAC redirection rule\n",
 				dev->device->name);
-			return;
+			return ret;
 		}
-		if (tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC) < 0)
+		ret = tap_flow_implicit_create(pmd, TAP_REMOTE_LOCAL_MAC);
+		if (ret < 0) {
 			RTE_LOG(ERR, PMD,
 				"%s: Couldn't add MAC redirection rule\n",
 				dev->device->name);
+			return ret;
+		}
 	}
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index d7c81747e..623329998 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -67,7 +67,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr,
 				uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
 				struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -1056,7 +1056,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 	virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
@@ -1072,9 +1072,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 		ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
 		memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-		virtio_send_command(hw->cvq, &ctrl, &len, 1);
-	} else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-		virtio_set_hwaddr(hw);
+		return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+	}
+
+	if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+		return -ENOTSUP;
+
+	virtio_set_hwaddr(hw);
+	return 0;
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 01b4802e0..e5cbd7de6 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -72,7 +72,7 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
+static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
 				 struct ether_addr *mac_addr);
 static void vmxnet3_interrupt_handler(void *param);
 
@@ -1076,13 +1076,14 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
+static int
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 
 	ether_addr_copy(mac_addr, (struct ether_addr *)(hw->perm_addr));
 	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
+	return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 78b788b31..e6bc0da7b 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3034,6 +3034,7 @@ int
 rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 {
 	struct rte_eth_dev *dev;
+	int ret;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -3043,11 +3044,13 @@ rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
 	dev = &rte_eth_devices[port_id];
 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set, -ENOTSUP);
 
+	ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+	if (ret < 0)
+		return ret;
+
 	/* Update default address in NIC data structure */
 	ether_addr_copy(addr, &dev->data->mac_addrs[0]);
 
-	(*dev->dev_ops->mac_addr_set)(dev, addr);
-
 	return 0;
 }
 
diff --git a/lib/librte_ether/rte_ethdev_core.h b/lib/librte_ether/rte_ethdev_core.h
index e5681e466..55eb2b09e 100644
--- a/lib/librte_ether/rte_ethdev_core.h
+++ b/lib/librte_ether/rte_ethdev_core.h
@@ -255,7 +255,7 @@ typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
 				  uint32_t vmdq);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
-typedef void (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
 				  struct ether_addr *mac_addr);
 /**< @internal Set a MAC address into Receive Address Address Register */
 
diff --git a/test/test/virtual_pmd.c b/test/test/virtual_pmd.c
index 2f5b31dba..69b4ba034 100644
--- a/test/test/virtual_pmd.c
+++ b/test/test/virtual_pmd.c
@@ -216,10 +216,11 @@ static void
 virtual_ethdev_promiscuous_mode_disable(struct rte_eth_dev *dev __rte_unused)
 {}
 
-static void
+static int
 virtual_ethdev_mac_address_set(__rte_unused struct rte_eth_dev *dev,
 			       __rte_unused struct ether_addr *addr)
 {
+	return 0;
 }
 
 static const struct eth_dev_ops virtual_ethdev_default_dev_ops = {
-- 
2.11.0

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [dpdk-dev] [PATCH v4] ethdev: return diagnostic when setting MAC address
  2018-04-11 16:32     ` [dpdk-dev] [PATCH v4] " Olivier Matz
@ 2018-04-11 19:30       ` Ferruh Yigit
  0 siblings, 0 replies; 21+ messages in thread
From: Ferruh Yigit @ 2018-04-11 19:30 UTC (permalink / raw)
  To: Olivier Matz, dev
  Cc: Thomas Monjalon, Tomasz Duszynski, Andrew Rybchenko,
	Adrien Mazarguil, Shreyansh Jain, Nelio Laranjeiro, Ivan Malov

On 4/11/2018 5:32 PM, Olivier Matz wrote:
> Change the prototype and the behavior of dev_ops->eth_mac_addr_set(): a
> return code is added to notify the caller (librte_ether) if an error
> occurred in the PMD.
> 
> The new default MAC address is now copied in dev->data->mac_addrs[0]
> only if the operation is successful.
> 
> The patch also updates all the PMDs accordingly.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>

Applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2018-04-11 19:30 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-27 15:11 [dpdk-dev] [PATCH] ethdev: return diagnostic when setting MAC address Olivier Matz
2018-03-05 10:29 ` Adrien Mazarguil
2018-03-06  9:37 ` Tomasz Duszynski
2018-03-16 15:41 ` Andrew Rybchenko
2018-03-26 18:39 ` Ferruh Yigit
2018-03-28  8:24   ` Olivier Matz
2018-04-03 12:41 ` [dpdk-dev] [PATCH v2] " Olivier Matz
2018-04-03 13:02   ` Andrew Rybchenko
2018-04-03 14:57   ` Adrien Mazarguil
2018-04-03 16:26     ` Olivier Matz
2018-04-03 16:19   ` Ferruh Yigit
2018-04-03 16:25     ` Olivier Matz
2018-04-04  8:19   ` Shreyansh Jain
2018-04-06 15:21   ` [dpdk-dev] [PATCH] " Olivier Matz
2018-04-06 15:34     ` Olivier Matz
2018-04-09  8:57     ` Nélio Laranjeiro
2018-04-06 15:34   ` [dpdk-dev] [PATCH v3] " Olivier Matz
2018-04-06 16:03     ` Ferruh Yigit
2018-04-10 13:19       ` Thomas Monjalon
2018-04-11 16:32     ` [dpdk-dev] [PATCH v4] " Olivier Matz
2018-04-11 19:30       ` Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).