[dpdk-dev] [PATCH v2 2/7] net/qede: fix filtering code

Harish Patil harish.patil at qlogic.com
Fri Dec 23 01:48:06 CET 2016


In qede_mac_addr_add() a check is added to differentiate between
unicast/multicast mac to prevent a multicast mac from being wrongly added
to unicast filter table. Secondly, two separate lists will be used to keep
track of unicast/multicast mac filters to prevent duplicate filter
programming. The other change is to remove filter_config from struct
qed_eth_ops_pass and invoke the base APIs directly. This avoids the need
to have multiple structs and function calls.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil at qlogic.com>
---
 drivers/net/qede/qede_eth_if.c |  101 +-------------
 drivers/net/qede/qede_eth_if.h |   36 +----
 drivers/net/qede/qede_ethdev.c |  303 ++++++++++++++++++++++++++++------------
 drivers/net/qede/qede_ethdev.h |   15 ++
 4 files changed, 230 insertions(+), 225 deletions(-)

diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index 1ae6127..30fded0 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -310,86 +310,11 @@ qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
 	ecore_get_vport_stats(edev, stats);
 }
 
-static int
-qed_configure_filter_ucast(struct ecore_dev *edev,
-			   struct qed_filter_ucast_params *params)
-{
-	struct ecore_filter_ucast ucast;
-
-	if (!params->vlan_valid && !params->mac_valid) {
-		DP_NOTICE(edev, true,
-			  "Tried configuring a unicast filter,"
-			  "but both MAC and VLAN are not set\n");
-		return -EINVAL;
-	}
-
-	memset(&ucast, 0, sizeof(ucast));
-	switch (params->type) {
-	case QED_FILTER_XCAST_TYPE_ADD:
-		ucast.opcode = ECORE_FILTER_ADD;
-		break;
-	case QED_FILTER_XCAST_TYPE_DEL:
-		ucast.opcode = ECORE_FILTER_REMOVE;
-		break;
-	case QED_FILTER_XCAST_TYPE_REPLACE:
-		ucast.opcode = ECORE_FILTER_REPLACE;
-		break;
-	default:
-		DP_NOTICE(edev, true, "Unknown unicast filter type %d\n",
-			  params->type);
-	}
-
-	if (params->vlan_valid && params->mac_valid) {
-		ucast.type = ECORE_FILTER_MAC_VLAN;
-		ether_addr_copy((struct ether_addr *)&params->mac,
-				(struct ether_addr *)&ucast.mac);
-		ucast.vlan = params->vlan;
-	} else if (params->mac_valid) {
-		ucast.type = ECORE_FILTER_MAC;
-		ether_addr_copy((struct ether_addr *)&params->mac,
-				(struct ether_addr *)&ucast.mac);
-	} else {
-		ucast.type = ECORE_FILTER_VLAN;
-		ucast.vlan = params->vlan;
-	}
-
-	ucast.is_rx_filter = true;
-	ucast.is_tx_filter = true;
-
-	return ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
-}
-
-static int
-qed_configure_filter_mcast(struct ecore_dev *edev,
-			   struct qed_filter_mcast_params *params)
-{
-	struct ecore_filter_mcast mcast;
-	int i;
-
-	memset(&mcast, 0, sizeof(mcast));
-	switch (params->type) {
-	case QED_FILTER_XCAST_TYPE_ADD:
-		mcast.opcode = ECORE_FILTER_ADD;
-		break;
-	case QED_FILTER_XCAST_TYPE_DEL:
-		mcast.opcode = ECORE_FILTER_REMOVE;
-		break;
-	default:
-		DP_NOTICE(edev, true, "Unknown multicast filter type %d\n",
-			  params->type);
-	}
-
-	mcast.num_mc_addrs = params->num;
-	for (i = 0; i < mcast.num_mc_addrs; i++)
-		ether_addr_copy((struct ether_addr *)&params->mac[i],
-				(struct ether_addr *)&mcast.mac[i]);
-
-	return ecore_filter_mcast_cmd(edev, &mcast, ECORE_SPQ_MODE_CB, NULL);
-}
-
-int qed_configure_filter_rx_mode(struct ecore_dev *edev,
+int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
 				 enum qed_filter_rx_mode_type type)
 {
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	struct ecore_filter_accept_flags flags;
 
 	memset(&flags, 0, sizeof(flags));
@@ -422,25 +347,6 @@ int qed_configure_filter_rx_mode(struct ecore_dev *edev,
 				       ECORE_SPQ_MODE_CB, NULL);
 }
 
-static int
-qed_configure_filter(struct ecore_dev *edev, struct qed_filter_params *params)
-{
-	switch (params->type) {
-	case QED_FILTER_TYPE_UCAST:
-		return qed_configure_filter_ucast(edev, &params->filter.ucast);
-	case QED_FILTER_TYPE_MCAST:
-		return qed_configure_filter_mcast(edev, &params->filter.mcast);
-	case QED_FILTER_TYPE_RX_MODE:
-		return qed_configure_filter_rx_mode(edev,
-						    params->filter.
-						    accept_flags);
-	default:
-		DP_NOTICE(edev, true, "Unknown filter type %d\n",
-			  (int)params->type);
-		return -EINVAL;
-	}
-}
-
 static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
 	INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
@@ -455,7 +361,6 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
 	INIT_STRUCT_FIELD(fastpath_start, &qed_fastpath_start),
 	INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
-	INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
 };
 
 const struct qed_eth_ops *qed_get_eth_ops(void)
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 33655c3..9c0db87 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -26,12 +26,6 @@ enum qed_filter_rx_mode_type {
 	QED_FILTER_RX_MODE_TYPE_PROMISC,
 };
 
-enum qed_filter_xcast_params_type {
-	QED_FILTER_XCAST_TYPE_ADD,
-	QED_FILTER_XCAST_TYPE_DEL,
-	QED_FILTER_XCAST_TYPE_REPLACE,
-};
-
 enum qed_filter_type {
 	QED_FILTER_TYPE_UCAST,
 	QED_FILTER_TYPE_MCAST,
@@ -93,31 +87,6 @@ struct qed_stop_txq_params {
 	uint8_t tx_queue_id;
 };
 
-struct qed_filter_ucast_params {
-	enum qed_filter_xcast_params_type type;
-	uint8_t vlan_valid;
-	uint16_t vlan;
-	uint8_t mac_valid;
-	unsigned char mac[ETHER_ADDR_LEN];
-};
-
-struct qed_filter_mcast_params {
-	enum qed_filter_xcast_params_type type;
-	uint8_t num;
-	unsigned char mac[QEDE_MAX_MCAST_FILTERS][ETHER_ADDR_LEN];
-};
-
-union qed_filter_type_params {
-	enum qed_filter_rx_mode_type accept_flags;
-	struct qed_filter_ucast_params ucast;
-	struct qed_filter_mcast_params mcast;
-};
-
-struct qed_filter_params {
-	enum qed_filter_type type;
-	union qed_filter_type_params filter;
-};
-
 struct qed_eth_ops {
 	const struct qed_common_ops *common;
 
@@ -162,9 +131,6 @@ struct qed_eth_ops {
 
 	void (*get_vport_stats)(struct ecore_dev *edev,
 				struct ecore_eth_stats *stats);
-
-	int (*filter_config)(struct ecore_dev *edev,
-			     struct qed_filter_params *params);
 };
 
 /* externs */
@@ -173,7 +139,7 @@ extern const struct qed_common_ops qed_common_ops_pass;
 
 const struct qed_eth_ops *qed_get_eth_ops();
 
-int qed_configure_filter_rx_mode(struct ecore_dev *edev,
+int qed_configure_filter_rx_mode(struct rte_eth_dev *eth_dev,
 				 enum qed_filter_rx_mode_type type);
 
 #endif /* _QEDE_ETH_IF_H */
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 4943358..73f1824 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -222,47 +222,181 @@ static void qede_print_adapter_info(struct qede_dev *qdev)
 	DP_INFO(edev, "*********************************\n");
 }
 
+static void qede_set_ucast_cmn_params(struct ecore_filter_ucast *ucast)
+{
+	memset(ucast, 0, sizeof(struct ecore_filter_ucast));
+	ucast->is_rx_filter = true;
+	ucast->is_tx_filter = true;
+	/* ucast->assert_on_error = true; - For debug */
+}
+
 static int
-qede_set_ucast_rx_mac(struct qede_dev *qdev,
-		      enum qed_filter_xcast_params_type opcode,
-		      uint8_t mac[ETHER_ADDR_LEN])
+qede_ucast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
+		  bool add)
 {
-	struct ecore_dev *edev = &qdev->edev;
-	struct qed_filter_params filter_cmd;
-
-	memset(&filter_cmd, 0, sizeof(filter_cmd));
-	filter_cmd.type = QED_FILTER_TYPE_UCAST;
-	filter_cmd.filter.ucast.type = opcode;
-	filter_cmd.filter.ucast.mac_valid = 1;
-	rte_memcpy(&filter_cmd.filter.ucast.mac[0], &mac[0], ETHER_ADDR_LEN);
-	return qdev->ops->filter_config(edev, &filter_cmd);
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct qede_ucast_entry *tmp = NULL;
+	struct qede_ucast_entry *u;
+	struct ether_addr *mac_addr;
+
+	mac_addr  = (struct ether_addr *)ucast->mac;
+	if (add) {
+		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
+			if ((memcmp(mac_addr, &tmp->mac,
+				    ETHER_ADDR_LEN) == 0) &&
+			     ucast->vlan == tmp->vlan) {
+				DP_ERR(edev, "Unicast MAC is already added"
+				       " with vlan = %u, vni = %u\n",
+				       ucast->vlan,  ucast->vni);
+					return -EEXIST;
+			}
+		}
+		u = rte_malloc(NULL, sizeof(struct qede_ucast_entry),
+			       RTE_CACHE_LINE_SIZE);
+		if (!u) {
+			DP_ERR(edev, "Did not allocate memory for ucast\n");
+			return -ENOMEM;
+		}
+		ether_addr_copy(mac_addr, &u->mac);
+		u->vlan = ucast->vlan;
+		SLIST_INSERT_HEAD(&qdev->uc_list_head, u, list);
+		qdev->num_uc_addr++;
+	} else {
+		SLIST_FOREACH(tmp, &qdev->uc_list_head, list) {
+			if ((memcmp(mac_addr, &tmp->mac,
+				    ETHER_ADDR_LEN) == 0) &&
+			    ucast->vlan == tmp->vlan)
+			break;
+		}
+		if (tmp == NULL) {
+			DP_INFO(edev, "Unicast MAC is not found\n");
+			return -EINVAL;
+		}
+		SLIST_REMOVE(&qdev->uc_list_head, tmp, qede_ucast_entry, list);
+		qdev->num_uc_addr--;
+	}
+
+	return 0;
 }
 
-static void
-qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
-		  uint32_t index, __rte_unused uint32_t pool)
+static int
+qede_mcast_filter(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *mcast,
+		  bool add)
 {
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	int rc;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ether_addr *mac_addr;
+	struct qede_mcast_entry *tmp = NULL;
+	struct qede_mcast_entry *m;
+
+	mac_addr  = (struct ether_addr *)mcast->mac;
+	if (add) {
+		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0) {
+				DP_ERR(edev,
+					"Multicast MAC is already added\n");
+				return -EEXIST;
+			}
+		}
+		m = rte_malloc(NULL, sizeof(struct qede_mcast_entry),
+			RTE_CACHE_LINE_SIZE);
+		if (!m) {
+			DP_ERR(edev,
+				"Did not allocate memory for mcast\n");
+			return -ENOMEM;
+		}
+		ether_addr_copy(mac_addr, &m->mac);
+		SLIST_INSERT_HEAD(&qdev->mc_list_head, m, list);
+		qdev->num_mc_addr++;
+	} else {
+		SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+			if (memcmp(mac_addr, &tmp->mac, ETHER_ADDR_LEN) == 0)
+				break;
+		}
+		if (tmp == NULL) {
+			DP_INFO(edev, "Multicast mac is not found\n");
+			return -EINVAL;
+		}
+		SLIST_REMOVE(&qdev->mc_list_head, tmp,
+			     qede_mcast_entry, list);
+		qdev->num_mc_addr--;
+	}
 
-	PMD_INIT_FUNC_TRACE(edev);
+	return 0;
+}
 
-	if (index >= qdev->dev_info.num_mac_addrs) {
-		DP_ERR(edev, "Index %u is above MAC filter limit %u\n",
-		       index, qdev->dev_info.num_mac_addrs);
-		return;
+static enum _ecore_status_t
+qede_mac_int_ops(struct rte_eth_dev *eth_dev, struct ecore_filter_ucast *ucast,
+		 bool add)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	enum _ecore_status_t rc;
+	struct ecore_filter_mcast mcast;
+	struct qede_mcast_entry *tmp;
+	uint16_t j = 0;
+
+	/* Multicast */
+	if (is_multicast_ether_addr((struct ether_addr *)ucast->mac)) {
+		if (add) {
+			if (qdev->num_mc_addr >= ECORE_MAX_MC_ADDRS) {
+				DP_ERR(edev,
+				       "Mcast filter table limit exceeded, "
+				       "Please enable mcast promisc mode\n");
+				return -ECORE_INVAL;
+			}
+		}
+		rc = qede_mcast_filter(eth_dev, ucast, add);
+		if (rc == 0) {
+			DP_INFO(edev, "num_mc_addrs = %u\n", qdev->num_mc_addr);
+			memset(&mcast, 0, sizeof(mcast));
+			mcast.num_mc_addrs = qdev->num_mc_addr;
+			mcast.opcode = ECORE_FILTER_ADD;
+			SLIST_FOREACH(tmp, &qdev->mc_list_head, list) {
+				ether_addr_copy(&tmp->mac,
+					(struct ether_addr *)&mcast.mac[j]);
+				j++;
+			}
+			rc = ecore_filter_mcast_cmd(edev, &mcast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		}
+		if (rc != ECORE_SUCCESS) {
+			DP_ERR(edev, "Failed to add multicast filter"
+			       " rc = %d, op = %d\n", rc, add);
+		}
+	} else { /* Unicast */
+		if (add) {
+			if (qdev->num_uc_addr >= qdev->dev_info.num_mac_addrs) {
+				DP_ERR(edev,
+				       "Ucast filter table limit exceeded,"
+				       " Please enable promisc mode\n");
+				return -ECORE_INVAL;
+			}
+		}
+		rc = qede_ucast_filter(eth_dev, ucast, add);
+		if (rc == 0)
+			rc = ecore_filter_ucast_cmd(edev, ucast,
+						    ECORE_SPQ_MODE_CB, NULL);
+		if (rc != ECORE_SUCCESS) {
+			DP_ERR(edev, "MAC filter failed, rc = %d, op = %d\n",
+			       rc, add);
+		}
 	}
 
-	/* Adding macaddr even though promiscuous mode is set */
-	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
-		DP_INFO(edev, "Port is in promisc mode, yet adding it\n");
+	return rc;
+}
 
-	/* Add MAC filters according to the unicast secondary macs */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_ADD,
-				   mac_addr->addr_bytes);
-	if (rc)
-		DP_ERR(edev, "Unable to add macaddr rc=%d\n", rc);
+static void
+qede_mac_addr_add(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr,
+		  uint32_t index, __rte_unused uint32_t pool)
+{
+	struct ecore_filter_ucast ucast;
+
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.type = ECORE_FILTER_MAC;
+	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
+	(void)qede_mac_int_ops(eth_dev, &ucast, 1);
 }
 
 static void
@@ -271,6 +405,7 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct ether_addr mac_addr;
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	PMD_INIT_FUNC_TRACE(edev);
@@ -281,12 +416,15 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
 		return;
 	}
 
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.opcode = ECORE_FILTER_REMOVE;
+	ucast.type = ECORE_FILTER_MAC;
+
 	/* Use the index maintained by rte */
-	ether_addr_copy(&eth_dev->data->mac_addrs[index], &mac_addr);
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_DEL,
-				   mac_addr.addr_bytes);
-	if (rc)
-		DP_ERR(edev, "Unable to remove macaddr rc=%d\n", rc);
+	ether_addr_copy(&eth_dev->data->mac_addrs[index],
+			(struct ether_addr *)&ucast.mac);
+
+	ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
 }
 
 static void
@@ -294,6 +432,7 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
@@ -305,10 +444,13 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	}
 
 	/* First remove the primary mac */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_DEL,
-				   qdev->primary_mac.addr_bytes);
-
-	if (rc) {
+	qede_set_ucast_cmn_params(&ucast);
+	ucast.opcode = ECORE_FILTER_REMOVE;
+	ucast.type = ECORE_FILTER_MAC;
+	ether_addr_copy(&qdev->primary_mac,
+			(struct ether_addr *)&ucast.mac);
+	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
+	if (rc != 0) {
 		DP_ERR(edev, "Unable to remove current macaddr"
 			     " Reverting to previous default mac\n");
 		ether_addr_copy(&qdev->primary_mac,
@@ -317,18 +459,15 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 	}
 
 	/* Add new MAC */
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_ADD,
-				   mac_addr->addr_bytes);
-
-	if (rc)
+	ucast.opcode = ECORE_FILTER_ADD;
+	ether_addr_copy(mac_addr, (struct ether_addr *)&ucast.mac);
+	rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
+	if (rc != 0)
 		DP_ERR(edev, "Unable to add new default mac\n");
 	else
 		ether_addr_copy(mac_addr, &qdev->primary_mac);
 }
 
-
-
-
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool action)
 {
 	struct ecore_dev *edev = &qdev->edev;
@@ -414,22 +553,6 @@ static void qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
 		mask, rxmode->hw_vlan_strip, rxmode->hw_vlan_filter);
 }
 
-static int qede_set_ucast_rx_vlan(struct qede_dev *qdev,
-				  enum qed_filter_xcast_params_type opcode,
-				  uint16_t vid)
-{
-	struct qed_filter_params filter_cmd;
-	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
-
-	memset(&filter_cmd, 0, sizeof(filter_cmd));
-	filter_cmd.type = QED_FILTER_TYPE_UCAST;
-	filter_cmd.filter.ucast.type = opcode;
-	filter_cmd.filter.ucast.vlan_valid = 1;
-	filter_cmd.filter.ucast.vlan = vid;
-
-	return qdev->ops->filter_config(edev, &filter_cmd);
-}
-
 static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 				uint16_t vlan_id, int on)
 {
@@ -438,6 +561,7 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	struct qed_dev_eth_info *dev_info = &qdev->dev_info;
 	struct qede_vlan_entry *tmp = NULL;
 	struct qede_vlan_entry *vlan;
+	struct ecore_filter_ucast ucast;
 	int rc;
 
 	if (on) {
@@ -464,9 +588,13 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 			return -ENOMEM;
 		}
 
-		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_ADD,
-					    vlan_id);
-		if (rc) {
+		qede_set_ucast_cmn_params(&ucast);
+		ucast.opcode = ECORE_FILTER_ADD;
+		ucast.type = ECORE_FILTER_VLAN;
+		ucast.vlan = vlan_id;
+		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
+					    NULL);
+		if (rc != 0) {
 			DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id,
 			       rc);
 			rte_free(vlan);
@@ -496,9 +624,13 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 
 		SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list);
 
-		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_DEL,
-					    vlan_id);
-		if (rc) {
+		qede_set_ucast_cmn_params(&ucast);
+		ucast.opcode = ECORE_FILTER_REMOVE;
+		ucast.type = ECORE_FILTER_VLAN;
+		ucast.vlan = vlan_id;
+		rc = ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB,
+					    NULL);
+		if (rc != 0) {
 			DP_ERR(edev, "Failed to delete VLAN %u rc %d\n",
 			       vlan_id, rc);
 		} else {
@@ -740,22 +872,6 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
 	return ((curr->link_status == link.link_up) ? -1 : 0);
 }
 
-static void
-qede_rx_mode_setting(struct rte_eth_dev *eth_dev,
-		     enum qed_filter_rx_mode_type accept_flags)
-{
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	struct qed_filter_params rx_mode;
-
-	DP_INFO(edev, "%s mode %u\n", __func__, accept_flags);
-
-	memset(&rx_mode, 0, sizeof(struct qed_filter_params));
-	rx_mode.type = QED_FILTER_TYPE_RX_MODE;
-	rx_mode.filter.accept_flags = accept_flags;
-	qdev->ops->filter_config(edev, &rx_mode);
-}
-
 static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
@@ -768,7 +884,7 @@ static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
 		type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
 
-	qede_rx_mode_setting(eth_dev, type);
+	qed_configure_filter_rx_mode(eth_dev, type);
 }
 
 static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
@@ -779,10 +895,11 @@ static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
 	PMD_INIT_FUNC_TRACE(edev);
 
 	if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
-		qede_rx_mode_setting(eth_dev,
-				     QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
 	else
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_REGULAR);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_REGULAR);
 }
 
 static void qede_poll_sp_sb_cb(void *param)
@@ -1040,15 +1157,17 @@ static void qede_allmulticast_enable(struct rte_eth_dev *eth_dev)
 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
 		type |= QED_FILTER_RX_MODE_TYPE_PROMISC;
 
-	qede_rx_mode_setting(eth_dev, type);
+	qed_configure_filter_rx_mode(eth_dev, type);
 }
 
 static void qede_allmulticast_disable(struct rte_eth_dev *eth_dev)
 {
 	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1)
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_PROMISC);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_PROMISC);
 	else
-		qede_rx_mode_setting(eth_dev, QED_FILTER_RX_MODE_TYPE_REGULAR);
+		qed_configure_filter_rx_mode(eth_dev,
+				QED_FILTER_RX_MODE_TYPE_REGULAR);
 }
 
 static int qede_flow_ctrl_set(struct rte_eth_dev *eth_dev,
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index a97e3d9..a35ea8b 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -123,6 +123,17 @@ struct qede_vlan_entry {
 	uint16_t vid;
 };
 
+struct qede_mcast_entry {
+	struct ether_addr mac;
+	SLIST_ENTRY(qede_mcast_entry) list;
+};
+
+struct qede_ucast_entry {
+	struct ether_addr mac;
+	uint16_t vlan;
+	SLIST_ENTRY(qede_ucast_entry) list;
+};
+
 /*
  *  Structure to store private data for each port.
  */
@@ -147,6 +158,10 @@ struct qede_dev {
 	uint16_t configured_vlans;
 	bool accept_any_vlan;
 	struct ether_addr primary_mac;
+	SLIST_HEAD(mc_list_head, qede_mcast_entry) mc_list_head;
+	uint16_t num_mc_addr;
+	SLIST_HEAD(uc_list_head, qede_ucast_entry) uc_list_head;
+	uint16_t num_uc_addr;
 	bool handle_hw_err;
 	char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
 };
-- 
1.7.10.3



More information about the dev mailing list