DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters
@ 2014-05-19 23:51 Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 1/3] ixgbe: Add L2 ethertype filter for ixgbe Vladimir Medvedkin
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2014-05-19 23:51 UTC (permalink / raw)
  To: dev

This patchset adds in addition to the Flow Director filters L2 Ethertype, SYN and Five tuple queue filters to route 
packets according to ethertype, l4 proto, source/destination ip/ports pool and presence of SYN flag in TCP packet.
Unlike http://dpdk.org/ml/archives/dev/2014-May/002512.html this gives capability to work with pools. 
This patch functionality can be merged with the patch above.
 

Vladimir Medvedkin (3):
  ixgbe: Add L2 ethertype filter for ixgbe
  ixgbe: Add syn queue filter for ixgbe
  ixgbe: Add five tuple filter for ixgbe

 lib/librte_ether/rte_ethdev.c           | 228 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h           | 237 +++++++++++++++++++++++++++
 lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h |  20 +++
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c     | 274 ++++++++++++++++++++++++++++++++
 4 files changed, 759 insertions(+)

-- 
1.8.3.2

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

* [dpdk-dev] [PATCH 1/3]  ixgbe: Add L2 ethertype filter for ixgbe
  2014-05-19 23:51 [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Vladimir Medvedkin
@ 2014-05-19 23:51 ` Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 2/3] ixgbe: Add syn queue " Vladimir Medvedkin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2014-05-19 23:51 UTC (permalink / raw)
  To: dev

This patch adds ability to route packets according to ethertype, priority and pool to certain queue specified in rx_queue field.
---
 lib/librte_ether/rte_ethdev.c           |  81 +++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h           |  78 ++++++++++++++++++++++++
 lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h |   6 ++
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c     | 104 ++++++++++++++++++++++++++++++++
 4 files changed, 269 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a5727dd..5cd0148 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1194,6 +1194,87 @@ rte_eth_dev_get_vlan_offload(uint8_t port_id)
 	return ret;
 }
 
+int
+rte_eth_dev_l2_etype_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info info;
+
+	rte_eth_dev_info_get(port_id, &info);
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+        if (filter == NULL) {
+                PMD_DEBUG_TRACE("Invalid filter pointer\n");
+                return (-EINVAL);
+        }
+
+        if(filter->rx_queue >= info.max_rx_queues) {
+                PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", filter->rx_queue);
+                return (-EINVAL);
+        }
+
+	if (filter->etype == ETHER_TYPE_IPv4 || filter->etype == ETHER_TYPE_IPv6){
+		PMD_DEBUG_TRACE("IP and IPv6 are not supported in ethertype filter\n");
+		return (-EINVAL);
+	}
+
+        if(filter->flags & ETH_L2ETYPE_POOL_EN) {
+                if(dev->data->dev_conf.rxmode.mq_mode < ETH_MQ_RX_VMDQ_ONLY) {
+                        PMD_DEBUG_TRACE("Port %d is in non-VT mode\n", port_id);
+                        return (-EINVAL);
+                }
+                if(filter->pool >= dev->data->dev_conf.rx_adv_conf.vmdq_rx_conf.nb_queue_pools) {
+                        PMD_DEBUG_TRACE("Invalid pool number %d\n", filter->pool);
+                        return (-EINVAL);
+                }
+        }
+
+        FUNC_PTR_OR_ERR_RET(*dev->dev_ops->l2_etype_add_filter, -ENOTSUP);
+        return (*dev->dev_ops->l2_etype_add_filter)(dev, filter_id, filter);
+}
+
+int
+rte_eth_dev_l2_etype_get_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	if (filter == NULL) {
+		PMD_DEBUG_TRACE("Invalid filter pointer\n");
+		return (-EINVAL);
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->l2_etype_add_filter, -ENOTSUP);
+	return (*dev->dev_ops->l2_etype_get_filter)(dev, filter_id, filter);
+}
+
+int
+rte_eth_dev_l2_etype_del_filter(uint8_t port_id, uint8_t filter_id)
+{
+        struct rte_eth_dev *dev;
+
+        if (port_id >= nb_ports) {
+                PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+                return (-ENODEV);
+        }
+
+        dev = &rte_eth_devices[port_id];
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->l2_etype_add_filter, -ENOTSUP);
+	return (*dev->dev_ops->l2_etype_del_filter)(dev, filter_id);
+}
 
 int
 rte_eth_dev_fdir_add_signature_filter(uint8_t port_id,
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index dea7471..0e6326e 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -363,6 +363,10 @@ struct rte_eth_rss_conf {
 /* Definitions used for unicast hash  */
 #define ETH_VMDQ_NUM_UC_HASH_ARRAY  128 /**< Maximum nb. of UC hash array. */
 
+/* Definitions used for L2 Ether type filters  */
+#define ETH_L2ETYPE_UP_EN		0x1
+#define ETH_L2ETYPE_POOL_EN		0x2
+
 /* Definitions used for VMDQ pool rx mode setting */
 #define ETH_VMDQ_ACCEPT_UNTAG   0x0001 /**< accept untagged packets. */
 #define ETH_VMDQ_ACCEPT_HASH_MC 0x0002 /**< accept packets in multicast table . */
@@ -558,6 +562,17 @@ struct rte_eth_pfc_conf {
 };
 
 /**
+ * A structure used to configure L2 Ethertype Filters
+ */
+struct rte_eth_l2etype_filter {
+	uint16_t	etype;
+	uint8_t		priority; /**< VLAN User Priority.  */
+	uint8_t		pool;
+	uint8_t		flags;	  /**< Flags byte.  */
+	uint8_t		rx_queue;
+};
+
+/**
  *  Flow Director setting modes: none (default), signature or perfect.
  */
 enum rte_fdir_mode {
@@ -911,6 +926,15 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq,
 				   uint16_t nb_pkts);
 /**< @internal Send output packets on a transmit queue of an Ethernet device. */
 
+typedef int (*l2_etype_add_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+/**< @internal Setup a new L2 Ethertype filter */
+
+typedef int (*l2_etype_get_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+/**< @internal Get L2 Ethertype filter */
+
+typedef int (*l2_etype_del_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id);
+/**< @internal Delete L2 Ethertype filter */
+
 typedef int (*fdir_add_signature_filter_t)(struct rte_eth_dev *dev,
 					   struct rte_fdir_filter *fdir_ftr,
 					   uint8_t rx_queue);
@@ -1120,6 +1144,12 @@ struct eth_dev_ops {
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
 
+	/** Setup a L2 Ethertype filter. */
+	l2_etype_add_filter_t l2_etype_add_filter;
+	/** Get a L2 Ethertype filter. */
+	l2_etype_get_filter_t l2_etype_get_filter;
+	/** Delete a L2 Ethertype filter. */
+	l2_etype_del_filter_t l2_etype_del_filter;
 	/** Add a signature filter. */
 	fdir_add_signature_filter_t fdir_add_signature_filter;
 	/** Update a signature filter. */
@@ -2109,6 +2139,54 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
 #endif
 
 /**
+ * Setup L2 Ethertype queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..7] range
+ * @param filter
+ *   The pointer to the l2 ethertype structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support l2 ether type filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-EINVAL)  if *filter*  invalid
+ *   - (-ENOENT)  if *filter_id* invalid
+*/
+int rte_eth_dev_l2_etype_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+
+/**
+ *  Get L2 Ethertype queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..7] range
+ * @param filter
+ *   The pointer to the l2 ethertype structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support l2 ether type filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if *filter_id* rule inactive
+ *   - (-EINVAL)  if *filter* pointer is NULL or *filter_id* invalid
+*/
+int rte_eth_dev_l2_etype_get_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+
+/**
+ * Delete L2 Ethertype queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..7] range
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support l2 ether type filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if *filter_id* invalid
+*/
+int rte_eth_dev_l2_etype_del_filter(uint8_t port_id, uint8_t filter_id);
+
+/**
  * Setup a new signature filter rule on an Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
index f03046f..28653d5 100644
--- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
+++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
@@ -1537,6 +1537,12 @@ enum {
 #define IXGBE_ETQF_FILTER_EN		0x80000000 /* bit 31 */
 #define IXGBE_ETQF_POOL_ENABLE		(1 << 26) /* bit 26 */
 #define IXGBE_ETQF_POOL_SHIFT		20
+#define IXGBE_ETQF_POOL_MASK            0x03F00000 /* bits 25:20 */
+#define IXGBE_ETQF_UP_ENABLE            (1 << 19) /* bit 19 */
+#define IXGBE_ETQF_UP_SHIFT             16
+#define IXGBE_ETQF_UP_MASK              0x00070000 /* bits 18:16 */
+#define IXGBE_ETQF_UP_NUMBER		8
+#define IXGBE_ETQF_ETYPE                0x0000FFFF /* bits 15:0 */
 
 #define IXGBE_ETQS_RX_QUEUE		0x007F0000 /* bits 22:16 */
 #define IXGBE_ETQS_RX_QUEUE_SHIFT	16
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index e78c208..e1604e5 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -147,6 +147,10 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config);
 
+static int ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+static int ixgbe_l2_etype_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
+static int ixgbe_l2_etype_del_filter(struct rte_eth_dev *dev, uint8_t filter_id);
+
 /* For Virtual Function support */
 static int eth_ixgbevf_dev_init(struct eth_driver *eth_drv,
 		struct rte_eth_dev *eth_dev);
@@ -279,6 +283,9 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.l2_etype_add_filter          = ixgbe_l2_etype_add_filter,
+	.l2_etype_get_filter          = ixgbe_l2_etype_get_filter,
+	.l2_etype_del_filter          = ixgbe_l2_etype_del_filter,
 	.fdir_add_signature_filter    = ixgbe_fdir_add_signature_filter,
 	.fdir_update_signature_filter = ixgbe_fdir_update_signature_filter,
 	.fdir_remove_signature_filter = ixgbe_fdir_remove_signature_filter,
@@ -3060,3 +3067,100 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
 
 	return 0;
 }
+
+static int
+ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t etqf, etqs = 0;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if(filter_id >= IXGBE_MAX_ETQF_FILTERS)
+		return (-ENOENT);
+
+	etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(filter_id));
+	if (etqf & IXGBE_ETQF_FILTER_EN)
+		return (-EINVAL);
+
+	etqf = 0;
+
+	if((filter->flags & ETH_L2ETYPE_UP_EN) && (filter->priority >= IXGBE_ETQF_UP_NUMBER))
+		return (-EINVAL);
+
+        etqf = filter->etype;
+        if (filter->flags & ETH_L2ETYPE_UP_EN) {
+                etqf |= IXGBE_ETQF_UP_ENABLE;
+                etqf |= filter->priority << IXGBE_ETQF_UP_SHIFT;
+        }
+        if (filter->flags & ETH_L2ETYPE_POOL_EN) {
+                if (ixgbe_vmdq_mode_check(hw) < 0)
+                        return (-ENOTSUP);
+                etqf |= IXGBE_ETQF_POOL_ENABLE;
+                etqf |= filter->pool << IXGBE_ETQF_POOL_SHIFT;
+        }
+        etqf |= IXGBE_ETQF_FILTER_EN;
+
+        etqs = filter->rx_queue << IXGBE_ETQS_RX_QUEUE_SHIFT;
+        etqs |= IXGBE_ETQS_QUEUE_EN;
+
+        IXGBE_WRITE_REG(hw, IXGBE_ETQF(filter_id), etqf);
+        IXGBE_WRITE_REG(hw, IXGBE_ETQS(filter_id), etqs);
+
+        return 0;
+}
+
+static int
+ixgbe_l2_etype_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t etqf, etqs;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if(filter_id >= IXGBE_MAX_ETQF_FILTERS)
+		return (-EINVAL);
+
+	etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(filter_id));
+	etqs = IXGBE_READ_REG(hw, IXGBE_ETQS(filter_id));
+
+	if(!(etqf & IXGBE_ETQF_FILTER_EN) | !(etqs & IXGBE_ETQS_QUEUE_EN))
+		return (-ENOENT);
+
+	filter->etype = etqf & IXGBE_ETQF_ETYPE;
+	filter->flags = 0;
+
+	if (etqf & IXGBE_ETQF_UP_ENABLE) {
+		filter->flags = ETH_L2ETYPE_UP_EN;
+		filter->priority = (etqf & IXGBE_ETQF_UP_MASK) >> IXGBE_ETQF_UP_SHIFT;
+	}
+
+	if (etqf & IXGBE_ETQF_POOL_ENABLE) {
+		filter->flags |= ETH_L2ETYPE_POOL_EN;
+		filter->pool = (etqf & IXGBE_ETQF_POOL_MASK) >> IXGBE_ETQF_POOL_SHIFT;
+	}
+
+	filter->rx_queue = (etqs & IXGBE_ETQS_RX_QUEUE) >> IXGBE_ETQS_RX_QUEUE_SHIFT;
+
+	return 0;
+}
+
+static int
+ixgbe_l2_etype_del_filter(struct rte_eth_dev *dev, uint8_t filter_id)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if (filter_id >= IXGBE_MAX_ETQF_FILTERS)
+		return (-ENOENT);
+
+        IXGBE_WRITE_REG(hw, IXGBE_ETQF(filter_id), 0);
+        IXGBE_WRITE_REG(hw, IXGBE_ETQS(filter_id), 0);
+
+        return 0;
+}
+
-- 
1.8.3.2

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

* [dpdk-dev] [PATCH 2/3]  ixgbe: Add syn queue filter for ixgbe
  2014-05-19 23:51 [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 1/3] ixgbe: Add L2 ethertype filter for ixgbe Vladimir Medvedkin
@ 2014-05-19 23:51 ` Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 3/3] ixgbe: Add five tuple " Vladimir Medvedkin
  2014-05-27 23:09 ` [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Thomas Monjalon
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2014-05-19 23:51 UTC (permalink / raw)
  To: dev

This patch adds ability to route TCP packets according to SYN flag presence to certain queue.
---
 lib/librte_ether/rte_ethdev.c           | 66 +++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h           | 63 +++++++++++++++++++++++++++++++
 lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h |  6 +++
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c     | 57 +++++++++++++++++++++++++++-
 4 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 5cd0148..4597176 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1195,6 +1195,72 @@ rte_eth_dev_get_vlan_offload(uint8_t port_id)
 }
 
 int
+rte_eth_dev_synq_add_filter(uint8_t port_id, struct rte_eth_synq_filter *filter)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info info;
+
+	rte_eth_dev_info_get(port_id, &info);
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	if (filter == NULL) {
+		PMD_DEBUG_TRACE("Invalid filter pointer\n");
+		return (-EINVAL);
+	}
+
+	if(filter->rx_queue >= info.max_rx_queues) {
+		PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", filter->rx_queue);
+		return (-EINVAL);
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP);
+	return (*dev->dev_ops->synq_add_filter)(dev, filter);
+}
+
+int
+rte_eth_dev_synq_get_filter(uint8_t port_id, struct rte_eth_synq_filter *filter)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	if (filter == NULL) {
+		PMD_DEBUG_TRACE("Invalid filter pointer\n");
+		return (-EINVAL);
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP);
+	return (*dev->dev_ops->synq_get_filter)(dev, filter);
+}
+
+int
+rte_eth_dev_synq_del_filter(uint8_t port_id)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP);
+	return (*dev->dev_ops->synq_del_filter)(dev);
+}
+
+int
 rte_eth_dev_l2_etype_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0e6326e..6b90aed 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -562,6 +562,14 @@ struct rte_eth_pfc_conf {
 };
 
 /**
+ * A structure used to configure SYN Packet queue Filters
+ */
+struct rte_eth_synq_filter {
+	uint8_t		rx_queue;
+	uint8_t		synq_first; /**< Defines the priority between SYNQF and 5-tuple filter.  */
+};
+
+/**
  * A structure used to configure L2 Ethertype Filters
  */
 struct rte_eth_l2etype_filter {
@@ -926,6 +934,15 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq,
 				   uint16_t nb_pkts);
 /**< @internal Send output packets on a transmit queue of an Ethernet device. */
 
+typedef int (*synq_add_filter_t)(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
+/**< @internal Setup SYN Packer queue filter */
+
+typedef int (*synq_get_filter_t)(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
+/**< @internal Get SYN Packer queue filter */
+
+typedef int (*synq_del_filter_t)(struct rte_eth_dev *dev);
+/**< @internal Delete SYN Packer queue filter */
+
 typedef int (*l2_etype_add_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
 /**< @internal Setup a new L2 Ethertype filter */
 
@@ -1144,6 +1161,12 @@ struct eth_dev_ops {
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
 
+	/** Setup a SYN Packet queue filter. */
+	synq_add_filter_t synq_add_filter;
+	/** Get a SYN Packet queue filter. */
+	synq_get_filter_t synq_get_filter;
+	/** Delete a SYN Packet queue filter. */
+	synq_del_filter_t synq_del_filter;
 	/** Setup a L2 Ethertype filter. */
 	l2_etype_add_filter_t l2_etype_add_filter;
 	/** Get a L2 Ethertype filter. */
@@ -2139,6 +2162,46 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
 #endif
 
 /**
+ * Setup SYN Packet queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter
+ *   The pointer to the synq filter structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-EINVAL)  if *filter* invalid.
+*/
+int rte_eth_dev_synq_add_filter(uint8_t port_id, struct rte_eth_synq_filter *filter);
+
+/**
+ * Get SYN Packet queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter
+ *   The pointer to the synq filter structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if SYN Packet filter inactive
+ *   - (-EINVAL)  if *filter* pointer is NULL
+*/
+int rte_eth_dev_synq_get_filter(uint8_t port_id, struct rte_eth_synq_filter *filter);
+
+/**
+ * Clear SYN Packet queue filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+*/
+int rte_eth_dev_synq_del_filter(uint8_t port_id);
+
+/**
  * Setup L2 Ethertype queue filter
  * @param port_id
  *   The port identifier of the Ethernet device.
diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
index 28653d5..8f911ff 100644
--- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
+++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
@@ -1529,6 +1529,12 @@ enum {
 
 #define IXGBE_IVAR_ALLOC_VAL		0x80 /* Interrupt Allocation valid */
 
+/* SYN Packet Queue Filter */
+#define IXGBE_SYNQF_EN			0x00000001
+#define IXGBE_SYNQF_RX_QUEUE		0x000000FE
+#define IXGBE_SYNQF_SHIFT		1
+#define IXGBE_SYNQF_SYN_FIRST		(1 << 31) /* bit 31 */
+
 /* ETYPE Queue Filter/Select Bit Masks */
 #define IXGBE_MAX_ETQF_FILTERS		8
 #define IXGBE_ETQF_FCOE			0x08000000 /* bit 27 */
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index e1604e5..8ed637b 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -146,7 +146,9 @@ static void 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_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config);
-
+static int ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
+static int ixgbe_synq_get_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
+static int ixgbe_synq_del_filter(struct rte_eth_dev *dev);
 static int ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
 static int ixgbe_l2_etype_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter);
 static int ixgbe_l2_etype_del_filter(struct rte_eth_dev *dev, uint8_t filter_id);
@@ -283,6 +285,9 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.synq_add_filter          = ixgbe_synq_add_filter,
+	.synq_get_filter          = ixgbe_synq_get_filter,
+	.synq_del_filter          = ixgbe_synq_del_filter,
 	.l2_etype_add_filter          = ixgbe_l2_etype_add_filter,
 	.l2_etype_get_filter          = ixgbe_l2_etype_get_filter,
 	.l2_etype_del_filter          = ixgbe_l2_etype_del_filter,
@@ -3069,6 +3074,56 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
 }
 
 static int
+ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t synqf = 0;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	synqf = IXGBE_SYNQF_EN;
+	synqf |= filter->rx_queue << IXGBE_SYNQF_SHIFT;
+
+	if(filter->synq_first)
+		synqf |= IXGBE_SYNQF_SYN_FIRST;
+
+	IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf);
+	return 0;
+}
+
+static int
+ixgbe_synq_get_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t synqf;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+
+	if (!(synqf & IXGBE_SYNQF_EN))
+		return (-ENOENT);
+
+	filter->rx_queue = (synqf & IXGBE_SYNQF_RX_QUEUE) >> IXGBE_SYNQF_SHIFT;
+	filter->synq_first = synqf & IXGBE_SYNQF_SYN_FIRST;
+	return 0;
+}
+
+static int
+ixgbe_synq_del_filter(struct rte_eth_dev *dev)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	IXGBE_WRITE_REG(hw, IXGBE_SYNQF, 0);
+	return 0;
+}
+
+static int
 ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter)
 {
 	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-- 
1.8.3.2

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

* [dpdk-dev] [PATCH 3/3]  ixgbe: Add five tuple filter for ixgbe
  2014-05-19 23:51 [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 1/3] ixgbe: Add L2 ethertype filter for ixgbe Vladimir Medvedkin
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 2/3] ixgbe: Add syn queue " Vladimir Medvedkin
@ 2014-05-19 23:51 ` Vladimir Medvedkin
  2014-05-27 23:09 ` [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Thomas Monjalon
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2014-05-19 23:51 UTC (permalink / raw)
  To: dev

This patch adds ability to route packets according to source, destination ip/ports, L4 proto and pool to certain queue.
---
 lib/librte_ether/rte_ethdev.c           |  81 ++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h           |  96 ++++++++++++++++++++++++++
 lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h |   8 +++
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c     | 115 ++++++++++++++++++++++++++++++++
 4 files changed, 300 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4597176..6cf838b 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1195,6 +1195,87 @@ rte_eth_dev_get_vlan_offload(uint8_t port_id)
 }
 
 int
+rte_eth_dev_5tuple_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_5tuple_filter *filter)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info info;
+
+	rte_eth_dev_info_get(port_id, &info);
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	if (filter == NULL) {
+		PMD_DEBUG_TRACE("Invalid filter pointer\n");
+		return (-EINVAL);
+	}
+
+	if(filter->rx_queue >= info.max_rx_queues) {
+		PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", filter->rx_queue);
+		return (-EINVAL);
+	}
+
+	if ((filter->proto == RTE_5TUPLE_PROTO_OTHER) && (filter->mask & (ETH_5TUPLE_MASK_SRCPORT|ETH_5TUPLE_MASK_DSTPORT))) {
+		PMD_DEBUG_TRACE(" L4 protocol not TCP, UDP or SCTP, ports are meaningless /n");
+		return(-EINVAL);
+	}
+
+	if (filter->mask & ETH_5TUPLE_MASK_POOL) {
+		if(dev->data->dev_conf.rxmode.mq_mode < ETH_MQ_RX_VMDQ_ONLY) {
+			PMD_DEBUG_TRACE("Port %d is in non-VT mode\n", port_id);
+			return (-EINVAL);
+		}
+		if(filter->pool >= dev->data->dev_conf.rx_adv_conf.vmdq_rx_conf.nb_queue_pools) {
+			PMD_DEBUG_TRACE("Invalid pool number %d\n", filter->pool);
+			return (-EINVAL);
+		}
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_5tuple_filter, -ENOTSUP);
+	return (*dev->dev_ops->add_5tuple_filter)(dev, filter_id, filter);
+}
+
+int
+rte_eth_dev_5tuple_get_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_5tuple_filter *filter)
+{
+        struct rte_eth_dev *dev;
+
+        if (port_id >= nb_ports) {
+                PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+                return (-ENODEV);
+        }
+
+        dev = &rte_eth_devices[port_id];
+
+        if (filter == NULL) {
+                PMD_DEBUG_TRACE("Invalid filter pointer\n");
+                return (-EINVAL);
+        }
+
+        FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_5tuple_filter, -ENOTSUP);
+        return (*dev->dev_ops->get_5tuple_filter)(dev, filter_id, filter);
+}
+
+int
+rte_eth_dev_5tuple_del_filter(uint8_t port_id, uint8_t filter_id)
+{
+	struct rte_eth_dev *dev;
+
+	if (port_id >= nb_ports) {
+		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+		return (-ENODEV);
+	}
+
+	dev = &rte_eth_devices[port_id];
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->del_5tuple_filter, -ENOTSUP);
+	return (*dev->dev_ops->del_5tuple_filter)(dev, filter_id);
+}
+int
 rte_eth_dev_synq_add_filter(uint8_t port_id, struct rte_eth_synq_filter *filter)
 {
 	struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 6b90aed..7f460c8 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -363,6 +363,14 @@ struct rte_eth_rss_conf {
 /* Definitions used for unicast hash  */
 #define ETH_VMDQ_NUM_UC_HASH_ARRAY  128 /**< Maximum nb. of UC hash array. */
 
+/* Definitions used for 5 tuple filters  */
+#define ETH_5TUPLE_MASK_SRCIP		0x1
+#define ETH_5TUPLE_MASK_DSTIP		0x2
+#define ETH_5TUPLE_MASK_SRCPORT		0x4
+#define ETH_5TUPLE_MASK_DSTPORT		0x8
+#define ETH_5TUPLE_MASK_PROTO		0x10
+#define ETH_5TUPLE_MASK_POOL		0x20
+
 /* Definitions used for L2 Ether type filters  */
 #define ETH_L2ETYPE_UP_EN		0x1
 #define ETH_L2ETYPE_POOL_EN		0x2
@@ -562,6 +570,31 @@ struct rte_eth_pfc_conf {
 };
 
 /**
+ *  Possible l4type of 5 tuple filters.
+ */
+enum rte_5tuple_proto {
+        RTE_5TUPLE_PROTO_TCP = 0,	/**< TCP. */
+        RTE_5TUPLE_PROTO_UDP,		/**< UDP. */
+        RTE_5TUPLE_PROTO_SCTP,		/**< SCTP. */
+        RTE_5TUPLE_PROTO_OTHER,		/**< Other. */
+};
+
+/**
+ * A structure used to configure Five Tuple Filters
+ */
+struct rte_eth_5tuple_filter {
+	uint32_t		src;
+	uint32_t		dst;
+	uint16_t		src_port;
+	uint16_t		dst_port;
+	enum rte_5tuple_proto	proto;
+	uint8_t			priority;
+	uint8_t			pool;
+	uint8_t			mask;
+	uint8_t			rx_queue;
+};
+
+/**
  * A structure used to configure SYN Packet queue Filters
  */
 struct rte_eth_synq_filter {
@@ -934,6 +967,15 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq,
 				   uint16_t nb_pkts);
 /**< @internal Send output packets on a transmit queue of an Ethernet device. */
 
+typedef int (*add_5tuple_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+/**< @internal Setup 5 tuple queue filter */
+
+typedef int (*get_5tuple_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+/**< @internal Get 5 tuple queue filter */
+
+typedef int (*del_5tuple_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id);
+/**< @internal Delete 5 tuple queue filter */
+
 typedef int (*synq_add_filter_t)(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
 /**< @internal Setup SYN Packer queue filter */
 
@@ -1161,6 +1203,12 @@ struct eth_dev_ops {
 	eth_set_vf_tx_t            set_vf_tx;  /**< enable/disable a VF transmit */
 	eth_set_vf_vlan_filter_t   set_vf_vlan_filter;  /**< Set VF VLAN filter */
 
+	/** Setup a 5 tuple filter. */
+	add_5tuple_filter_t add_5tuple_filter;
+	/** Get a 5 tuple filter. */
+	get_5tuple_filter_t get_5tuple_filter;
+	/** Delete a 5 tuple filter. */
+	del_5tuple_filter_t del_5tuple_filter;
 	/** Setup a SYN Packet queue filter. */
 	synq_add_filter_t synq_add_filter;
 	/** Get a SYN Packet queue filter. */
@@ -2162,6 +2210,54 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
 #endif
 
 /**
+ * Setup 5 tuple filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..127] range
+ * @param filter
+ *   The pointer to the rte_eth_5tuple_filter structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support 5 tuple filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if *filter_id* invalid
+ *   - (-EINVAL)  if *filter* invalid.
+*/
+int rte_eth_dev_5tuple_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+
+/**
+ *  Get 5 tuple filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..127] range
+ * @param filter
+ *   The pointer to the rte_eth_5tuple_filter structure.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support 5 tuple filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if *filter_id* rule inactive
+ *   - (-EINVAL)  if *filter* pointer is NULL
+*/
+int rte_eth_dev_5tuple_get_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+
+/**
+ * Delete 5 tuple filter
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param filter_id
+ *   The index of filter rule. Must be in [0..127] range
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support 5 tuple filters.
+ *   - (-ENODEV)  if *port_id* invalid.
+ *   - (-ENOENT)  if *filter_id* invalid
+*/
+int rte_eth_dev_5tuple_del_filter(uint8_t port_id, uint8_t filter_id);
+
+/**
  * Setup SYN Packet queue filter
  * @param port_id
  *   The port identifier of the Ethernet device.
diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
index 8f911ff..b4b3644 100644
--- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
+++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h
@@ -1509,6 +1509,14 @@ enum {
 #define IXGBE_FTQF_PROTOCOL_COMP_MASK	0x0F
 #define IXGBE_FTQF_POOL_MASK_EN		0x40000000
 #define IXGBE_FTQF_QUEUE_ENABLE		0x80000000
+#define IXGBE_FTQF_MAX_PRIORITY		7
+
+#define IXGBE_SDQPF_PORT_MASK		0x0000ffff
+#define IXGBE_SDQPF_DSTPORT_SHIFT	16
+
+#define IXGBE_L34TIMIR_RESERVE		0x00080000
+#define IXGBE_L34TIMIR_QUEUE_MASK	0x7f
+#define IXGBE_L34TIMIR_QUEUE_SHIFT	21
 
 /* Interrupt clear mask */
 #define IXGBE_IRQ_CLEAR_MASK	0xFFFFFFFF
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 8ed637b..3f8a5b1 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -146,6 +146,9 @@ static void 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_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config);
+static int ixgbe_5tuple_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+static int ixgbe_5tuple_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter);
+static int ixgbe_5tuple_del_filter(struct rte_eth_dev *dev, uint8_t filter_id);
 static int ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
 static int ixgbe_synq_get_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter);
 static int ixgbe_synq_del_filter(struct rte_eth_dev *dev);
@@ -285,6 +288,9 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.set_vf_rx            = ixgbe_set_pool_rx,
 	.set_vf_tx            = ixgbe_set_pool_tx,
 	.set_vf_vlan_filter   = ixgbe_set_pool_vlan_filter,
+	.add_5tuple_filter      = ixgbe_5tuple_add_filter,
+	.get_5tuple_filter      = ixgbe_5tuple_get_filter,
+	.del_5tuple_filter      = ixgbe_5tuple_del_filter,
 	.synq_add_filter          = ixgbe_synq_add_filter,
 	.synq_get_filter          = ixgbe_synq_get_filter,
 	.synq_del_filter          = ixgbe_synq_del_filter,
@@ -3074,6 +3080,115 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
 }
 
 static int
+ixgbe_5tuple_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t sdpqf, ftqf, l34timir = 0;
+	uint8_t mask = 0xff;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if (filter_id >= IXGBE_MAX_FTQF_FILTERS)
+		return (-ENOENT);
+
+	if (!(filter->priority && (filter->priority <= IXGBE_FTQF_MAX_PRIORITY)))
+		return (-EINVAL);
+
+	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(filter_id));
+	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE)
+		return(-ENOENT);
+	ftqf = 0;
+
+	sdpqf = ((filter->dst_port << IXGBE_SDQPF_DSTPORT_SHIFT) | filter->src_port);
+	ftqf = (filter->proto & IXGBE_FTQF_PROTOCOL_MASK);
+	ftqf |= ((filter->priority & IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
+	if (filter->mask & ETH_5TUPLE_MASK_SRCIP)
+		mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
+	if (filter->mask & ETH_5TUPLE_MASK_DSTIP)
+		mask &= IXGBE_FTQF_DEST_ADDR_MASK;
+	if (filter->mask & ETH_5TUPLE_MASK_SRCPORT)
+		mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
+	if (filter->mask & ETH_5TUPLE_MASK_DSTPORT)
+		mask &= IXGBE_FTQF_DEST_PORT_MASK;
+	if (filter->mask & ETH_5TUPLE_MASK_PROTO)
+		mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
+	ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
+
+	if (filter->mask & ETH_5TUPLE_MASK_POOL) {
+		if (ixgbe_vmdq_mode_check(hw) < 0)
+			return (-ENOTSUP);
+		ftqf &= ~IXGBE_FTQF_POOL_MASK_EN;
+		ftqf |= ((filter->pool & IXGBE_FTQF_POOL_MASK) << IXGBE_FTQF_POOL_SHIFT);
+	}
+	ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
+
+	l34timir = IXGBE_L34TIMIR_RESERVE;
+	l34timir |= ((filter->rx_queue & IXGBE_L34TIMIR_QUEUE_MASK) << IXGBE_L34TIMIR_QUEUE_SHIFT);
+
+	IXGBE_WRITE_REG(hw, IXGBE_SAQF(filter_id), filter->src);
+	IXGBE_WRITE_REG(hw, IXGBE_DAQF(filter_id), filter->dst);
+	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(filter_id), sdpqf);
+	IXGBE_WRITE_REG(hw, IXGBE_FTQF(filter_id), ftqf);
+	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(filter_id), l34timir);
+	return 0;
+}
+
+static int
+ixgbe_5tuple_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_5tuple_filter *filter)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	uint32_t sdpqf, ftqf, l34timir;
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if (filter_id >= IXGBE_MAX_FTQF_FILTERS)
+		return (-ENOENT);
+
+	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(filter_id));
+	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {
+		filter->proto = (enum rte_5tuple_proto)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);
+		filter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) & IXGBE_FTQF_PRIORITY_MASK;
+		filter->mask = ~(ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) & IXGBE_FTQF_5TUPLE_MASK_MASK;
+		if (!(ftqf & IXGBE_FTQF_POOL_MASK_EN)) {
+			filter->pool = (ftqf >> IXGBE_FTQF_POOL_SHIFT) & IXGBE_FTQF_POOL_MASK;
+			filter->mask |= ETH_5TUPLE_MASK_POOL;
+		}
+		filter->src = IXGBE_READ_REG(hw, IXGBE_SAQF(filter_id));
+		filter->dst = IXGBE_READ_REG(hw, IXGBE_DAQF(filter_id));
+		sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(filter_id));
+		filter->src_port = sdpqf & IXGBE_SDQPF_PORT_MASK;
+		filter->dst_port = (sdpqf >> IXGBE_SDQPF_DSTPORT_SHIFT) & IXGBE_SDQPF_PORT_MASK;
+		l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(filter_id));
+		filter->rx_queue = (l34timir >> IXGBE_L34TIMIR_QUEUE_SHIFT) & IXGBE_L34TIMIR_QUEUE_MASK;
+
+		return 0;
+	}
+	return (-ENOENT);
+}
+
+static int
+ixgbe_5tuple_del_filter(struct rte_eth_dev *dev, uint8_t filter_id)
+{
+	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (hw->mac.type != ixgbe_mac_82599EB)
+		return (-ENOSYS);
+
+	if (filter_id >= IXGBE_MAX_FTQF_FILTERS)
+		return (-ENOENT);
+
+	IXGBE_WRITE_REG(hw, IXGBE_SAQF(filter_id), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_DAQF(filter_id), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(filter_id), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_FTQF(filter_id), 0);
+	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(filter_id), 0);
+
+	return 0;
+}
+
+static int
 ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter)
 {
 	struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-- 
1.8.3.2

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

* Re: [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters
  2014-05-19 23:51 [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Vladimir Medvedkin
                   ` (2 preceding siblings ...)
  2014-05-19 23:51 ` [dpdk-dev] [PATCH 3/3] ixgbe: Add five tuple " Vladimir Medvedkin
@ 2014-05-27 23:09 ` Thomas Monjalon
  2014-06-04  9:58   ` Vladimir Medvedkin
  3 siblings, 1 reply; 6+ messages in thread
From: Thomas Monjalon @ 2014-05-27 23:09 UTC (permalink / raw)
  To: Vladimir Medvedkin; +Cc: dev

Hi Vladimir,

Seems like hardware filtering becomes useful these days :)

2014-05-19 19:51, Vladimir Medvedkin:
> This patchset adds in addition to the Flow Director filters L2 Ethertype,
> SYN and Five tuple queue filters to route packets according to ethertype,
> l4 proto, source/destination ip/ports pool and presence of SYN flag in TCP
> packet. Unlike http://dpdk.org/ml/archives/dev/2014-May/002512.html this
> gives capability to work with pools. This patch functionality can be merged
> with the patch above.

2 comments:

1) Do you have a good confidence that this new API is generic enough to be 
used by other NICs than ixgbe?

2) Could you try to check your patches with the kernel script checkpatch.pl, 
please?

Thanks
-- 
Thomas

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

* Re: [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters
  2014-05-27 23:09 ` [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Thomas Monjalon
@ 2014-06-04  9:58   ` Vladimir Medvedkin
  0 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2014-06-04  9:58 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi Thomas,

Sorry for late reply, I'm on vacation now.

1. I'm not shure about other NICs but Intel. API for Intel NICs is generic
enough, even more generic than Jingjing's API because of pool logic.
Besides I think it's more properly make rx_queue as part of filter struct
for Jingjing's etype and 5-tuple filters implementation.

2. I'll try to send checked patch today.

Regards,
Vladimir.


2014-05-28 3:09 GMT+04:00 Thomas Monjalon <thomas.monjalon@6wind.com>:

> Hi Vladimir,
>
> Seems like hardware filtering becomes useful these days :)
>
> 2014-05-19 19:51, Vladimir Medvedkin:
> > This patchset adds in addition to the Flow Director filters L2 Ethertype,
> > SYN and Five tuple queue filters to route packets according to ethertype,
> > l4 proto, source/destination ip/ports pool and presence of SYN flag in
> TCP
> > packet. Unlike http://dpdk.org/ml/archives/dev/2014-May/002512.html this
> > gives capability to work with pools. This patch functionality can be
> merged
> > with the patch above.
>
> 2 comments:
>
> 1) Do you have a good confidence that this new API is generic enough to be
> used by other NICs than ixgbe?
>
> 2) Could you try to check your patches with the kernel script
> checkpatch.pl,
> please?
>
> Thanks
> --
> Thomas
>

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

end of thread, other threads:[~2014-06-04  9:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 23:51 [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Vladimir Medvedkin
2014-05-19 23:51 ` [dpdk-dev] [PATCH 1/3] ixgbe: Add L2 ethertype filter for ixgbe Vladimir Medvedkin
2014-05-19 23:51 ` [dpdk-dev] [PATCH 2/3] ixgbe: Add syn queue " Vladimir Medvedkin
2014-05-19 23:51 ` [dpdk-dev] [PATCH 3/3] ixgbe: Add five tuple " Vladimir Medvedkin
2014-05-27 23:09 ` [dpdk-dev] [PATCH 0/3] ixgbe: Add L2 Ethertype, SYN and Five tuple queue filters Thomas Monjalon
2014-06-04  9:58   ` Vladimir Medvedkin

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).