All of lore.kernel.org
 help / color / mirror / Atom feed
From: alvinx.zhang@intel.com
To: dev@dpdk.org
Cc: haiyue.wang@intel.com, xiaolong.ye@intel.com,
	qi.z.zhang@intel.com, beilei.xing@intel.com,
	Alvin Zhang <alvinx.zhang@intel.com>
Subject: [dpdk-dev] [PATCH v1 11/15] net/igc: implement ether-type filter
Date: Mon,  9 Mar 2020 16:24:03 +0800	[thread overview]
Message-ID: <1583742247-370386-11-git-send-email-alvinx.zhang@intel.com> (raw)
In-Reply-To: <1583742247-370386-1-git-send-email-alvinx.zhang@intel.com>

From: Alvin Zhang <alvinx.zhang@intel.com>

Update feature list too.

Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
---
 doc/guides/nics/features/igc.ini |   1 +
 drivers/net/igc/Makefile         |   1 +
 drivers/net/igc/igc_ethdev.c     |   5 +
 drivers/net/igc/igc_ethdev.h     |  15 +++
 drivers/net/igc/igc_filter.c     | 237 +++++++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_filter.h     |  31 +++++
 drivers/net/igc/meson.build      |   3 +-
 7 files changed, 292 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/igc/igc_filter.c
 create mode 100644 drivers/net/igc/igc_filter.h

diff --git a/doc/guides/nics/features/igc.ini b/doc/guides/nics/features/igc.ini
index f5c862b..95c41ee 100644
--- a/doc/guides/nics/features/igc.ini
+++ b/doc/guides/nics/features/igc.ini
@@ -31,6 +31,7 @@ RSS key update       = Y
 RSS reta update      = Y
 VLAN filter          = Y
 VLAN offload         = Y
+Flow API             = P
 Linux UIO            = Y
 Linux VFIO           = Y
 x86-64               = Y
diff --git a/drivers/net/igc/Makefile b/drivers/net/igc/Makefile
index b8cc7b9..45b0cf7 100644
--- a/drivers/net/igc/Makefile
+++ b/drivers/net/igc/Makefile
@@ -68,5 +68,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += e1000_phy.c
 SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_logs.c
 SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_txrx.c
+SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_filter.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index ae3c42b..e23dc3a 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -11,6 +11,7 @@
 
 #include "igc_logs.h"
 #include "igc_txrx.h"
+#include "igc_filter.h"
 
 #define IGC_INTEL_VENDOR_ID		0x8086
 
@@ -289,6 +290,7 @@ static int eth_igc_vlan_tpid_set(struct rte_eth_dev *dev,
 	.vlan_offload_set	= eth_igc_vlan_offload_set,
 	.vlan_tpid_set		= eth_igc_vlan_tpid_set,
 	.vlan_strip_queue_set	= eth_igc_vlan_strip_queue_set,
+	.filter_ctrl		= eth_igc_filter_ctrl,
 };
 
 /*
@@ -1155,6 +1157,8 @@ static int eth_igc_vlan_tpid_set(struct rte_eth_dev *dev,
 	if (!adapter->stopped)
 		eth_igc_stop(dev);
 
+	igc_clear_all_filter(dev);
+
 	igc_intr_other_disable(dev);
 	do {
 		int ret = rte_intr_callback_unregister(intr_handle,
@@ -1324,6 +1328,7 @@ static int eth_igc_vlan_tpid_set(struct rte_eth_dev *dev,
 		igc->rxq_stats_map[i] = -1;
 	}
 
+	igc_clear_all_filter(dev);
 	return 0;
 
 err_late:
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
index 1a157ee..0880380 100644
--- a/drivers/net/igc/igc_ethdev.h
+++ b/drivers/net/igc/igc_ethdev.h
@@ -91,6 +91,14 @@
 	ETH_RSS_IPV6_TCP_EX | \
 	ETH_RSS_IPV6_UDP_EX)
 
+#define IGC_MAX_ETQF_FILTERS		3	/* etqf(3) is used for 1588 */
+#define IGC_ETQF_FILTER_1588		3
+#define IGC_ETQF_QUEUE_SHIFT		16
+#define IGC_ETQF_QUEUE_MASK		(7 << IGC_ETQF_QUEUE_SHIFT)
+#define IGC_GET_ETHER_TYPE_FROM_ETQF(_etqf)	((uint16_t)(_etqf))
+#define IGC_GET_QUEUE_FROM_ETQF(_etqf)	\
+	((uint8_t)(((_etqf) & IGC_ETQF_QUEUE_MASK) >> IGC_ETQF_QUEUE_SHIFT))
+
 /* structure for interrupt relative data */
 struct igc_interrupt {
 	uint32_t flags;
@@ -126,6 +134,11 @@ struct igc_vfta {
 	uint32_t vfta[IGC_VFTA_SIZE];
 };
 
+/* ethertype filter structure */
+struct igc_ethertype_filter {
+	uint32_t etqf;
+};
+
 /*
  * Structure to store private data for each driver instance (for each port).
  */
@@ -139,6 +152,8 @@ struct igc_adapter {
 	struct igc_interrupt	intr;
 	struct igc_vfta	shadow_vfta;
 	bool		stopped;
+
+	struct igc_ethertype_filter ethertype_filters[IGC_MAX_ETQF_FILTERS];
 };
 
 #define IGC_DEV_PRIVATE(_dev)	((_dev)->data->dev_private)
diff --git a/drivers/net/igc/igc_filter.c b/drivers/net/igc/igc_filter.c
new file mode 100644
index 0000000..231fcd4
--- /dev/null
+++ b/drivers/net/igc/igc_filter.c
@@ -0,0 +1,237 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+
+#include "rte_malloc.h"
+#include "igc_logs.h"
+#include "igc_txrx.h"
+#include "igc_filter.h"
+
+/*
+ * igc_ethertype_filter_lookup - lookup ether-type filter
+ *
+ * @igc, IGC filter pointer
+ * @ethertype, ethernet type
+ * @empty, a place to store the index of empty entry if the item not found
+ *  it's not smaller than 0 if valid, otherwise -1 for no empty entry.
+ *  empty parameter is only valid if the return value of the function is -1
+ *
+ * Return value
+ * >= 0, item index of the ether-type filter
+ * -1, the item not been found
+ */
+static inline int
+igc_ethertype_filter_lookup(const struct igc_adapter *igc,
+			uint16_t ethertype, int *empty)
+{
+	int i = 0;
+
+	if (empty) {
+		/* set to invalid valid */
+		*empty = -1;
+
+		/* search the filters array */
+		for (; i < IGC_MAX_ETQF_FILTERS; i++) {
+			uint32_t etqf = igc->ethertype_filters[i].etqf;
+			if (etqf) {
+				if (IGC_GET_ETHER_TYPE_FROM_ETQF(etqf) ==
+					ethertype)
+					/* filter be found, return index */
+					return i;
+			} else {
+				/* get empty entry */
+				*empty = i;
+				i++;
+				break;
+			}
+		}
+	}
+
+	/* search the rest of filters */
+	for (; i < IGC_MAX_ETQF_FILTERS; i++) {
+		uint32_t etqf = igc->ethertype_filters[i].etqf;
+		if (etqf && IGC_GET_ETHER_TYPE_FROM_ETQF(etqf) == ethertype)
+			return i;	/* filter be found, return index */
+	}
+
+	return -1;
+}
+
+int
+igc_del_ethertype_filter(struct rte_eth_dev *dev,
+			const struct rte_eth_ethertype_filter *filter)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
+	uint32_t etqf;
+	int ret;
+
+	ret = igc_ethertype_filter_lookup(igc, filter->ether_type, NULL);
+	if (ret < 0) {
+		/* not found */
+		PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter doesn't"
+			" exist.", filter->ether_type);
+		return -ENOENT;
+	}
+
+	etqf = 0;
+	igc->ethertype_filters[ret].etqf = 0;
+
+	IGC_WRITE_REG(hw, IGC_ETQF(ret), etqf);
+	IGC_WRITE_FLUSH(hw);
+	return 0;
+}
+
+int
+igc_add_ethertype_filter(struct rte_eth_dev *dev,
+			const struct rte_eth_ethertype_filter *filter)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
+	uint32_t etqf;
+	int ret, empty;
+
+	if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
+		filter->ether_type == RTE_ETHER_TYPE_IPV6) {
+		PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in"
+			" ethertype filter.", filter->ether_type);
+		return -EINVAL;
+	}
+
+	if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
+		PMD_DRV_LOG(ERR, "mac compare is unsupported.");
+		return -EINVAL;
+	}
+
+	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
+		PMD_DRV_LOG(ERR, "drop option is unsupported.");
+		return -EINVAL;
+	}
+
+	ret = igc_ethertype_filter_lookup(igc, filter->ether_type, &empty);
+	if (ret >= 0) {
+		PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter exists.",
+				filter->ether_type);
+		return -EEXIST;
+	}
+
+	if (empty < 0) {
+		PMD_DRV_LOG(ERR, "no ethertype filter entry.");
+		return -ENOSPC;
+	}
+	ret = empty;
+
+	etqf = filter->ether_type;
+	etqf |= IGC_ETQF_FILTER_ENABLE | IGC_ETQF_QUEUE_ENABLE;
+	etqf |= (uint32_t)filter->queue << IGC_ETQF_QUEUE_SHIFT;
+	igc->ethertype_filters[ret].etqf = etqf;
+
+	IGC_WRITE_REG(hw, IGC_ETQF(ret), etqf);
+	IGC_WRITE_FLUSH(hw);
+	return 0;
+}
+
+static int
+igc_get_ethertype_filter(const struct rte_eth_dev *dev,
+			struct rte_eth_ethertype_filter *filter)
+{
+	const struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
+	uint32_t etqf;
+	int ret;
+
+	ret = igc_ethertype_filter_lookup(igc, filter->ether_type, NULL);
+	if (ret < 0) {
+		PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter doesn't exist.",
+			    filter->ether_type);
+		return -ENOENT;
+	}
+
+	etqf = igc->ethertype_filters[ret].etqf;
+	filter->queue = IGC_GET_QUEUE_FROM_ETQF(etqf);
+	filter->flags = 0;
+	return 0;
+}
+
+/* clear all the ether type filters */
+static void
+igc_clear_all_ethertype_filter(struct rte_eth_dev *dev)
+{
+	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
+	int i;
+
+	for (i = 0; i < IGC_MAX_ETQF_FILTERS; i++)
+		IGC_WRITE_REG(hw, IGC_ETQF(i), 0);
+	IGC_WRITE_FLUSH(hw);
+
+	memset(&igc->ethertype_filters, 0, sizeof(igc->ethertype_filters));
+}
+
+/**
+ * igc_ethertype_filter_handle - Handle operations for ethernet type filter.
+ *
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @filter: a pointer to structure of rte_eth_ethertype_filter
+ *
+ * Return 0, or negative for error
+ **/
+static int
+igc_ethertype_filter_handle(struct rte_eth_dev *dev,
+			enum rte_filter_op filter_op,
+			struct rte_eth_ethertype_filter *filter)
+{
+	int ret;
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = igc_add_ethertype_filter(dev, filter);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = igc_del_ethertype_filter(dev, filter);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = igc_get_ethertype_filter(dev, filter);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+void
+igc_clear_all_filter(struct rte_eth_dev *dev)
+{
+	igc_clear_all_ethertype_filter(dev);
+}
+
+int
+eth_igc_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type,
+		enum rte_filter_op filter_op, void *arg)
+{
+	int ret = 0;
+
+	switch (filter_type) {
+	case RTE_ETH_FILTER_ETHERTYPE:
+		ret = igc_ethertype_filter_handle(dev, filter_op,
+			(struct rte_eth_ethertype_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
+							filter_type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
diff --git a/drivers/net/igc/igc_filter.h b/drivers/net/igc/igc_filter.h
new file mode 100644
index 0000000..eff0e47
--- /dev/null
+++ b/drivers/net/igc/igc_filter.h
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+
+#ifndef _IGC_FILTER_H_
+#define _IGC_FILTER_H_
+
+#include <rte_ethdev_core.h>
+#include <rte_eth_ctrl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int igc_add_ethertype_filter(struct rte_eth_dev *dev,
+		const struct rte_eth_ethertype_filter *filter);
+int igc_del_ethertype_filter(struct rte_eth_dev *dev,
+		const struct rte_eth_ethertype_filter *filter);
+void
+igc_clear_all_filter(struct rte_eth_dev *dev);
+
+int
+eth_igc_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type,
+		enum rte_filter_op filter_op, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IGC_FILTER_H_ */
diff --git a/drivers/net/igc/meson.build b/drivers/net/igc/meson.build
index 8742a59..d509c0e 100644
--- a/drivers/net/igc/meson.build
+++ b/drivers/net/igc/meson.build
@@ -7,7 +7,8 @@ objs = [base_objs]
 sources = files(
 	'igc_logs.c',
 	'igc_ethdev.c',
-	'igc_txrx.c'
+	'igc_txrx.c',
+	'igc_filter.c'
 )
 
 includes += include_directories('base')
-- 
1.8.3.1


  parent reply	other threads:[~2020-03-09  8:30 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-09  8:23 [dpdk-dev] [PATCH v1 01/15] net/igc: add igc PMD alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 02/15] net/igc: update base share codes alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 03/15] net/igc: device initialization alvinx.zhang
2020-03-12  4:42   ` Ye Xiaolong
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 04/15] net/igc: implement device base ops alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 05/15] net/igc: support reception and transmission of packets alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 06/15] net/igc: implement status API alvinx.zhang
2020-03-09  8:23 ` [dpdk-dev] [PATCH v1 07/15] net/igc: enable Rx queue interrupts alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 08/15] net/igc: implement flow control ops alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 09/15] net/igc: implement RSS API alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 10/15] net/igc: implement feature of VLAN alvinx.zhang
2020-03-09  8:24 ` alvinx.zhang [this message]
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 12/15] net/igc: implement 2-tuple filter alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 13/15] net/igc: implement TCP SYN filter alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 14/15] net/igc: implement hash filter configure alvinx.zhang
2020-03-09  8:24 ` [dpdk-dev] [PATCH v1 15/15] net/igc: implement flow API alvinx.zhang
2020-03-09  8:35 ` [dpdk-dev] [PATCH v1 01/15] net/igc: add igc PMD Ye Xiaolong
2020-03-12  3:09 ` Ye Xiaolong
2020-03-20  2:46 ` [dpdk-dev] [PATCH v2 00/14] " alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 01/14] net/igc: add " alvinx.zhang
2020-04-03 12:21     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 02/14] net/igc: support device initialization alvinx.zhang
2020-04-03 12:23     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 03/14] net/igc: implement device base ops alvinx.zhang
2020-04-03 12:24     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 04/14] net/igc: support reception and transmission of packets alvinx.zhang
2020-04-03 12:27     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 05/14] net/igc: implement status API alvinx.zhang
2020-04-03 12:24     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 06/14] net/igc: enable Rx queue interrupts alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 07/14] net/igc: implement flow control ops alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 08/14] net/igc: implement RSS API alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 09/14] net/igc: implement feature of VLAN alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 10/14] net/igc: implement ether-type filter alvinx.zhang
2020-04-03 12:26     ` Ferruh Yigit
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 11/14] net/igc: implement 2-tuple filter alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 12/14] net/igc: implement TCP SYN filter alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 13/14] net/igc: implement hash filter configure alvinx.zhang
2020-03-20  2:46   ` [dpdk-dev] [PATCH v2 14/14] net/igc: implement flow API alvinx.zhang
2020-04-03 12:26     ` Ferruh Yigit

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=1583742247-370386-11-git-send-email-alvinx.zhang@intel.com \
    --to=alvinx.zhang@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=dev@dpdk.org \
    --cc=haiyue.wang@intel.com \
    --cc=qi.z.zhang@intel.com \
    --cc=xiaolong.ye@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.