patches for DPDK stable branches
 help / color / mirror / Atom feed
From: "Wei Hu (Xavier)" <huwei013@chinasoftinc.com>
To: <stable@dpdk.org>, <bluca@debian.org>
Cc: <xavier.huwei@huawei.com>
Subject: [dpdk-stable] [PATCH v2 05/10] net/hns3: fix adding multicast MAC address
Date: Tue, 18 Aug 2020 14:49:26 +0800	[thread overview]
Message-ID: <20200818064931.46414-6-huwei013@chinasoftinc.com> (raw)
In-Reply-To: <20200818064931.46414-1-huwei013@chinasoftinc.com>

From: Chengchang Tang <tangchengchang@huawei.com>

[ upstream commit fb94f359481ff6d53f6b7850d3ad393addfb6afb ]

Currently, when upper application calls the rte_eth_dev_mac_addr_add API
function to add a MC mac address based on hns3 PF/VF device, it will
fail.

In hns3 network engine adding UC and MC mac address with different
commands with firmware. We need to determine whether the input address
is a UC or a MC address to call different commands in the
'.mac_addr_add' and '.mac_addr_remove' ops implementation functions in
hns3 PF and VF driver as below:
  hns3_add_mac_addr
  hns3vf_add_uc_mac_addr
  hns3_remove_mac_addr
  hns3vf_remove_mac_addr

By the way, it is recommended calling the rte_eth_dev_set_mc_addr_list API
function to set the MC mac address, because using the
rte_eth_dev_mac_addr_add API function to set MC mac address may affect the
specifications of UC mac addresses.

Fixes: 7d7f9f80bbfb ("net/hns3: support MAC address related operations")
Cc: stable@dpdk.org

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c    | 133 ++++++++++++++---
 drivers/net/hns3/hns3_ethdev_vf.c | 231 +++++++++++++++++++++++-------
 2 files changed, 295 insertions(+), 69 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 128cd793d..217aea4c0 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -77,6 +77,11 @@ static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
 				    int on);
 static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
 
+static int hns3_add_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+static int hns3_remove_mc_addr(struct hns3_hw *hw,
+			    struct rte_ether_addr *mac_addr);
+
 static void
 hns3_pf_disable_irq0(struct hns3_hw *hw)
 {
@@ -1459,6 +1464,53 @@ hns3_add_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	return ret;
 }
 
+static int
+hns3_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3_add_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3_remove_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_remove_mc_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to remove mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		  uint32_t idx, __attribute__ ((unused)) uint32_t pool)
@@ -1468,12 +1520,27 @@ hns3_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_add_uc_addr_common(hw, mac_addr);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_add_uc_addr_common(hw, mac_addr);
+
 	if (ret) {
 		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
+			 ret);
 		return ret;
 	}
 
@@ -1495,7 +1562,7 @@ hns3_remove_uc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Remove unicast mac addr err! addr(%s) invalid",
+		hns3_err(hw, "remove unicast mac addr err! addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1522,16 +1589,18 @@ hns3_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_remove_uc_addr_common(hw, mac_addr);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3_remove_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3_remove_uc_addr_common(hw, mac_addr);
+	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
-		rte_spinlock_unlock(&hw->lock);
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s): %d", mac_str, ret);
-		return;
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d", mac_str,
+			 ret);
 	}
-
-	rte_spinlock_unlock(&hw->lock);
 }
 
 static int
@@ -1632,19 +1701,22 @@ hns3_configure_all_mac_addr(struct hns3_adapter *hns, bool del)
 
 	for (i = 0; i < HNS3_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		if (del)
-			ret = hns3_remove_uc_addr_common(hw, addr);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3_remove_mc_addr(hw, addr) :
+			      hns3_add_mc_addr(hw, addr);
 		else
-			ret = hns3_add_uc_addr_common(hw, addr);
+			ret = del ? hns3_remove_uc_addr_common(hw, addr) :
+			      hns3_add_uc_addr_common(hw, addr);
+
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
-			hns3_dbg(hw,
-				 "Failed to %s mac addr(%s). ret:%d i:%d",
-				 del ? "remove" : "restore", mac_str, ret, i);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
 	return err;
@@ -1691,7 +1763,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 	if (!rte_is_multicast_ether_addr(mac_addr)) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr, addr(%s) invalid",
+		hns3_err(hw, "failed to add mc mac addr, addr(%s) invalid",
 			 mac_str);
 		return -EINVAL;
 	}
@@ -1720,7 +1792,7 @@ hns3_add_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
 			hns3_err(hw, "mc mac vlan table is full");
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mc mac addr(%s): %d", mac_str, ret);
+		hns3_err(hw, "failed to add mc mac addr(%s): %d", mac_str, ret);
 	}
 
 	return ret;
@@ -1785,7 +1857,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
@@ -1798,7 +1870,7 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
@@ -1809,12 +1881,30 @@ hns3_set_mc_addr_chk_param(struct hns3_hw *hw,
 				rte_ether_format_addr(mac_str,
 						      RTE_ETHER_ADDR_FMT_SIZE,
 						      addr);
-				hns3_err(hw, "Failed to set mc mac addr, "
+				hns3_err(hw, "failed to set mc mac addr, "
 					 "addrs invalid. two same addrs(%s).",
 					 mac_str);
 				return -EINVAL;
 			}
 		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
 
 	return 0;
@@ -3597,6 +3687,7 @@ hns3_get_mac_ethertype_cmd_status(uint16_t cmdq_resp, uint8_t resp_code)
 			     "add mac ethertype failed for undefined, code=%d.",
 			     resp_code);
 		return_status = -EIO;
+		break;
 	}
 
 	return return_status;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 63fca0197..b929fbcc8 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -59,6 +59,10 @@ static enum hns3_reset_level hns3vf_get_reset_level(struct hns3_hw *hw,
 static int hns3vf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int hns3vf_dev_configure_vlan(struct rte_eth_dev *dev);
 
+static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
+				  struct rte_ether_addr *mac_addr);
+static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
+				     struct rte_ether_addr *mac_addr);
 /* set PCI bus mastering */
 static void
 hns3vf_set_bus_master(const struct rte_pci_device *device, bool op)
@@ -134,6 +138,76 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op)
 	return -1;
 }
 
+static int
+hns3vf_add_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
+				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_remove_uc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	/* mac address was checked by upper level interface */
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	int ret;
+
+	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
+				HNS3_MBX_MAC_VLAN_UC_REMOVE,
+				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN,
+				false, NULL, 0);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add uc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
+static int
+hns3vf_add_mc_addr_common(struct hns3_hw *hw, struct rte_ether_addr *mac_addr)
+{
+	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
+	struct rte_ether_addr *addr;
+	int ret;
+	int i;
+
+	for (i = 0; i < hw->mc_addrs_num; i++) {
+		addr = &hw->mc_addrs[i];
+		/* Check if there are duplicate addresses */
+		if (rte_is_same_ether_addr(addr, mac_addr)) {
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to add mc mac addr, same addrs"
+				 "(%s) is added by the set_mc_mac_addr_list "
+				 "API", mac_str);
+			return -EINVAL;
+		}
+	}
+
+	ret = hns3vf_add_mc_mac_addr(hw, mac_addr);
+	if (ret) {
+		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+				      mac_addr);
+		hns3_err(hw, "failed to add mc mac addr(%s), ret = %d",
+			 mac_str, ret);
+	}
+	return ret;
+}
+
 static int
 hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 		    __attribute__ ((unused)) uint32_t idx,
@@ -144,14 +218,26 @@ hns3vf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_ADD, mac_addr->addr_bytes,
-				RTE_ETHER_ADDR_LEN, false, NULL, 0);
+
+	/*
+	 * In hns3 network engine adding UC and MC mac address with different
+	 * commands with firmware. We need to determine whether the input
+	 * address is a UC or a MC address to call different commands.
+	 * By the way, it is recommended calling the API function named
+	 * rte_eth_dev_set_mc_addr_list to set the MC mac address, because
+	 * using the rte_eth_dev_mac_addr_add API function to set MC mac address
+	 * may affect the specifications of UC mac addresses.
+	 */
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_add_mc_addr_common(hw, mac_addr);
+	else
+		ret = hns3vf_add_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to add mac addr(%s) for vf: %d", mac_str,
+		hns3_err(hw, "failed to add mac addr(%s), ret = %d", mac_str,
 			 ret);
 	}
 
@@ -168,15 +254,17 @@ hns3vf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t idx)
 	int ret;
 
 	rte_spinlock_lock(&hw->lock);
-	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST,
-				HNS3_MBX_MAC_VLAN_UC_REMOVE,
-				mac_addr->addr_bytes, RTE_ETHER_ADDR_LEN, false,
-				NULL, 0);
+
+	if (rte_is_multicast_ether_addr(mac_addr))
+		ret = hns3vf_remove_mc_mac_addr(hw, mac_addr);
+	else
+		ret = hns3vf_remove_uc_mac_addr(hw, mac_addr);
+
 	rte_spinlock_unlock(&hw->lock);
 	if (ret) {
 		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 				      mac_addr);
-		hns3_err(hw, "Failed to remove mac addr(%s) for vf: %d",
+		hns3_err(hw, "failed to remove mac addr(%s), ret = %d",
 			 mac_str, ret);
 	}
 }
@@ -228,39 +316,39 @@ hns3vf_configure_mac_addr(struct hns3_adapter *hns, bool del)
 {
 	struct hns3_hw *hw = &hns->hw;
 	struct rte_ether_addr *addr;
-	enum hns3_mbx_mac_vlan_subcode opcode;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int ret = 0;
+	int err = 0;
+	int ret;
 	int i;
 
-	if (del)
-		opcode = HNS3_MBX_MAC_VLAN_UC_REMOVE;
-	else
-		opcode = HNS3_MBX_MAC_VLAN_UC_ADD;
 	for (i = 0; i < HNS3_VF_UC_MACADDR_NUM; i++) {
 		addr = &hw->data->mac_addrs[i];
-		if (!rte_is_valid_assigned_ether_addr(addr))
+		if (rte_is_zero_ether_addr(addr))
 			continue;
-		rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE, addr);
-		hns3_dbg(hw, "rm mac addr: %s", mac_str);
-		ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_UNICAST, opcode,
-					addr->addr_bytes, RTE_ETHER_ADDR_LEN,
-					false, NULL, 0);
+		if (rte_is_multicast_ether_addr(addr))
+			ret = del ? hns3vf_remove_mc_mac_addr(hw, addr) :
+			      hns3vf_add_mc_mac_addr(hw, addr);
+		else
+			ret = del ? hns3vf_remove_uc_mac_addr(hw, addr) :
+			      hns3vf_add_uc_mac_addr(hw, addr);
+
 		if (ret) {
-			hns3_err(hw, "Failed to remove mac addr for vf: %d",
-				 ret);
-			break;
+			err = ret;
+			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
+					      addr);
+			hns3_err(hw, "failed to %s mac addr(%s) index:%d "
+				 "ret = %d.", del ? "remove" : "restore",
+				 mac_str, i, ret);
 		}
 	}
-	return ret;
+	return err;
 }
 
 static int
-hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_add_mc_mac_addr(struct hns3_hw *hw,
 		       struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -279,11 +367,10 @@ hns3vf_add_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
+hns3vf_remove_mc_mac_addr(struct hns3_hw *hw,
 			  struct rte_ether_addr *mac_addr)
 {
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	struct hns3_hw *hw = &hns->hw;
 	int ret;
 
 	ret = hns3_send_mbx_msg(hw, HNS3_MBX_SET_MULTICAST,
@@ -302,45 +389,92 @@ hns3vf_remove_mc_mac_addr(struct hns3_adapter *hns,
 }
 
 static int
-hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
-			    struct rte_ether_addr *mc_addr_set,
-			    uint32_t nb_mc_addr)
+hns3vf_set_mc_addr_chk_param(struct hns3_hw *hw,
+			     struct rte_ether_addr *mc_addr_set,
+			     uint32_t nb_mc_addr)
 {
-	struct hns3_adapter *hns = dev->data->dev_private;
-	struct hns3_hw *hw = &hns->hw;
-	struct rte_ether_addr *addr;
 	char mac_str[RTE_ETHER_ADDR_FMT_SIZE];
-	int cur_addr_num;
-	int set_addr_num;
-	int num;
-	int ret;
-	int i;
+	struct rte_ether_addr *addr;
+	uint32_t i;
+	uint32_t j;
 
 	if (nb_mc_addr > HNS3_MC_MACADDR_NUM) {
-		hns3_err(hw, "Failed to set mc mac addr, nb_mc_addr(%d) "
+		hns3_err(hw, "failed to set mc mac addr, nb_mc_addr(%d) "
 			 "invalid. valid range: 0~%d",
 			 nb_mc_addr, HNS3_MC_MACADDR_NUM);
 		return -EINVAL;
 	}
 
-	set_addr_num = (int)nb_mc_addr;
-	for (i = 0; i < set_addr_num; i++) {
+	/* Check if input mac addresses are valid */
+	for (i = 0; i < nb_mc_addr; i++) {
 		addr = &mc_addr_set[i];
 		if (!rte_is_multicast_ether_addr(addr)) {
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
 					      addr);
 			hns3_err(hw,
-				 "Failed to set mc mac addr, addr(%s) invalid.",
+				 "failed to set mc mac addr, addr(%s) invalid.",
 				 mac_str);
 			return -EINVAL;
 		}
+
+		/* Check if there are duplicate addresses */
+		for (j = i + 1; j < nb_mc_addr; j++) {
+			if (rte_is_same_ether_addr(addr, &mc_addr_set[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. two same addrs(%s).",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * Check if there are duplicate addresses between mac_addrs
+		 * and mc_addr_set
+		 */
+		for (j = 0; j < HNS3_VF_UC_MACADDR_NUM; j++) {
+			if (rte_is_same_ether_addr(addr,
+						   &hw->data->mac_addrs[j])) {
+				rte_ether_format_addr(mac_str,
+						      RTE_ETHER_ADDR_FMT_SIZE,
+						      addr);
+				hns3_err(hw, "failed to set mc mac addr, "
+					 "addrs invalid. addrs(%s) has already "
+					 "configured in mac_addr add API",
+					 mac_str);
+				return -EINVAL;
+			}
+		}
 	}
+
+	return 0;
+}
+
+static int
+hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mc_addr_set,
+			    uint32_t nb_mc_addr)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_ether_addr *addr;
+	int cur_addr_num;
+	int set_addr_num;
+	int num;
+	int ret;
+	int i;
+
+	ret = hns3vf_set_mc_addr_chk_param(hw, mc_addr_set, nb_mc_addr);
+	if (ret)
+		return ret;
+
 	rte_spinlock_lock(&hw->lock);
 	cur_addr_num = hw->mc_addrs_num;
 	for (i = 0; i < cur_addr_num; i++) {
 		num = cur_addr_num - i - 1;
 		addr = &hw->mc_addrs[num];
-		ret = hns3vf_remove_mc_mac_addr(hns, addr);
+		ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -349,9 +483,10 @@ hns3vf_set_mc_mac_addr_list(struct rte_eth_dev *dev,
 		hw->mc_addrs_num--;
 	}
 
+	set_addr_num = (int)nb_mc_addr;
 	for (i = 0; i < set_addr_num; i++) {
 		addr = &mc_addr_set[i];
-		ret = hns3vf_add_mc_mac_addr(hns, addr);
+		ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			rte_spinlock_unlock(&hw->lock);
 			return ret;
@@ -380,9 +515,9 @@ hns3vf_configure_all_mc_mac_addr(struct hns3_adapter *hns, bool del)
 		if (!rte_is_multicast_ether_addr(addr))
 			continue;
 		if (del)
-			ret = hns3vf_remove_mc_mac_addr(hns, addr);
+			ret = hns3vf_remove_mc_mac_addr(hw, addr);
 		else
-			ret = hns3vf_add_mc_mac_addr(hns, addr);
+			ret = hns3vf_add_mc_mac_addr(hw, addr);
 		if (ret) {
 			err = ret;
 			rte_ether_format_addr(mac_str, RTE_ETHER_ADDR_FMT_SIZE,
-- 
2.27.0


  parent reply	other threads:[~2020-08-18  6:50 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-17  9:25 [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 01/24] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 02/24] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 03/24] net/hns3: support setting VF MAC address by PF driver Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 04/24] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 05/24] net/hns3: support TSO Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 06/24] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 07/24] net/hns3: support promiscuous and allmulticast mode for VF Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 08/24] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 09/24] net/hns3: get Rx/Tx queue fbd in xstats Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 10/24] net/hns3: get Tx abnormal errors " Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 11/24] net/hns3: get PCI revision ID Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 12/24] net/hns3: check TSO segment size during Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 13/24] net/hns3: support symmetric RSS Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 14/24] net/hns3: support LRO Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 15/24] net/hns3: decrease non-nearby memory access in Rx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 16/24] net/hns3: support setting VF PVID by PF driver Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 17/24] net/hns3: get device capability in primary process Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 18/24] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 19/24] net/hns3: cleanup duplicated code on processing TSO in Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 20/24] net/hns3: support copper media type Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 21/24] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 22/24] net/hns3: fix inserted VLAN tag position " Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 23/24] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-17  9:25 ` [dpdk-stable] [PATCH 24/24] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-17  9:51 ` [dpdk-stable] [PATCH 00/24] backport for 19.11.4 Luca Boccassi
2020-08-17 11:54   ` Wei Hu (Xavier)
2020-08-17 13:42     ` Luca Boccassi
2020-08-18  3:25       ` Wei Hu (Xavier)
2020-08-18  6:49 ` [dpdk-stable] [PATCH v2 00/10] " Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 01/10] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 02/10] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 03/10] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 04/10] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-18  6:49   ` Wei Hu (Xavier) [this message]
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 06/10] net/hns3: get device capability in primary process Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 07/10] net/hns3: report Tx descriptor segment limitations Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 08/10] net/hns3: fix reassembling multiple segment packets in Tx Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 09/10] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-18  6:49   ` [dpdk-stable] [PATCH v2 10/10] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-18  7:15 ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 1/7] net/hns3: get link status change through mailbox Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 2/7] net/hns3: optimize default RSS algorithm Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 3/7] net/hns3: remove unnecessary branch Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 4/7] net/hns3: remove restriction on setting VF MTU Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 5/7] net/hns3: fix adding multicast MAC address Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 6/7] app/testpmd: remove hardcoded descriptors limit Wei Hu (Xavier)
2020-08-18  7:15   ` [dpdk-stable] [PATCH v3 7/7] net/bonding: change state machine to defaulted Wei Hu (Xavier)
2020-08-18 18:00   ` [dpdk-stable] [PATCH v3 0/7] backport for 19.11.4 Luca Boccassi

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20200818064931.46414-6-huwei013@chinasoftinc.com \
    --to=huwei013@chinasoftinc.com \
    --cc=bluca@debian.org \
    --cc=stable@dpdk.org \
    --cc=xavier.huwei@huawei.com \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).