ethdev: return diagnostic when setting MAC address
authorOlivier Matz <olivier.matz@6wind.com>
Wed, 11 Apr 2018 16:32:51 +0000 (18:32 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 13 Apr 2018 22:43:30 +0000 (00:43 +0200)
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>
31 files changed:
doc/guides/rel_notes/deprecation.rst
drivers/net/ark/ark_ethdev.c
drivers/net/avf/avf_ethdev.c
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bonding/rte_eth_bond_pmd.c
drivers/net/cxgbe/cxgbe_ethdev.c
drivers/net/cxgbe/cxgbe_pfvf.h
drivers/net/dpaa/dpaa_ethdev.c
drivers/net/dpaa2/dpaa2_ethdev.c
drivers/net/e1000/em_ethdev.c
drivers/net/e1000/igb_ethdev.c
drivers/net/failsafe/failsafe_ops.c
drivers/net/i40e/i40e_ethdev.c
drivers/net/i40e/i40e_ethdev_vf.c
drivers/net/ixgbe/ixgbe_ethdev.c
drivers/net/mlx4/mlx4.h
drivers/net/mlx4/mlx4_ethdev.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_mac.c
drivers/net/mvpp2/mrvl_ethdev.c
drivers/net/null/rte_eth_null.c
drivers/net/octeontx/octeontx_ethdev.c
drivers/net/qede/qede_ethdev.c
drivers/net/sfc/sfc_ethdev.c
drivers/net/szedata2/rte_eth_szedata2.c
drivers/net/tap/rte_eth_tap.c
drivers/net/virtio/virtio_ethdev.c
drivers/net/vmxnet3/vmxnet3_ethdev.c
lib/librte_ether/rte_ethdev.c
lib/librte_ether/rte_ethdev_core.h
test/test/virtual_pmd.c

index 16eb328..fd9def2 100644 (file)
@@ -100,14 +100,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
index c9d5419..d275ab7 100644 (file)
@@ -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
index 5409130..a1ae3a2 100644 (file)
@@ -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
index 54348de..a856c7e 100644 (file)
@@ -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
index 2ba1055..8847d20 100644 (file)
@@ -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 = {
index 24c9a93..3df51b5 100644 (file)
@@ -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 = {
index 0c1c170..2bba974 100644 (file)
@@ -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,
index 581e3a0..9242f5a 100644 (file)
@@ -816,7 +816,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)
 {
@@ -828,6 +828,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 = {
index 146566e..4225339 100644 (file)
@@ -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
index 9d089cf..de7db26 100644 (file)
@@ -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
index 8723571..9b808a9 100644 (file)
@@ -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;
 }
 
 
index 2bdadd5..61cff9e 100644 (file)
@@ -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
index 359026f..180ac74 100644 (file)
@@ -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
index f6d7f40..031c706 100644 (file)
@@ -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
index cd5894f..a5e2fc0 100644 (file)
@@ -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);
@@ -4785,14 +4785,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
@@ -5941,12 +5942,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
index d656a68..4584655 100644 (file)
@@ -132,7 +132,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);
index 09e24b2..d1b71c8 100644 (file)
@@ -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);
 }
 
 /**
index 6e7e3c6..6ad4139 100644 (file)
@@ -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 */
 
index 0fb4a3e..edc7a32 100644 (file)
@@ -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);
 }
index 6ab515c..d787154 100644 (file)
@@ -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;
 }
 
 /**
index 73fe8b0..74dde95 100644 (file)
@@ -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 = {
index f829e0c..6d67d25 100644 (file)
@@ -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
index 13c2a3b..1202300 100644 (file)
@@ -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)
index 6631c5a..47d7a86 100644 (file)
@@ -914,13 +914,14 @@ fail_inval:
        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;
 }
 
 
index 41a6fb4..824debb 100644 (file)
@@ -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
index 54c7c2b..915d937 100644 (file)
@@ -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
index da022e9..41042cb 100644 (file)
@@ -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
index 93d9de1..011e262 100644 (file)
@@ -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);
 
@@ -1077,13 +1077,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 */
index a023b3e..3c049ef 100644 (file)
@@ -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;
 }
 
index e5681e4..55eb2b0 100644 (file)
@@ -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 */
 
index 2f5b31d..69b4ba0 100644 (file)
@@ -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 = {