From: Jingjing Wu <jingjing.wu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v3 3/6] e1000: ntuple filter functions replace old ones for 2tuple and 5tuple filter
Date: Tue, 10 Feb 2015 12:48:30 +0800 [thread overview]
Message-ID: <1423543713-21624-4-git-send-email-jingjing.wu@intel.com> (raw)
In-Reply-To: <1423543713-21624-1-git-send-email-jingjing.wu@intel.com>
This patch defines new functions dealing with ntuple filters which is
corresponding to 2tuple filter for 82580 and i350 in HW, and to 5tuple
filter for 82576 in HW.
It removes old functions which deal with 2tuple and 5tuple filters in igb driver.
Ntuple filter is dealt with through entrance eth_igb_filter_ctrl.
Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
lib/librte_pmd_e1000/e1000_ethdev.h | 69 ++-
lib/librte_pmd_e1000/igb_ethdev.c | 869 ++++++++++++++++++++++++------------
2 files changed, 647 insertions(+), 291 deletions(-)
diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..571a70d 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -67,14 +67,6 @@
#define E1000_IMIR_DSTPORT 0x0000FFFF
#define E1000_IMIR_PRIORITY 0xE0000000
-#define E1000_IMIR_EXT_SIZE_BP 0x00001000
-#define E1000_IMIR_EXT_CTRL_UGR 0x00002000
-#define E1000_IMIR_EXT_CTRL_ACK 0x00004000
-#define E1000_IMIR_EXT_CTRL_PSH 0x00008000
-#define E1000_IMIR_EXT_CTRL_RST 0x00010000
-#define E1000_IMIR_EXT_CTRL_SYN 0x00020000
-#define E1000_IMIR_EXT_CTRL_FIN 0x00040000
-#define E1000_IMIR_EXT_CTRL_BP 0x00080000
#define E1000_MAX_TTQF_FILTERS 8
#define E1000_2TUPLE_MAX_PRI 7
@@ -96,11 +88,6 @@
#define E1000_MAX_FTQF_FILTERS 8
#define E1000_FTQF_PROTOCOL_MASK 0x000000FF
#define E1000_FTQF_5TUPLE_MASK_SHIFT 28
-#define E1000_FTQF_PROTOCOL_COMP_MASK 0x10000000
-#define E1000_FTQF_SOURCE_ADDR_MASK 0x20000000
-#define E1000_FTQF_DEST_ADDR_MASK 0x40000000
-#define E1000_FTQF_SOURCE_PORT_MASK 0x80000000
-#define E1000_FTQF_VF_MASK_EN 0x00008000
#define E1000_FTQF_QUEUE_MASK 0x03ff0000
#define E1000_FTQF_QUEUE_SHIFT 16
#define E1000_FTQF_QUEUE_ENABLE 0x00000100
@@ -131,6 +118,56 @@ struct e1000_vf_info {
uint16_t tx_rate;
};
+TAILQ_HEAD(e1000_5tuple_filter_list, e1000_5tuple_filter);
+TAILQ_HEAD(e1000_2tuple_filter_list, e1000_2tuple_filter);
+
+struct e1000_5tuple_filter_info {
+ uint32_t dst_ip;
+ uint32_t src_ip;
+ uint16_t dst_port;
+ uint16_t src_port;
+ uint8_t proto; /* l4 protocol. */
+ /* the packet matched above 5tuple and contain any set bit will hit this filter. */
+ uint8_t tcp_flags;
+ uint8_t priority; /* seven levels (001b-111b), 111b is highest,
+ used when more than one filter matches. */
+ uint8_t dst_ip_mask:1, /* if mask is 1b, do not compare dst ip. */
+ src_ip_mask:1, /* if mask is 1b, do not compare src ip. */
+ dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+ src_port_mask:1, /* if mask is 1b, do not compare src port. */
+ proto_mask:1; /* if mask is 1b, do not compare protocol. */
+};
+
+struct e1000_2tuple_filter_info {
+ uint16_t dst_port;
+ uint8_t proto; /* l4 protocol. */
+ /* the packet matched above 2tuple and contain any set bit will hit this filter. */
+ uint8_t tcp_flags;
+ uint8_t priority; /* seven levels (001b-111b), 111b is highest,
+ used when more than one filter matches. */
+ uint8_t dst_ip_mask:1, /* if mask is 1b, do not compare dst ip. */
+ src_ip_mask:1, /* if mask is 1b, do not compare src ip. */
+ dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+ src_port_mask:1, /* if mask is 1b, do not compare src port. */
+ proto_mask:1; /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct e1000_5tuple_filter {
+ TAILQ_ENTRY(e1000_5tuple_filter) entries;
+ uint16_t index; /* the index of 5tuple filter */
+ struct e1000_5tuple_filter_info filter_info;
+ uint16_t queue; /* rx queue assigned to */
+};
+
+/* 2tuple filter structure */
+struct e1000_2tuple_filter {
+ TAILQ_ENTRY(e1000_2tuple_filter) entries;
+ uint16_t index; /* the index of 2tuple filter */
+ struct e1000_2tuple_filter_info filter_info;
+ uint16_t queue; /* rx queue assigned to */
+};
+
/*
* Structure to store filters' info.
*/
@@ -138,6 +175,12 @@ struct e1000_filter_info {
uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
/* store used ethertype filters*/
uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+ /* Bit mask for every used 5tuple filter */
+ uint8_t fivetuple_mask;
+ struct e1000_5tuple_filter_list fivetuple_list;
+ /* Bit mask for every used 2tuple filter */
+ uint8_t twotuple_mask;
+ struct e1000_2tuple_filter_list twotuple_list;
};
/*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 2a268b8..51f47cc 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -154,14 +154,10 @@ static int eth_igb_add_syn_filter(struct rte_eth_dev *dev,
static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev);
static int eth_igb_get_syn_filter(struct rte_eth_dev *dev,
struct rte_syn_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev,
- uint16_t index,
- struct rte_2tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
- uint16_t index);
-static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
- uint16_t index,
- struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_2tuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter);
static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
uint16_t index,
struct rte_flex_filter *filter, uint16_t rx_queue);
@@ -170,14 +166,18 @@ static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
uint16_t index,
struct rte_flex_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
- uint16_t index,
- struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
- uint16_t index);
-static int eth_igb_get_5tuple_filter(struct rte_eth_dev *dev,
- uint16_t index,
- struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *filter,
+ bool add);
+static int igb_get_ntuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *filter);
+static int igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+ enum rte_filter_op filter_op,
+ void *arg);
static int igb_add_del_ethertype_filter(struct rte_eth_dev *dev,
struct rte_eth_ethertype_filter *filter,
bool add);
@@ -268,15 +268,9 @@ static struct eth_dev_ops eth_igb_ops = {
.add_syn_filter = eth_igb_add_syn_filter,
.remove_syn_filter = eth_igb_remove_syn_filter,
.get_syn_filter = eth_igb_get_syn_filter,
- .add_2tuple_filter = eth_igb_add_2tuple_filter,
- .remove_2tuple_filter = eth_igb_remove_2tuple_filter,
- .get_2tuple_filter = eth_igb_get_2tuple_filter,
.add_flex_filter = eth_igb_add_flex_filter,
.remove_flex_filter = eth_igb_remove_flex_filter,
.get_flex_filter = eth_igb_get_flex_filter,
- .add_5tuple_filter = eth_igb_add_5tuple_filter,
- .remove_5tuple_filter = eth_igb_remove_5tuple_filter,
- .get_5tuple_filter = eth_igb_get_5tuple_filter,
.filter_ctrl = eth_igb_filter_ctrl,
};
@@ -470,6 +464,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
struct e1000_vfta * shadow_vfta =
E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
uint32_t ctrl_ext;
pci_dev = eth_dev->pci_dev;
@@ -601,6 +597,12 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
/* enable support intr */
igb_intr_enable(eth_dev);
+ /* initialize ntuple filter list */
+ TAILQ_INIT(&filter_info->twotuple_list);
+ filter_info->twotuple_mask = 0;
+ TAILQ_INIT(&filter_info->fivetuple_list);
+ filter_info->fivetuple_mask = 0;
+
return 0;
err_late:
@@ -926,7 +928,11 @@ static void
eth_igb_stop(struct rte_eth_dev *dev)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
struct rte_eth_link link;
+ struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
+ struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
igb_intr_disable(hw);
igb_pf_reset_hw(hw);
@@ -949,6 +955,24 @@ eth_igb_stop(struct rte_eth_dev *dev)
/* clear the recorded link status */
memset(&link, 0, sizeof(link));
rte_igb_dev_atomic_write_link_status(dev, &link);
+
+ /* Remove all ntuple filters of the device */
+ for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+ p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+ p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+ TAILQ_REMOVE(&filter_info->fivetuple_list,
+ p_5tuple, entries);
+ rte_free(p_5tuple);
+ }
+ filter_info->fivetuple_mask = 0;
+ for (p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list);
+ p_2tuple != NULL; p_2tuple = p_2tuple_next) {
+ p_2tuple_next = TAILQ_NEXT(p_2tuple, entries);
+ TAILQ_REMOVE(&filter_info->twotuple_list,
+ p_2tuple, entries);
+ rte_free(p_2tuple);
+ }
+ filter_info->twotuple_mask = 0;
}
static void
@@ -2491,165 +2515,209 @@ eth_igb_get_syn_filter(struct rte_eth_dev *dev,
return -ENOSYS; \
} while (0)
-/*
- * add a 2tuple filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that will be added.
- * rx_queue: the queue id the filter assigned to.
- *
- * @return
- * - On success, zero.
- * - On failure, a negative value.
- */
-static int
-eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
- struct rte_2tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_2tuple_filter_info*/
+static inline int
+ntuple_filter_to_2tuple(struct rte_eth_ntuple_filter *filter,
+ struct e1000_2tuple_filter_info *filter_info)
{
- struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint32_t ttqf, imir = 0;
- uint32_t imir_ext = 0;
-
- MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
- if (index >= E1000_MAX_TTQF_FILTERS ||
- rx_queue >= IGB_MAX_RX_QUEUE_NUM ||
- filter->priority > E1000_2TUPLE_MAX_PRI)
+ if (filter->queue >= IGB_MAX_RX_QUEUE_NUM)
+ return -EINVAL;
+ if (filter->priority > E1000_2TUPLE_MAX_PRI)
return -EINVAL; /* filter index is out of range. */
- if (filter->tcp_flags > TCP_FLAG_ALL)
+ if (filter->tcp_flags > TCP_FLAG_ALL)
return -EINVAL; /* flags is invalid. */
- ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
- if (ttqf & E1000_TTQF_QUEUE_ENABLE)
- return -EINVAL; /* filter index is in use. */
-
- imir = (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
- if (filter->dst_port_mask == 1) /* 1b means not compare. */
- imir |= E1000_IMIR_PORT_BP;
- else
- imir &= ~E1000_IMIR_PORT_BP;
+ switch (filter->dst_port_mask) {
+ case UINT16_MAX:
+ filter_info->dst_port_mask = 0;
+ filter_info->dst_port = filter->dst_port;
+ break;
+ case 0:
+ filter_info->dst_port_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid dst_port mask.");
+ return -EINVAL;
+ }
- imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+ switch (filter->proto_mask) {
+ case UINT8_MAX:
+ filter_info->proto_mask = 0;
+ filter_info->proto = filter->proto;
+ break;
+ case 0:
+ filter_info->proto_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid protocol mask.");
+ return -EINVAL;
+ }
- ttqf = 0;
- ttqf |= E1000_TTQF_QUEUE_ENABLE;
- ttqf |= (uint32_t)(rx_queue << E1000_TTQF_QUEUE_SHIFT);
- ttqf |= (uint32_t)(filter->protocol & E1000_TTQF_PROTOCOL_MASK);
- if (filter->protocol_mask == 1)
- ttqf |= E1000_TTQF_MASK_ENABLE;
+ filter_info->priority = (uint8_t)filter->priority;
+ if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+ filter_info->tcp_flags = filter->tcp_flags;
else
- ttqf &= ~E1000_TTQF_MASK_ENABLE;
+ filter_info->tcp_flags = 0;
- imir_ext |= E1000_IMIR_EXT_SIZE_BP;
- /* tcp flags bits setting. */
- if (filter->tcp_flags & TCP_FLAG_ALL) {
- if (filter->tcp_flags & TCP_UGR_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
- if (filter->tcp_flags & TCP_ACK_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
- if (filter->tcp_flags & TCP_PSH_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
- if (filter->tcp_flags & TCP_RST_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_RST;
- if (filter->tcp_flags & TCP_SYN_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
- if (filter->tcp_flags & TCP_FIN_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
- imir_ext &= ~E1000_IMIR_EXT_CTRL_BP;
- } else
- imir_ext |= E1000_IMIR_EXT_CTRL_BP;
- E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
- E1000_WRITE_REG(hw, E1000_TTQF(index), ttqf);
- E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
return 0;
}
+static inline struct e1000_2tuple_filter *
+igb_2tuple_filter_lookup(struct e1000_2tuple_filter_list *filter_list,
+ struct e1000_2tuple_filter_info *key)
+{
+ struct e1000_2tuple_filter *it;
+
+ TAILQ_FOREACH(it, filter_list, entries) {
+ if (memcmp(key, &it->filter_info,
+ sizeof(struct e1000_2tuple_filter_info)) == 0) {
+ return it;
+ }
+ }
+ return NULL;
+}
+
/*
- * remove a 2tuple filter
+ * igb_add_2tuple_filter - add a 2tuple filter
*
* @param
* dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
+ * ntuple_filter: ponter to the filter that will be added.
*
* @return
* - On success, zero.
* - On failure, a negative value.
*/
static int
-eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
- uint16_t index)
+igb_add_2tuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct e1000_2tuple_filter *filter;
+ uint32_t ttqf = E1000_TTQF_DISABLE_MASK;
+ uint32_t imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+ int i, ret;
+
+ filter = rte_zmalloc("e1000_2tuple_filter",
+ sizeof(struct e1000_2tuple_filter), 0);
+ if (filter == NULL)
+ return -ENOMEM;
- MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+ ret = ntuple_filter_to_2tuple(ntuple_filter,
+ &filter->filter_info);
+ if (ret < 0) {
+ rte_free(filter);
+ return ret;
+ }
+ if (igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+ &filter->filter_info) != NULL) {
+ PMD_DRV_LOG(ERR, "filter exists.");
+ rte_free(filter);
+ return -EEXIST;
+ }
+ filter->queue = ntuple_filter->queue;
- if (index >= E1000_MAX_TTQF_FILTERS)
- return -EINVAL; /* filter index is out of range */
+ /*
+ * look for an unused 2tuple filter index,
+ * and insert the filter to list.
+ */
+ for (i = 0; i < E1000_MAX_TTQF_FILTERS; i++) {
+ if (!(filter_info->twotuple_mask & (1 << i))) {
+ filter_info->twotuple_mask |= 1 << i;
+ filter->index = i;
+ TAILQ_INSERT_TAIL(&filter_info->twotuple_list,
+ filter,
+ entries);
+ break;
+ }
+ }
+ if (i >= E1000_MAX_TTQF_FILTERS) {
+ PMD_DRV_LOG(ERR, "2tuple filters are full.");
+ rte_free(filter);
+ return -ENOSYS;
+ }
+
+ imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+ if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+ imir |= E1000_IMIR_PORT_BP;
+ else
+ imir &= ~E1000_IMIR_PORT_BP;
- E1000_WRITE_REG(hw, E1000_TTQF(index), 0);
- E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
- E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+ imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+ ttqf |= E1000_TTQF_QUEUE_ENABLE;
+ ttqf |= (uint32_t)(filter->queue << E1000_TTQF_QUEUE_SHIFT);
+ ttqf |= (uint32_t)(filter->filter_info.proto & E1000_TTQF_PROTOCOL_MASK);
+ if (filter->filter_info.proto_mask == 0)
+ ttqf &= ~E1000_TTQF_MASK_ENABLE;
+
+ /* tcp flags bits setting. */
+ if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+ if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_URG;
+ if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_ACK;
+ if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_PSH;
+ if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_RST;
+ if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_SYN;
+ if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_FIN;
+ } else
+ imir_ext |= E1000_IMIREXT_CTRL_BP;
+ E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+ E1000_WRITE_REG(hw, E1000_TTQF(i), ttqf);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
return 0;
}
/*
- * get a 2tuple filter
+ * igb_remove_2tuple_filter - remove a 2tuple filter
*
* @param
* dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
+ * ntuple_filter: ponter to the filter that will be removed.
*
* @return
* - On success, zero.
* - On failure, a negative value.
*/
static int
-eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
- struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint32_t imir, ttqf, imir_ext;
-
- MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct e1000_2tuple_filter_info filter_2tuple;
+ struct e1000_2tuple_filter *filter;
+ int ret;
- if (index >= E1000_MAX_TTQF_FILTERS)
- return -EINVAL; /* filter index is out of range. */
+ memset(&filter_2tuple, 0, sizeof(struct e1000_2tuple_filter_info));
+ ret = ntuple_filter_to_2tuple(ntuple_filter,
+ &filter_2tuple);
+ if (ret < 0)
+ return ret;
- ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
- if (ttqf & E1000_TTQF_QUEUE_ENABLE) {
- imir = E1000_READ_REG(hw, E1000_IMIR(index));
- filter->protocol = ttqf & E1000_TTQF_PROTOCOL_MASK;
- filter->protocol_mask = (ttqf & E1000_TTQF_MASK_ENABLE) ? 1 : 0;
- *rx_queue = (ttqf & E1000_TTQF_RX_QUEUE_MASK) >>
- E1000_TTQF_QUEUE_SHIFT;
- filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
- filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
- filter->priority = (imir & E1000_IMIR_PRIORITY) >>
- E1000_IMIR_PRIORITY_SHIFT;
-
- imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
- if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
- if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
- filter->tcp_flags |= TCP_UGR_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
- filter->tcp_flags |= TCP_ACK_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
- filter->tcp_flags |= TCP_PSH_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
- filter->tcp_flags |= TCP_RST_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
- filter->tcp_flags |= TCP_SYN_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
- filter->tcp_flags |= TCP_FIN_FLAG;
- } else
- filter->tcp_flags = 0;
- return 0;
+ filter = igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+ &filter_2tuple);
+ if (filter == NULL) {
+ PMD_DRV_LOG(ERR, "filter doesn't exist.");
+ return -ENOENT;
}
- return -ENOENT;
+
+ filter_info->twotuple_mask &= ~(1 << filter->index);
+ TAILQ_REMOVE(&filter_info->twotuple_list, filter, entries);
+ rte_free(filter);
+
+ E1000_WRITE_REG(hw, E1000_TTQF(filter->index), E1000_TTQF_DISABLE_MASK);
+ E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+ return 0;
}
/*
@@ -2807,192 +2875,265 @@ eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
return -ENOENT;
}
-/*
- * add a 5tuple filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that will be added.
- * rx_queue: the queue id the filter assigned to.
- *
- * @return
- * - On success, zero.
- * - On failure, a negative value.
- */
-static int
-eth_igb_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
- struct rte_5tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple_82576(struct rte_eth_ntuple_filter *filter,
+ struct e1000_5tuple_filter_info *filter_info)
{
- struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint32_t ftqf, spqf = 0;
- uint32_t imir = 0;
- uint32_t imir_ext = 0;
+ if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576)
+ return -EINVAL;
+ if (filter->priority > E1000_2TUPLE_MAX_PRI)
+ return -EINVAL; /* filter index is out of range. */
+ if (filter->tcp_flags > TCP_FLAG_ALL)
+ return -EINVAL; /* flags is invalid. */
- if (hw->mac.type != e1000_82576)
- return -ENOSYS;
+ switch (filter->dst_ip_mask) {
+ case UINT32_MAX:
+ filter_info->dst_ip_mask = 0;
+ filter_info->dst_ip = filter->dst_ip;
+ break;
+ case 0:
+ filter_info->dst_ip_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid dst_ip mask.");
+ return -EINVAL;
+ }
- if (index >= E1000_MAX_FTQF_FILTERS ||
- rx_queue >= IGB_MAX_RX_QUEUE_NUM_82576)
- return -EINVAL; /* filter index is out of range. */
+ switch (filter->src_ip_mask) {
+ case UINT32_MAX:
+ filter_info->src_ip_mask = 0;
+ filter_info->src_ip = filter->src_ip;
+ break;
+ case 0:
+ filter_info->src_ip_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid src_ip mask.");
+ return -EINVAL;
+ }
- ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
- if (ftqf & E1000_FTQF_QUEUE_ENABLE)
- return -EINVAL; /* filter index is in use. */
-
- ftqf = 0;
- ftqf |= filter->protocol & E1000_FTQF_PROTOCOL_MASK;
- if (filter->src_ip_mask == 1) /* 1b means not compare. */
- ftqf |= E1000_FTQF_SOURCE_ADDR_MASK;
- if (filter->dst_ip_mask == 1)
- ftqf |= E1000_FTQF_DEST_ADDR_MASK;
- if (filter->src_port_mask == 1)
- ftqf |= E1000_FTQF_SOURCE_PORT_MASK;
- if (filter->protocol_mask == 1)
- ftqf |= E1000_FTQF_PROTOCOL_COMP_MASK;
- ftqf |= (rx_queue << E1000_FTQF_QUEUE_SHIFT) & E1000_FTQF_QUEUE_MASK;
- ftqf |= E1000_FTQF_VF_MASK_EN;
- ftqf |= E1000_FTQF_QUEUE_ENABLE;
- E1000_WRITE_REG(hw, E1000_FTQF(index), ftqf);
- E1000_WRITE_REG(hw, E1000_DAQF(index), filter->dst_ip);
- E1000_WRITE_REG(hw, E1000_SAQF(index), filter->src_ip);
+ switch (filter->dst_port_mask) {
+ case UINT16_MAX:
+ filter_info->dst_port_mask = 0;
+ filter_info->dst_port = filter->dst_port;
+ break;
+ case 0:
+ filter_info->dst_port_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid dst_port mask.");
+ return -EINVAL;
+ }
+
+ switch (filter->src_port_mask) {
+ case UINT16_MAX:
+ filter_info->src_port_mask = 0;
+ filter_info->src_port = filter->src_port;
+ break;
+ case 0:
+ filter_info->src_port_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid src_port mask.");
+ return -EINVAL;
+ }
- spqf |= filter->src_port & E1000_SPQF_SRCPORT;
- E1000_WRITE_REG(hw, E1000_SPQF(index), spqf);
+ switch (filter->proto_mask) {
+ case UINT8_MAX:
+ filter_info->proto_mask = 0;
+ filter_info->proto = filter->proto;
+ break;
+ case 0:
+ filter_info->proto_mask = 1;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "invalid protocol mask.");
+ return -EINVAL;
+ }
- imir |= (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
- if (filter->dst_port_mask == 1) /* 1b means not compare. */
- imir |= E1000_IMIR_PORT_BP;
+ filter_info->priority = (uint8_t)filter->priority;
+ if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+ filter_info->tcp_flags = filter->tcp_flags;
else
- imir &= ~E1000_IMIR_PORT_BP;
- imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+ filter_info->tcp_flags = 0;
- imir_ext |= E1000_IMIR_EXT_SIZE_BP;
- /* tcp flags bits setting. */
- if (filter->tcp_flags & TCP_FLAG_ALL) {
- if (filter->tcp_flags & TCP_UGR_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
- if (filter->tcp_flags & TCP_ACK_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
- if (filter->tcp_flags & TCP_PSH_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
- if (filter->tcp_flags & TCP_RST_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_RST;
- if (filter->tcp_flags & TCP_SYN_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
- if (filter->tcp_flags & TCP_FIN_FLAG)
- imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
- } else
- imir_ext |= E1000_IMIR_EXT_CTRL_BP;
- E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
- E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
return 0;
}
+static inline struct e1000_5tuple_filter *
+igb_5tuple_filter_lookup_82576(struct e1000_5tuple_filter_list *filter_list,
+ struct e1000_5tuple_filter_info *key)
+{
+ struct e1000_5tuple_filter *it;
+
+ TAILQ_FOREACH(it, filter_list, entries) {
+ if (memcmp(key, &it->filter_info,
+ sizeof(struct e1000_5tuple_filter_info)) == 0) {
+ return it;
+ }
+ }
+ return NULL;
+}
+
/*
- * remove a 5tuple filter
+ * igb_add_5tuple_filter_82576 - add a 5tuple filter
*
* @param
* dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
+ * ntuple_filter: ponter to the filter that will be added.
*
* @return
* - On success, zero.
* - On failure, a negative value.
*/
static int
-eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
- uint16_t index)
+igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct e1000_5tuple_filter *filter;
+ uint32_t ftqf = E1000_FTQF_VF_BP | E1000_FTQF_MASK;
+ uint32_t spqf, imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+ uint8_t i;
+ int ret;
+
+ filter = rte_zmalloc("e1000_5tuple_filter",
+ sizeof(struct e1000_5tuple_filter), 0);
+ if (filter == NULL)
+ return -ENOMEM;
+
+ ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+ &filter->filter_info);
+ if (ret < 0) {
+ rte_free(filter);
+ return ret;
+ }
- if (hw->mac.type != e1000_82576)
+ if (igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+ &filter->filter_info) != NULL) {
+ PMD_DRV_LOG(ERR, "filter exists.");
+ rte_free(filter);
+ return -EEXIST;
+ }
+ filter->queue = ntuple_filter->queue;
+
+ /*
+ * look for an unused 5tuple filter index,
+ * and insert the filter to list.
+ */
+ for (i = 0; i < E1000_MAX_FTQF_FILTERS; i++) {
+ if (!(filter_info->fivetuple_mask & (1 << i))) {
+ filter_info->fivetuple_mask |= 1 << i;
+ filter->index = i;
+ TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
+ filter,
+ entries);
+ break;
+ }
+ }
+ if (i >= E1000_MAX_FTQF_FILTERS) {
+ PMD_DRV_LOG(ERR, "5tuple filters are full.");
+ rte_free(filter);
return -ENOSYS;
+ }
- if (index >= E1000_MAX_FTQF_FILTERS)
- return -EINVAL; /* filter index is out of range. */
+ ftqf |= filter->filter_info.proto & E1000_FTQF_PROTOCOL_MASK;
+ if (filter->filter_info.src_ip_mask == 0) /* 0b means compare. */
+ ftqf &= ~E1000_FTQF_MASK_SOURCE_ADDR_BP;
+ if (filter->filter_info.dst_ip_mask == 0)
+ ftqf &= ~E1000_FTQF_MASK_DEST_ADDR_BP;
+ if (filter->filter_info.src_port_mask == 0)
+ ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+ if (filter->filter_info.proto_mask == 0)
+ ftqf &= ~E1000_FTQF_MASK_PROTO_BP;
+ ftqf |= (filter->queue << E1000_FTQF_QUEUE_SHIFT) &
+ E1000_FTQF_QUEUE_MASK;
+ ftqf |= E1000_FTQF_QUEUE_ENABLE;
+ E1000_WRITE_REG(hw, E1000_FTQF(i), ftqf);
+ E1000_WRITE_REG(hw, E1000_DAQF(i), filter->filter_info.dst_ip);
+ E1000_WRITE_REG(hw, E1000_SAQF(i), filter->filter_info.src_ip);
+
+ spqf = filter->filter_info.src_port & E1000_SPQF_SRCPORT;
+ E1000_WRITE_REG(hw, E1000_SPQF(i), spqf);
- E1000_WRITE_REG(hw, E1000_FTQF(index), 0);
- E1000_WRITE_REG(hw, E1000_DAQF(index), 0);
- E1000_WRITE_REG(hw, E1000_SAQF(index), 0);
- E1000_WRITE_REG(hw, E1000_SPQF(index), 0);
- E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
- E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+ imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+ if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+ imir |= E1000_IMIR_PORT_BP;
+ else
+ imir &= ~E1000_IMIR_PORT_BP;
+ imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+ /* tcp flags bits setting. */
+ if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+ if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_URG;
+ if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_ACK;
+ if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_PSH;
+ if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_RST;
+ if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_SYN;
+ if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+ imir_ext |= E1000_IMIREXT_CTRL_FIN;
+ } else
+ imir_ext |= E1000_IMIREXT_CTRL_BP;
+ E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
return 0;
}
/*
- * get a 5tuple filter
+ * igb_remove_5tuple_filter_82576 - remove a 5tuple filter
*
* @param
* dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns
- * *rx_queue: pointer of the queue id the filter assigned to
+ * ntuple_filter: ponter to the filter that will be removed.
*
* @return
* - On success, zero.
* - On failure, a negative value.
*/
static int
-eth_igb_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
- struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- uint32_t spqf, ftqf, imir, imir_ext;
-
- if (hw->mac.type != e1000_82576)
- return -ENOSYS;
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct e1000_5tuple_filter_info filter_5tuple;
+ struct e1000_5tuple_filter *filter;
+ int ret;
- if (index >= E1000_MAX_FTQF_FILTERS)
- return -EINVAL; /* filter index is out of range. */
+ memset(&filter_5tuple, 0, sizeof(struct e1000_5tuple_filter_info));
+ ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+ &filter_5tuple);
+ if (ret < 0)
+ return ret;
- ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
- if (ftqf & E1000_FTQF_QUEUE_ENABLE) {
- filter->src_ip_mask =
- (ftqf & E1000_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
- filter->dst_ip_mask =
- (ftqf & E1000_FTQF_DEST_ADDR_MASK) ? 1 : 0;
- filter->src_port_mask =
- (ftqf & E1000_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
- filter->protocol_mask =
- (ftqf & E1000_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
- filter->protocol =
- (uint8_t)ftqf & E1000_FTQF_PROTOCOL_MASK;
- *rx_queue = (uint16_t)((ftqf & E1000_FTQF_QUEUE_MASK) >>
- E1000_FTQF_QUEUE_SHIFT);
-
- spqf = E1000_READ_REG(hw, E1000_SPQF(index));
- filter->src_port = spqf & E1000_SPQF_SRCPORT;
-
- filter->dst_ip = E1000_READ_REG(hw, E1000_DAQF(index));
- filter->src_ip = E1000_READ_REG(hw, E1000_SAQF(index));
-
- imir = E1000_READ_REG(hw, E1000_IMIR(index));
- filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
- filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
- filter->priority = (imir & E1000_IMIR_PRIORITY) >>
- E1000_IMIR_PRIORITY_SHIFT;
-
- imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
- if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
- if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
- filter->tcp_flags |= TCP_UGR_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
- filter->tcp_flags |= TCP_ACK_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
- filter->tcp_flags |= TCP_PSH_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
- filter->tcp_flags |= TCP_RST_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
- filter->tcp_flags |= TCP_SYN_FLAG;
- if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
- filter->tcp_flags |= TCP_FIN_FLAG;
- } else
- filter->tcp_flags = 0;
- return 0;
+ filter = igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+ &filter_5tuple);
+ if (filter == NULL) {
+ PMD_DRV_LOG(ERR, "filter doesn't exist.");
+ return -ENOENT;
}
- return -ENOENT;
+
+ filter_info->fivetuple_mask &= ~(1 << filter->index);
+ TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+ rte_free(filter);
+
+ E1000_WRITE_REG(hw, E1000_FTQF(filter->index),
+ E1000_FTQF_VF_BP | E1000_FTQF_MASK);
+ E1000_WRITE_REG(hw, E1000_DAQF(filter->index), 0);
+ E1000_WRITE_REG(hw, E1000_SAQF(filter->index), 0);
+ E1000_WRITE_REG(hw, E1000_SPQF(filter->index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+ return 0;
}
static int
@@ -3045,6 +3186,175 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
return 0;
}
+/*
+ * igb_add_del_ntuple_filter - add or delete a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ * add: if true, add filter, if false, remove filter
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter,
+ bool add)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
+
+ switch (ntuple_filter->flags) {
+ case RTE_5TUPLE_FLAGS:
+ case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+ if (hw->mac.type != e1000_82576)
+ return -ENOTSUP;
+ if (add)
+ ret = igb_add_5tuple_filter_82576(dev,
+ ntuple_filter);
+ else
+ ret = igb_remove_5tuple_filter_82576(dev,
+ ntuple_filter);
+ break;
+ case RTE_2TUPLE_FLAGS:
+ case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+ if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+ return -ENOTSUP;
+ if (add)
+ ret = igb_add_2tuple_filter(dev, ntuple_filter);
+ else
+ ret = igb_remove_2tuple_filter(dev, ntuple_filter);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * igb_get_ntuple_filter - get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+igb_get_ntuple_filter(struct rte_eth_dev *dev,
+ struct rte_eth_ntuple_filter *ntuple_filter)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_filter_info *filter_info =
+ E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct e1000_5tuple_filter_info filter_5tuple;
+ struct e1000_2tuple_filter_info filter_2tuple;
+ struct e1000_5tuple_filter *p_5tuple_filter;
+ struct e1000_2tuple_filter *p_2tuple_filter;
+ int ret;
+
+ switch (ntuple_filter->flags) {
+ case RTE_5TUPLE_FLAGS:
+ case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+ if (hw->mac.type != e1000_82576)
+ return -ENOTSUP;
+ memset(&filter_5tuple,
+ 0,
+ sizeof(struct e1000_5tuple_filter_info));
+ ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+ &filter_5tuple);
+ if (ret < 0)
+ return ret;
+ p_5tuple_filter = igb_5tuple_filter_lookup_82576(
+ &filter_info->fivetuple_list,
+ &filter_5tuple);
+ if (p_5tuple_filter == NULL) {
+ PMD_DRV_LOG(ERR, "filter doesn't exist.");
+ return -ENOENT;
+ }
+ ntuple_filter->queue = p_5tuple_filter->queue;
+ break;
+ case RTE_2TUPLE_FLAGS:
+ case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+ if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+ return -ENOTSUP;
+ memset(&filter_2tuple,
+ 0,
+ sizeof(struct e1000_2tuple_filter_info));
+ ret = ntuple_filter_to_2tuple(ntuple_filter, &filter_2tuple);
+ if (ret < 0)
+ return ret;
+ p_2tuple_filter = igb_2tuple_filter_lookup(
+ &filter_info->twotuple_list,
+ &filter_2tuple);
+ if (p_2tuple_filter == NULL) {
+ PMD_DRV_LOG(ERR, "filter doesn't exist.");
+ return -ENOENT;
+ }
+ ntuple_filter->queue = p_2tuple_filter->queue;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * igb_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ */
+static int
+igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ if (filter_op == RTE_ETH_FILTER_NOP)
+ return 0;
+
+ if (arg == NULL) {
+ PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+ filter_op);
+ return -EINVAL;
+ }
+
+ switch (filter_op) {
+ case RTE_ETH_FILTER_ADD:
+ ret = igb_add_del_ntuple_filter(dev,
+ (struct rte_eth_ntuple_filter *)arg,
+ TRUE);
+ break;
+ case RTE_ETH_FILTER_DELETE:
+ ret = igb_add_del_ntuple_filter(dev,
+ (struct rte_eth_ntuple_filter *)arg,
+ FALSE);
+ break;
+ case RTE_ETH_FILTER_GET:
+ ret = igb_get_ntuple_filter(dev,
+ (struct rte_eth_ntuple_filter *)arg);
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
static inline int
igb_ethertype_filter_lookup(struct e1000_filter_info *filter_info,
uint16_t ethertype)
@@ -3234,6 +3544,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
int ret = -EINVAL;
switch (filter_type) {
+ case RTE_ETH_FILTER_NTUPLE:
+ ret = igb_ntuple_filter_handle(dev, filter_op, arg);
+ break;
case RTE_ETH_FILTER_ETHERTYPE:
ret = igb_ethertype_filter_handle(dev, filter_op, arg);
break;
--
1.9.3
next prev parent reply other threads:[~2015-02-10 4:48 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-15 1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
2015-01-15 1:45 ` [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-01-15 1:45 ` [dpdk-dev] [PATCH 2/5] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-01-15 1:45 ` [dpdk-dev] [PATCH 3/5] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
2015-01-15 1:46 ` [dpdk-dev] [PATCH 4/5] testpmd: new commands for ntuple filter Jingjing Wu
2015-01-15 1:46 ` [dpdk-dev] [PATCH 5/5] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-01-21 12:18 ` [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
2015-01-22 0:28 ` Wu, Jingjing
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 4/6] testpmd: new commands for ntuple filter Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-01-22 7:38 ` [dpdk-dev] [PATCH v2 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
2015-01-28 14:28 ` [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
2015-01-30 8:22 ` Wu, Jingjing
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 " Jingjing Wu
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-02-10 4:48 ` Jingjing Wu [this message]
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 4/6] testpmd: new commands for ntuple filter Jingjing Wu
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-02-10 4:48 ` [dpdk-dev] [PATCH v3 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
2015-02-13 2:59 ` [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters Xu, HuilongX
2015-02-20 17:29 ` De Lara Guarch, Pablo
2015-02-22 3:10 ` Thomas Monjalon
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=1423543713-21624-4-git-send-email-jingjing.wu@intel.com \
--to=jingjing.wu@intel.com \
--cc=dev@dpdk.org \
/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).